Создание путей

Создание путей.

Пока что мы изучали методы, позволяющие рисовать прямо на холсте, однако это не всегда возможно или уместно. Чаще всего приходится сначала в фоновом режиме обрабатывать фигуры и изображения, а после этого отправлять результат в контекст, для того чтобы рисунок в итоге появился на странице. Для этого в API Canvas (Холст) предусмотрено несколько методов генерации путей.

Путь — это контур, вдоль которого следует кончик воображаемого пера, оставляя за собой след. Сначала нам нужно определить путь, затем отправить его в контекст, и только после этого он будет постоянно визуализирован на экране. Путь может включать в себя различные виды штрихов: прямые линии, дуги, прямоугольники и т. п. Из всех этих разнообразных компонентов можно составлять весьма сложные фигуры.

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

— beginPath(). Объявляет о начале определения новой фигуры. Вызывается в первую очередь, еще до того, как мы начнем создавать новый путь;

— closePath(). Закрывает путь, добавляя прямую линию между последней точкой и исходной точкой пути. Существуют способы избежать появления этой линии в ситуациях, когда требуется открытый путь или когда для рисования пути используется метод fill().

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

— stroke(). Визуализирует путь в виде контура;

— fill(). Визуализирует путь в виде залитой цветом фигуры. Если вы используете данный метод, то закрывать путь посредством closePath() не требуется — он автоматически закрывается прямой линией, соединяющей последнюю точку с первой;

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

Листинг 7.6. Базовые правила для определения пути

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

// здесь описывается путь canvas. stroke();

}

Window. addEventListener("load", initiate, false);

Код из листинга 7.6 не создает никаких рисунков, он лишь сигнализирует о начале описания пути в контексте конкретного холста и визуализирует контур этого пути на экране с помощью метода stroke(). Для описания пути и создания реальной фигуры предназначены следующие методы:

— moveTo(x, y). Перемещает кончик пера в указанную позицию. Позволяет начать или продолжить рисование пути с новой точки сетки, создав таким образом разрыв в контуре;

— lineTo(x, y). Создает прямой отрезок линии между текущей позицией пера и точкой с координатами x и y;

— rect(x, y, width, height). Создает прямоугольник. В отличие от методов, описанных ранее, в данном случае прямоугольник становится частью пути (а не сразу же визуализируется на холсте). Тем не менее атрибуты остаются неизменными;

— arc(x, y, radius, startAngle, endAngle, direction). Создает дугу или окружность с центром в точке с координатами x и y, радиусом и угловым значением, объявленными в атрибутах. Последний атрибут — это булево значение, задающее направление рисования: по часовой стрелке или против нее;

— quadraticCurveTo(cpx, cpy, x, y). Создает квадратичную кривую Безье, начинающуюся в текущей позиции пера и заканчивающуюся в позиции с координатами x и y. Атрибуты cpx и cpy представляют собой контрольные точки, управляющие формой кривой;

— bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y). Аналогичен предыдущему, но задействует два дополнительных атрибута, позволяющих определить кубическую кривую Безье. В данном случае для управления формой кривой используются две контрольные точки на сетке, описываемые значениями cp1x, cply, cp2x и cp2y.

Давайте попробуем создать простой путь, для того чтобы понять, как работают эти методы.

Листинг 7.7. Наш первый путь

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath(); canvas. moveTo(100,100); canvas. lineTo(200,200); canvas. lineTo(100,200);

Canvas. stroke();

}

Рекомендуем всегда задавать начальную позицию пера сразу же после объявления начала пути. В коде из листинга 7.7 мы сначала перенесли перо в позицию (100, 100), а затем создали линию между этой точкой и точкой (200, 200). После этого текущей позицией пера уже считается точка (200, 200), а следующий отрезок создается между ней и точкой (100, 200). Наконец, мы визуализируем путь в виде контура, применяя для этого метод stroke().

Протестировав этот код в своем браузере, вы увидите на странице острый угол (или треугольник без одной стороны). Этот треугольник можно закрыть и даже залить цветом или узором, применив различные методы, как в следующих примерах (листинги 7.8 и 7.9).

Листинг 7.8. Завершение создания треугольника

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Canvas. moveTo(100,100);

Canvas. lineTo(200,200);

Canvas. lineTo(100,200);

Canvas. closePath();

Canvas. stroke();

}

Window. addEventListener("load", initiate, false);

Метод closePath() всего лишь добавляет к пути прямой отрезок, соединяющий последнюю точку с первой и таким образом закрывающий фигуру.

Применив метод stroke() в конце пути, мы нарисовали на холсте пустой треугольник. Чтобы получить треугольник, залитый цветом, необходимо использовать метод fill().

Листинг 7.9. Заливаем треугольник сплошным цветом

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Canvas. moveTo(100,100);

Canvas. lineTo(200,200);

Canvas. lineTo(100,200);

Canvas. fill();

}

Window. addEventListener("load", initiate, false);

Теперь на экране отображается сплошной черный треугольник. Метод fill() автоматически закрывает путь, поэтому добавлять в код метод closePath() не требуется.

Ранее мы упоминали еще один метод визуализации контура на холсте, а именно clip(). Этот метод ничего не рисует, он всего лишь создает маску в форме пути и таким образом позволяет определить, что будет нарисовано на холсте, а что нет. Ничего из того, что оказывается за пределами маски, на экране не отображается.

Листинг 7.10. Используем треугольник в качестве маски

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Canvas. moveTo(100,100);

Canvas. lineTo(200,200);

Canvas. lineTo(100,200);

Canvas. clip();

Canvas. beginPath(); for(f=0; f<300; f=f+10){ canvas. moveTo(0,f); canvas. lineTo(500,f);

}

Canvas. stroke();

}

Window. addEventListener("load", initiate, false);

Для того чтобы продемонстрировать работу метода clip(), мы добавили в листинг 7.10 цикл, создающий горизонтальные линии через каждые 10 пикселов. Линии пересекают холст слева направо, но на странице мы видим только те их фрагменты, которые попадают внутрь треугольной маски.

Теперь, когда мы научились рисовать пути, настало время изучить альтернативные варианты. Пока что мы создавали только прямые линии и прямоугольные фигуры. Для создания фигур, включающих в себя различные дуги, в API предусмотрено три новых метода: arc(), quadraticCurveTo() и bezierCurveTo(). Первый относительно прост и предназначен для рисования полных окружностей или дуг, что иллюстрирует листинг 7.11.

Листинг 7.11. Создание окружности с помощью метода arc()

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Canvas. arc(100,100,50,0,Math. PI*2, false);

Canvas. stroke();

}

Window. addEventListener("load", initiate, false);

Вы наверняка обратили внимание на значение PI в определении метода. Данный метод ориентируется на значения угла в радианах, а не в градусах. Значение PI в радианах соответствует 180°, таким образом, формула PI х 2 означает удвоение PI, что в итоге дает 360°.

Код из листинга 7.11 создает дугу с центром в точке (100, 100) радиусом 50 пикселов, начинающуюся от угла 0° и заканчивающуюся углом Math. PI х 2 градусов, что соответствует полной окружности. Свойство PI объекта Math дает точное значение числа п.

Для перевода значения в градусах в радианы используйте формулу Math. PI/180 х градусы, как в следующем примере.

Листинг 7.12. Дуга размером 45°

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Var radians=Math. PI/180*45;

Canvas. arc(100,100,50,0,radians, false); canvas. stroke();

}

Выполнив код из листинга 7.12, мы увидим на экране дугу, составляющую только 45° окружности. Попробуйте изменить значение атрибута direction в этом примере на true. В результате на экране появится дуга между точками 0° и 315°, выглядящая как окружность без небольшого фрагмента.

Очень важно учитывать следующее: если вы продолжите работать с этим путем после создания дуги, то начальной точной будет считаться конец дуги. Если такое поведение нежелательно, нужно при помощи метода moveTo() изменить позицию пера. Кстати, если следующей кривой также должна быть дуга, например, вы хотите нарисовать полный круг, то не стоит забывать, что метод moveTo() переносит виртуальное перо в точку, с которой начинается рисование, а не в центр круга. Предположим, что центр вашего круга должен находиться в точке (300, 150), а его радиус равен 50 пикселам. Тогда для получения нужной фигуры следует перевести перо в точку (350, 150).

Помимо arc() есть еще два метода рисования сложных кривых. Метод quadraticCurveTo() генерирует квадратичную кривую Безье, а метод bezierCurveTo() предназначен для рисования кубической кривой Безье. Различие между этими методами заключается в том, что первый предлагает только одну контрольную точку, а второй — две, таким образом, они создают кривые разных типов.

Листинг 7.13. Сложные кривые

Function initiate(){

Var elem=document. getElementById(‘canvas’); canvas=elem. getContext(‘2d’);

Canvas. beginPath();

Canvas. moveTo(50,50);

Canvas. quadraticCurveTo(100, 125, 50, 200);

Canvas. moveTo(250,50);

Canvas. bezierCurveTo(200, 125, 300, 125, 250, 200);

Canvas. stroke();

}

Window. addEventListener("load", initiate, false);

Для рисования квадратичной кривой мы переместили виртуальное перо в позицию (50, 50), а координаты конечной точки определили как (50, 200). Координаты контрольной точки этой кривой (100, 125).

Кубическая кривая, создаваемая методом bezierCurveTo(), немного сложнее. У нее две контрольные точки, одна с координатами (200, 125), вторая — (300, 125) (рис. 7.2).

Значения на рис. 7.2 указывают позиции контрольных точек наших кривых. Перемещая контрольные точки, вы можете менять форму кривых.

Вы можете добавить сколь угодно много кривых для построения желаемых фигур. Попробуйте поменять значения контрольных точек в коде из листинга 7.13 и проверьте в браузере, как изменится форма кривых. Стройте сложные фигуры, объединяя разные кривые и линии, для того чтобы понять, каким образом конструируют пути.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *