Дуги

Snap.svg предоставляет гибкий инструмент для работы с кривыми и дугами через элемент <path>. Дуга в SVG представляет собой часть окружности или эллипса, описываемую командой A (arc) в атрибуте d пути. Формат команды дуги:

A rx ry x-axis-rotation large-arc-flag sweep-flag x y
  • rx, ry — радиусы дуги по осям X и Y.
  • x-axis-rotation — угол поворота оси эллипса относительно оси X.
  • large-arc-flag0 или 1, определяет, какой из двух возможных сегментов дуги использовать (меньший или больший).
  • sweep-flag0 или 1, направление обхода дуги (против часовой стрелки или по часовой).
  • x, y — конечная точка дуги.

Пример создания дуги через Snap.svg:

var s = Snap(400, 400);

var arc = s.path("M100,200 A50,50 0 0,1 200,200");
arc.attr({
    fill: "none",
    stroke: "#3498db",
    strokeWidth: 4
});

В данном примере дуга начинается в точке (100, 200) и заканчивается в (200, 200) с радиусом 50 по обеим осям, без поворота, выбирается малая дуга, направление обхода по часовой стрелке.


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

Snap.svg не предоставляет встроенной функции drawArc, но можно реализовать её самостоятельно, вычисляя координаты точек и параметры дуги.

function describeArc(x, y, radius, startAngle, endAngle){
    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);
    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
    
    return [
        "M", start.x, start.y,
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ].join(" ");
}

function polarToCartesian(centerX, centerY, radius, angleInDegrees){
    var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
    return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
    };
}

var s = Snap(400, 400);
var pathString = describeArc(200, 200, 100, 0, 270);
var arc = s.path(pathString);
arc.attr({stroke: "#e74c3c", strokeWidth: 5, fill: "none"});

В этом примере функция describeArc строит строку пути для дуги, задавая начальный и конечный угол, а функция polarToCartesian конвертирует углы в координаты.


Анимация дуг

Snap.svg позволяет анимировать свойства пути, в том числе дуги. Для плавного изменения угла дуги можно использовать промежуточные значения, создавая эффект “рисования”:

var s = Snap(400, 400);
var arc = s.path(describeArc(200, 200, 100, 0, 0));
arc.attr({stroke: "#2ecc71", strokeWidth: 4, fill: "none"});

Snap.animate(0, 270, function(val){
    arc.attr({d: describeArc(200, 200, 100, 0, val)});
}, 2000);

Здесь дуга анимируется от 0 до 270 градусов за 2 секунды. Такой подход позволяет реализовать прогресс-бары, индикаторы или декоративные элементы на круговых диаграммах.


Работа с эллиптическими дугами

Дуги могут быть эллиптическими, задавая разные значения rx и ry в атрибуте A. Это особенно важно при создании диаграмм, сложных интерфейсных элементов и анимации.

var s = Snap(400, 400);
var ellipseArc = s.path("M50,200 A150,100 30 1,1 350,200");
ellipseArc.attr({stroke: "#9b59b6", strokeWidth: 4, fill: "none"});

Здесь создается эллиптическая дуга с поворотом оси на 30 градусов, большой дугой (large-arc-flag = 1) и обходом по часовой стрелке (sweep-flag = 1).


Комбинирование дуг с другими фигурами

Дуги часто комбинируются с линиями, кривыми Безье или другими дугами для создания сложных фигур. Например, можно соединить несколько дуг в одну непрерывную фигуру:

var s = Snap(400, 400);
var complexPath = s.path("M100,200 A50,50 0 0,1 200,200 A50,50 0 0,1 100,200 Z");
complexPath.attr({stroke: "#f39c12", strokeWidth: 3, fill: "#f1c40f"});

Команда Z закрывает путь, превращая две дуги в замкнутый сегмент окружности.


Управление дугами через свойства Snap.svg

После создания пути дугой доступно динамическое управление:

  • Смена цвета и толщины:
arc.attr({stroke: "#e67e22", strokeWidth: 6});
  • Изменение координат через transform:
arc.transform("t50,50 r45");

transform позволяет перемещать, вращать и масштабировать дугу без изменения исходного пути.

  • Применение масок и градиентов: Дуга может быть частью сложной композиции, на которую накладываются маски или градиенты. Например:
var gradient = s.gradient("r(0.5, 0.5, 1)#e74c3c-#3498db");
arc.attr({stroke: gradient});

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