Книга: Выразительный JavaScript

Кривые

Кривые

Путь может состоять из кривых. Их рисовать посложнее, нежели прямые.

Метод quadraticCurveTo рисует кривую до нужной точки. Для определения кривизны методу даётся контрольная точка вместе с точкой назначения. Представьте, что контрольная точка как бы притягивает линию, задавая кривой кривизну. Линия не проходит через контрольную точку. Вместо этого направления линии в её начальной и конечной точках будут стремиться к контрольной точке. Следующий пример иллюстрирует это:

<canvas></canvas>
<script>
  var cx = document.querySelector("canvas").getContext("2d");
  cx.beginPath();
  cx.moveTo(10, 90);
  // control=(60,10) goal=(90,90)
  cx.quadraticCurveTo(60, 10, 90, 90);
  cx.lineTo(60, 10);
  cx.closePath();
  cx.stroke();
</script>

Рисуем слева направо квадратичную кривую, у которой контрольная точка задана как (60,10), а затем рисуем два сегмента, проходящие обратно через контрольную точку и начало линии. Результат напоминает эмблему Звёздного пути. Можно увидеть действие контрольной точки: линия, выходящая из начальной и конечной точек, начинается по направлению к контрольной точке, а затем загибается.

Метод bezierCurve рисует схожую кривую. Вместо одной контрольной точки у неё есть две – по одной на каждый из концов кривой. Вот похожий рисунок для иллюстрации поведения такой кривой:

<canvas></canvas>
<script>
  var cx = document.querySelector("canvas").getContext("2d");
  cx.beginPath();
  cx.moveTo(10, 90);
  // control1=(10,10) control2=(90,10) goal=(50,90)
  cx.bezierCurveTo(10, 10, 90, 10, 50, 90);
  cx.lineTo(90, 10);
  cx.lineTo(10, 10);
  cx.closePath();
  cx.stroke();
</script>

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

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

Дуги, фрагменты кругов, легче в обращении. Метод arcTo принимает целых пять аргументов. Первые четыре – похожи на аргументы quadraticCurveTo. Первая пара задаёт что-то вроде контрольной точки, вторая – место назначения кривой. Пятый задаёт радиус дуги. Метод создаёт скруглённый угол – линию, идущую к контрольной точке, а затем к точке назначения – и скругляет угол заданным радиусом. Метод arcTo рисует круглую часть, а также линию от точки старта до начала закруглённой части.

<canvas></canvas>
<script>
  var cx = document.querySelector("canvas").getContext("2d");
  cx.beginPath();
  cx.moveTo(10, 10);
  // control=(90,10) goal=(90,90) radius=20
  cx.arcTo(90, 10, 90, 90, 20);
  cx.moveTo(10, 10);
  // control=(90,10) goal=(90,90) radius=80
  cx.arcTo(90, 10, 90, 90, 80);
  cx.stroke();
</script>
arcTo
не рисует линию от конца закруглённой части до точки назначения, несмотря на своё название. Её можно закончить через lineTo с такими же координатами.

Чтобы нарисовать круг, можно сделать четыре вызова arcTo, где каждый повёрнут относительно другого на 90 градусов. Но метод arc предоставляет способ проще. Он принимает пару координат центра арки, радиус и начальный и конечный углы.

Два последних параметра могут помочь в рисовании части круга. Углы измеряются в радианах, а не градусах. Это значит, что полный круг имеет угол в 2?, или 2 * Math.PI, что примерно равно 6,28. Угол начинает отсчёт от точки справа от центра, и идёт против часовой стрелки. Чтобы нарисовать полный круг, можно задать начало в 0, а конец больше 2? (к примеру, 7).

<canvas></canvas>
<script>
  var cx = document.querySelector("canvas").getContext("2d");
  cx.beginPath();
  // center=(50,50) radius=40 angle=0 to 7
  cx.arc(50, 50, 40, 0, 7);
  // center=(150,50) radius=40 angle=0 to ??
  cx.arc(150, 50, 40, 0, 0.5 * Math.PI);
  cx.stroke();
</script>

На картинке в результате будет линия слева от круга (первый вызов arc), до левой части четверти круга (второй вызов). Как и другие методы рисования путей, линия дуги соединена с предыдущим сегментом пути. Для начала рисования нового пути надо вызвать moveTo.

Оглавление книги


Генерация: 0.676. Запросов К БД/Cache: 2 / 0
поделиться
Вверх Вниз