Пути

Автор: Евгений Рыжков и Татьяна Головко Дата публикации: 16.03.2011

IE Firefox Safari Chrome Opera iPhone Android
7.0+ 3.0+ 3.0+ 3.0+ 10.0+ 1.0+ 1.0+

для IE требуется библиотека explorercanvas.

Представь себе, что ты рисуешь чернилами. Ты вряд ли возьмешь и сразу начнешь рисовать, ведь высока вероятность сделать ошибку, которую уже не исправить. Ты сначала сделаешь эскиз рисунка карандашом. А когда тебе рисунок будет нравиться, просто наведешь его чернилами.

На каждом холсте будут присутствовать пути. Путь — это как набросок карандашом. Можно нарисовать, что угодно, но это не будет частью финального продукта пока ты не «наведешь его чернилами».

Следующие два метода позволяют рисовать прямые линии карандашом:

  • moveTo(x, y) — устанавливает карандаш в нужную точку на холсте;
  • lineTo(x, y) — рисует прямую линию из текущей точки до точки, указанной в параметрах.

Чем чаще вызывать moveTo и lineTo, тем больше и сложнее получится наш путь. Вызывать эти методы «карандаша» можно сколько угодно раз, но на холсте ничего не будет видно, пока не вызовешь методы «чернил».

Начнем с риcования бледно-серой сетки:

for (var x = 0.5; x < 500; x += 10) {
	context.moveTo(x, 0);
	context.lineTo(x, 375);
}

for (var y = 0.5; y < 375; y += 10) {
	context.moveTo(0, y);
	context.lineTo(500, y);
}

Это были методы «карандаша». На холсте еще ничего не отображено. Нужно применить методы «чернил», чтобы наш рисунок проявился на холсте:

context.strokeStyle = "#eee";
context.stroke();

stroke() — это один из «чернильных» методов. Он принимает путь любой сложности, который был ранее определен методами moveTo() и lineTo(), и рисует его на холсте. stokeStyle задает цвет линий. На следующем рисунке изображено то, что у нас вышло:

сетка на холсте

В: А почему мы начали рисовать из координаты 0.5 а не 0?

О: Представь себе каждый пиксель в виде большого квадрата. Целочисленные координаты (0, 1, 2, ..) будут гранями квадратов. Если ты рисуешь линию толщиной в 1 единицу между целочисленными координатами, она будет перекрывать противоположные стороны пиксельного квадрата и в результате получим линию толщиной в 2 единицы. Чтобы нарисовать линию шириной только в 1 единицу, необходимо сместить координаты на 0.5 перпендикулярно к направлению линии.

К примеру, если ты попробуешь нарисовать линию от (1, 0) до (1, 3), браузер будет рисовать линию с перекрытием в полпикселя по обе стороны от x=1. На экране невозможно отобразить половину пикселя, поэтому линия будет расширена для покрытия двух пикселей.

так линия получится толще, чем нужно

Если попробуешь нарисовать линию от (1.5, 0) до (1.5, 3), браузер нарисует линию с перекрытием полпикселя на каждой стороне от x=1.5, что в результате дает истинную однопиксельную линию.

линия правильной толщины

Теперь нарисуем горизонтальную стрелку. Все линии и кривые контура рисуются одного цвета (или градиентом — до него скоро дойдем). Мы хотим нарисовать стрелки другим цветом — черным, а не бледно-серым. Поэтому начнем новый контур.

context.beginPath();
context.moveTo(0, 40);
context.lineTo(240, 40);
context.moveTo(260, 40);
context.lineTo(500, 40);
context.moveTo(495, 35);
context.lineTo(500, 40);
context.lineTo(495, 45);

Вертикальная стрелка выглядит так же. А так как у них совпадают цвета, нет надобности начинать новый контур: две стрелки будут частью одного.

context.moveTo(60, 0);
context.lineTo(60, 153);
context.moveTo(60, 173);
context.lineTo(60, 375);
context.moveTo(65, 370);
context.lineTo(60, 375);
context.lineTo(55, 370);

Я сказал, что стрелки будут черными, но strokeStyle все еще бледно-серый (fillStyle и strokeStyle не сбрасываются когда начинаем новый контур). В этом нет ничего страшного, мы просто запустим серию «карандашных» методов. Но прежде чем отобразить рисунок реально в «чернилах», нужно установить strokeStyle в черный. Иначе стрелки останутся бледно-серыми и еле заметными. Следующие строки кода изменят цвет на черный и нарисуют лини на холсте:

context.strokeStyle = "#000";
context.stroke();

Получим такую картинку:

сетка с осями

Куда дальше