Кривые Безье

Кривые Безье — это фундаментальный инструмент для построения сложных кривых и контуров в векторной графике. В Snap.svg их использование позволяет создавать плавные линии с точным контролем формы через контрольные точки. Snap.svg предоставляет удобные методы для работы с кривыми Безье как кубическими, так и квадратичными.

Создание кривой Безье

Для создания кривой используется метод path(). Формат записи кривой соответствует стандарту SVG:

  • Квадратичная кривая: M x1 y1 Q cx cy x2 y2 где M задаёт начальную точку, Q — квадратичную кривую с контрольной точкой (cx, cy) и конечной точкой (x2, y2).

  • Кубическая кривая: M x1 y1 C cx1 cy1 cx2 cy2 x2 y2 где C задаёт кубическую кривую с двумя контрольными точками (cx1, cy1) и (cx2, cy2) и конечной точкой (x2, y2).

Пример создания кубической кривой:

var s = Snap("#svg");
var cubicCurve = s.path("M50 150 C150 50 250 250 350 150");
cubicCurve.attr({
    stroke: "#000",
    strokeWidth: 3,
    fill: "none"
});

Контрольные точки и их влияние

Ключевой принцип кривых Безье — контрольные точки определяют направление и «натяжение» кривой. В кубической кривой:

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

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

Изменение кривой через атрибуты

Snap.svg позволяет динамически изменять кривую, редактируя атрибут d:

cubicCurve.attr({ d: "M50 150 C100 100 300 200 350 150" });

Это позволяет анимировать кривые, создавая плавные переходы между формами. Также удобно использовать методы getPointAtLength() и getTotalLength() для вычисления точек на кривой и создания анимаций движения по пути.

Анимация по кривой

Snap.svg поддерживает анимацию объектов вдоль пути кривой Безье. Пример движения круга вдоль кривой:

var circle = s.circle(0, 0, 10).attr({ fill: "#f00" });
var pathLength = cubicCurve.getTotalLength();

Snap.animate(0, pathLength, function (value) {
    var point = cubicCurve.getPointAtLength(value);
    circle.attr({ cx: point.x, cy: point.y });
}, 3000);

В этом примере объект плавно перемещается от начала до конца кривой, используя длину пути и вычисление координат через getPointAtLength.

Создание сложных форм с кривыми

Кривые Безье могут объединяться в сложные контуры через последовательные команды C и Q. Например, создание волнистой линии:

var wave = s.path("M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80");
wave.attr({ stroke: "#00f", fill: "none", strokeWidth: 2 });

Здесь используется команда S, которая автоматически берёт вторую контрольную точку предыдущей кривой для симметрии, упрощая построение соединённых сегментов.

Взаимодействие с пользователем

Snap.svg позволяет динамически изменять кривые в зависимости от действий пользователя. События мыши могут изменять контрольные точки:

wave.drag(function(dx, dy) {
    var newD = "M10 80 C " + (40+dx) + " " + (10+dy) + ", 65 10, 95 80 S 150 150, 180 80";
    wave.attr({ d: newD });
});

Таким образом, интерактивное изменение формы кривой становится простым, а визуальная обратная связь мгновенной.

Практические советы

  • Для плавных соединений сегментов кубических кривых используйте команду S.
  • В квадратичных кривых контрольная точка должна располагаться ближе к центру кривизны для более естественного изгиба.
  • Анимации по кривой требуют аккуратного вычисления длины пути и координат точек на кривой для ровного движения.
  • Комбинируйте линии (L), квадратичные (Q) и кубические (C) кривые для сложных форм и декоративных элементов.

Кривые Безье в Snap.svg обеспечивают гибкость, точность и полный контроль над формой, что делает их незаменимым инструментом для векторной графики и анимации.