JavaScript. Подробное руководство, 6-е издание, стр. 357

<b>с.beginPath(); // Новый контур</b>

<b>c.moveTo(100, 100); // Новый фрагмент контура с начальной точкой (100,100) </b>

<b>c.lineTo(200, 200); // Добавить линию, соединяющую точки (100,100) и (200,200) </b>

<b>c.lineTo(100, 200); // Добавить линию, соединяющую точки (200,200) и (100,200)</b>

Фрагмент выше просто определяет контур - он ничего не рисует. Чтобы фактически нарисовать две линии, следует вызвать метод

stroked
, а чтобы залить область, ограниченную этими линиями, следует вызвать метод
<b>fill()</b>
:

<b>с.fill(); // Залить область треугольника</b>

<b>с.stroked; // Нарисовать две стороны треугольника</b>

Фрагмент выше (плюс некоторый дополнительный программный код, устанавливающий толщину линий и цвет заливки) воспроизводит рисунок, изображенный на рис. 21.5.

JavaScript. Подробное руководство, 6-е издание - i_056.jpg

Рис. 21.5. Простой путь, нарисованный и залитый

Обратите внимание, что фрагмент контура, определяемый выше, является «открытым». Он содержит всего две прямые линии, и его конечная точка не совпадает с начальной точкой. То есть он образует незамкнутую область. Метод

<b>fill()</b>
выполняет заливку открытых фрагментов контуров, как если бы конечная и начальная точка фрагмента контура были соединены прямой линией. Именно поэтому пример выше выполняет заливку треугольной области, но рисует только две стороны этого треугольника.

Если бы потребовалось нарисовать все три стороны треугольника выше, можно было бы вызвать метод

<b>closePath(),</b>
чтобы соединить конечную и начальную точки фрагмента контура. (Можно было бы также вызвать метод
<b>lineTo(100,100),</b>
но в этом случае получились бы три прямые линии с общей начальной и конечной точками, не образующие в действительности замкнутый фрагмент контура. При рисовании толстыми линиями результат визуально выглядит лучше, если используется метод
<b>closePath()</b>
.)

Следует сделать еще два важных замечания, касающиеся методов

<b>stroke()</b>
и
<b>fill().</b>
Во-первых, оба метода оперируют всеми элементами в текущем контуре. Допустим, что в примере выше был добавлен еще один фрагмент контура:

<b>с.moveTo(300,100); // Новый фрагмент контура с начальной точкой (300,100); </b>

<b>с.lineТо(300,200); // Нарисовать вертикальную линию вниз до точки (300,200);</b>

Если затем вызвать метод

<b>stroke(),</b>
получились бы две соединенные вместе стороны треугольника и не связанная с ними вертикальная линия.

Во-вторых, обратите внимание, что методы

<b>stroke()</b>
и
<b>fill()</b>
никогда не изменяют текущий контур: можно вызвать метод
<b>fill(),</b>
и от этого контур никуда не денется, когда вслед за этим будет вызван метод
<b>stroke().</b>
Когда вы закончили работу с текущим контуром и приступаете к работе с новым контуром, нужно не забыть вызывать метод
<b>beginPath().</b>
В противном случае вы просто добавите новый фрагмент контура в существующий контур, и старые фрагменты контура будут рисоваться снова и снова.

Пример 21.4 содержит определение функции рисования правильных многоугольников и демонстрирует использование методов

<b>moveTo(), lineTo()</b>
и
<b>closePath()</b>
для определения фрагментов контура и методов
<b>fill()</b>
и
<b>stroke()</b>
для рисования контуров. Он воспроизводит рисунок, изображенный на рис. 21.6.

JavaScript. Подробное руководство, 6-е издание - i_057.jpg

Пример 21.4. Рисование правильных многоугольников с помощью методов

<b>moveTo(), lineTo()</b>
и
closePath()

<b>// Определяет правильный многоугольник с п сторонами, вписанный в окружность с центром</b>

<b>// в точке (х,у) и радиусом r. Вершины многоугольника находятся на окружности,</b>

<b>// на равном удалении друг от друга. Первая вершина помещается в верхнюю точку</b>

<b>// окружности или со смещением на указанный угол angle. Поворот выполняется</b>

<b>// по часовой стрелке, если в последнем аргументе не передать значение true,</b>

<b>function polygon(c, n, x, y, r, angle, counterclockwise) {</b>

<b>  angle = angle || 0;</b>

<b>  counterclockwise = counterclockwise || false;</b>

<b>  c.moveTo(x + r*Math.sin(angle), // Новый фрагмент контура</b>

<b>       у - r*Math.cos(angle)); // Исп. тригонометрию для выч. координат</b>

<b>  var delta = 2*Math.PI/n; // Угловое расстояние между вершинами</b>

<b>  for(var і = 1; і &lt; n; i++) { // Для каждой из оставшихся вершин</b>

<b>    angle += counterclockwise?-delta:delta; // Скорректировать угол</b>

<b>    c.lineTo(x + r*Math.sin(angle), // Линия к след, вершине</b>

<b>             у - r*Math.cos(angle));</b>

<b>  }</b>

<b>  с.closePath(); // Соединить первую вершину с последней</b>

<b>} </b>

<b>// Создать новый контур и добавить фрагменты контура, соответствующие многоугольникам-</b>

<b>с.beginPath();</b>

<b>polygon(c, 3, 50, 70, 50);                   // Треугольник</b>

<b>polygon(c, 4, 150, 60, 50, Math.PI/4);       // Квадрат</b>