Пути
Элемент <path> является самым мощным элементом в библиотеке SVG основных фигур. Он может использоваться для создания линий, кривых, дуг и т. д.
Пути создают сложные фигуры, объединяя несколько прямых или кривых линий. Сложные фигуры, состоящие только из прямых линий, могут быть созданы как элементы <polyline>. В то время как <polyline> и <path> элементы могут создавать похожие фигуры, <polyline> элементы требуют большого количества коротких прямых линий для имитации кривых и не масштабируются хорошо при увеличении размера.
Хорошее понимание путей важно при отрисовке SVG. Хотя создание сложных путей с помощью редактора XML или текстового редактора не рекомендуется, понимание того, как они работают, позволит идентифицировать и исправлять проблемы с отображением в SVG.
Форма элемента <path> определяется одним параметром: d. (Подробнее см. в основных фигурах.) Атрибут d содержит серию команд и параметров, используемых этими командами.
Каждая команда инициализируется (например, создание класса, его именование и позиционирование) определённой буквой. Например, давайте переместимся в координаты x и y (10, 10). Команда "Перейти к" называется буквой M. Когда анализатор встречает эту букву, он понимает, что ему нужно переместиться в определённую точку. Таким образом, чтобы переместиться в (10, 10) нужно использовать команду M 10 10. После этого анализатор начинает чтение следующей команды.
Все команды также доступны в двух вариантах. Заглавная буква указывает абсолютные координаты на странице, а строчная буква — относительные координаты (например, перемещение на 10 пикселей вверх и на 7 пикселей влево от последней точки).
Координаты в параметре d всегда без единиц измерения и, следовательно, в системе координат пользователя. Позже мы узнаем, как пути могут быть преобразованы для других задач.
Команды линий
Существует пять команд линий для узлов <path>. Первая команда — "Перейти к" или M, о которой говорилось выше. Она принимает два параметра, координату (x) и координату (y) для перемещения. Если курсор уже находился где-то на странице, линия для соединения этих двух позиций не рисуется. Команда "Перейти к" появляется в начале путей для указания начала рисования. Например:
M x y (or) m dx dy
В следующем примере есть только точка в (10, 10). Однако она не будет отображаться, если путь будет нарисован обычно. Например:
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <path d="M10 10"/> <!-- Points --> <circle cx="10" cy="10" r="2" fill="red"/> </svg>
Существует три команды, которые рисуют линии. Самая общая — команда "Линия до", вызываемая L. L принимает два параметра — координаты x и y — и рисует линию от текущей позиции до новой.
L x y (or) l dx dy
Существуют два сокращенных варианта для рисования горизонтальных и вертикальных линий. H рисует горизонтальную линию, а V — вертикальную. Обе команды принимают только один параметр, так как они перемещаются только в одном направлении.
H x (or) h dx V y (or) v dy
Хорошей отправной точкой является рисование фигуры. Мы начнем с прямоугольника (который также может быть проще нарисован с помощью элемента <rect>). Он состоит только из горизонтальных и вертикальных линий.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 10 H 90 V 90 H 10 L 10 10"/> <!-- Points --> <circle cx="10" cy="10" r="2" fill="red"/> <circle cx="90" cy="90" r="2" fill="red"/> <circle cx="90" cy="10" r="2" fill="red"/> <circle cx="10" cy="90" r="2" fill="red"/> </svg>
Мы можем немного сократить объявление пути, используя команду "Закрыть путь", вызываемую Z. Эта команда рисует прямую линию от текущей позиции обратно к первой точке пути. Часто она располагается в конце узла пути, хотя и не всегда. Нет разницы между заглавной и строчной командой.
Z (or) z
Итак, наш путь выше можно сократить до:
<path d="M 10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black"/>
Также можно использовать относительные формы этих команд для рисования той же фигуры. Относительные команды вызываются с использованием строчных букв и вместо перемещения курсора в точную координату перемещают его относительно его последнего положения. Например, поскольку наш прямоугольник имеет размеры 80×80, элемент <path> мог быть записан как:
<path d="M 10 10 h 80 v 80 h -80 Z" fill="transparent" stroke="black"/>
Путь переместится в точку (10, 10) и затем переместится на 80 единиц вправо, затем на 80 единиц вниз, затем на 80 единиц влево и затем обратно в начало.
В этих примерах было бы проще использовать элементы <polygon> или <polyline>. Однако пути настолько часто используются в SVG, что разработчики могут предпочесть их использовать вместо других. Нет реальной разницы в производительности при использовании того или иного.
Команды кривых
Существует три разные команды, которые можно использовать для создания плавных кривых. Две из этих кривых — кривые Безье, а третья — "дуга" или часть окружности. Вы, возможно, уже имеете практический опыт работы с кривыми Безье, используя инструменты путей в Inkscape, Illustrator или Photoshop. Существует бесконечное множество кривых Безье, но только две простые доступны в элементах <path>: кубическая, вызываемая C, и квадратичная, вызываемая Q.
Кривые Безье
Кубическая кривая, C, — немного более сложная кривая. Кубические кривые Безье принимают две точки управления для каждой точки. Поэтому для создания кубической кривой Безье необходимо указать три набора координат.
C x1 y1, x2 y2, x y (or) c dx1 dy1, dx2 dy2, dx dy
Последний набор координат здесь (x, y) определяет, где должна закончиться линия. Другие два — точки управления. (x1, y1) — точка управления для начала кривой, а (x2, y2) — точка управления для конца. Точки управления по существу описывают наклон линии, начинающейся в каждой точке. Затем функция Безье создает плавную кривую, переходящую от угла, заданного в начале линии, к углу в конце.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/> <path d="M 70 10 C 70 20, 110 20, 110 10" stroke="black" fill="transparent"/> <path d="M 130 10 C 120 20, 180 20, 170 10" stroke="black" fill="transparent"/> <path d="M 10 60 C 20 80, 40 80, 50 60" stroke="black" fill="transparent"/> <path d="M 70 60 C 70 80, 110 80, 110 60" stroke="black" fill="transparent"/> <path d="M 130 60 C 120 80, 180 80, 170 60" stroke="black" fill="transparent"/> <path d="M 10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/> <path d="M 70 110 C 70 140, 110 140, 110 110" stroke="black" fill="transparent"/> <path d="M 130 110 C 120 140, 180 140, 170 110" stroke="black" fill="transparent"/> </svg>
Приведённый выше пример создаёт девять кубических кривых Безье. По мере продвижения кривых вправо точки управления всё дальше отстоят друг от друга по горизонтали. По мере продвижения кривых вниз они всё дальше отстоят от конечных точек. Важно отметить, что кривая начинается в направлении первой точки управления, а затем изгибается так, чтобы прибыть в направлении второй точки управления.
Несколько кривых Безье могут быть соединены вместе, чтобы создать расширенные, плавные фигуры. Часто точка управления с одной стороны точки будет отражением точки управления, используемой с другой стороны, чтобы сохранить постоянный наклон. В этом случае можно использовать сокращённую версию кубической кривой Безье, обозначенную командой S (или s).
S x2 y2, x y (or) s dx2 dy2, dx dy
S производит тот же тип кривой, что и раньше, но если она следует за другой командой S или командой C, первая точка управления предполагается отражением ранее использованной. Если команда S не следует за командой S или C, тогда текущая позиция курсора используется как первая точка управления. Результат отличается от того, что команда Q произвела бы с теми же параметрами, но схож.
Пример этого синтаксиса показан ниже, а на рисунке слева показаны указанные точки управления красным цветом, а выведенная точка управления — синим.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/> </svg>
Другой тип кривой Безье, квадратичная кривая, вызываемая Q, на самом деле является более простой кривой, чем кубическая. Она требует одной точки управления, которая определяет наклон кривой как в начальной, так и в конечной точке. Она принимает два параметра: точку управления и конечную точку кривой.
Примечание: Дельты координат для q относительны к предыдущей точке (то есть, dx и dy не относятся к dx1 и dy1).
Q x1 y1, x y (or) q dx1 dy1, dx dy
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 80 Q 95 10 180 80" stroke="black" fill="transparent"/> </svg>
Как и в случае с кубической кривой Безье, существует сокращение для объединения нескольких квадратичных кривых Безье, вызываемых T.
T x y (or) t dx dy
Это сокращение анализирует ранее использованную точку управления и выводит новую на её основе. Это означает, что после первой точки управления можно создавать довольно сложные фигуры, указывая только конечные точки.
Это работает только если предыдущей командой была команда Q или T. Если нет, то точка управления предполагается такой же, как и предыдущая, и будут нарисованы только линии.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="transparent"/> </svg>
Обе кривые дают похожие результаты, хотя кубическая кривая позволяет большую свободу в том, как именно выглядит кривая. Решение о том, какую кривую использовать, ситуативное и зависит от симметрии линии.
Дуги
Другой тип кривой линии, которую можно создать с помощью SVG, — это дуга, создаваемая с помощью команды A. Дуги представляют собой части окружностей или эллипсов.
Для заданных радиусов по оси x и оси y существуют два эллипса, которые могут соединить любые две точки (при условии, что они находятся в пределах радиуса окружности). На любой из этих окружностей существуют два возможных пути, по которым можно соединить точки — таким образом, в любой ситуации доступны четыре возможные дуги.
Поэтому для дуг требуется довольно много параметров:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
В начале элемент дуги принимает два параметра для радиусов по оси x и оси y. Если необходимо, см. <ellipse> и как они ведут себя. Два последних параметра обозначают координаты x и y, по которым нужно завершить обводку. Вместе эти четыре значения определяют основную структуру дуги.
Третий параметр описывает поворот дуги. Лучше всего это объяснить на примере:
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg"> <path d="M 10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10" stroke="black" fill="green" stroke-width="2" fill-opacity="0.5"/> </svg>
Пример показывает элемент <path> , который идет по диагонали страницы. В его центре вырезаны две эллиптические дуги (радиус по оси x = 30, радиус по оси y = 50). В первой дуге поворот оси x оставлен на 0, поэтому эллипс, по которому проходит дуга (показан серым цветом), ориентирован строго вертикально. Однако для второй дуги поворот оси x установлен на -45 градуса. Это поворачивает эллипс так, что его малая ось выстраивается по направлению траектории, как показано на втором эллипсе на изображении.
Для невращенного эллипса на изображении выше существуют только две разные дуги, а не четыре, потому что линия, проведенная от начала и конца дуги, проходит через центр эллипса. В немного измененном примере можно увидеть два эллипса, формирующие четыре различные дуги:
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320"> <path d="M 10 315 L 110 215 A 36 60 0 0 1 150.71 170.29 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10" stroke="black" fill="green" stroke-width="2" fill-opacity="0.5"/> <circle cx="150.71" cy="170.29" r="2" fill="red"/> <circle cx="110" cy="215" r="2" fill="red"/> <ellipse cx="144.931" cy="229.512" rx="36" ry="60" fill="transparent" stroke="blue"/> <ellipse cx="115.779" cy="155.778" rx="36" ry="60" fill="transparent" stroke="blue"/> </svg>
Обратите внимание, что каждый из синих эллипсов образован двумя дугами, в зависимости от движения по часовой стрелке или против часовой стрелки. Каждый эллипс имеет одну короткую и одну длинную дугу. Два эллипса — просто зеркальные отражения друг друга. Они отражены относительно линии, образованной точками начала→конца.
Если точки начала→конца находятся дальше, чем могут достичь радиусы эллипса по оси x и y, радиусы эллипса будут минимально увеличены, чтобы достичь точек начала→конца. Интерактивный код-пена внизу этой страницы хорошо демонстрирует это. Для определения, достаточно ли велики радиусы эллипса для увеличения, необходимо решить систему уравнений, такую как эта на Wolfram Alpha. Этот расчет относится к невращенному эллипсу с началом→концом (110, 215)→(150.71, 170.29). Решение (x, y) — это центр эллипса(ов). Решение будет мнимым, если радиусы эллипса слишком малы. Этот второй расчет относится к невращенному эллипсу с началом→концом (110, 215)→(162.55, 162.45). Решение имеет небольшую мнимую составляющую, потому что эллипс был увеличен лишь немного.
Четыре различных пути, упомянутые выше, определяются следующими двумя параметрами. Как уже упоминалось ранее, для траектории всё ещё существуют два возможных эллипса и два различных возможных пути на каждом из эллипсов, что даёт четыре возможных пути. Первый параметр — это large-arc-flag. Он определяет, должна ли дуга быть больше или меньше 180 градусов; в конечном счёте, этот флаг определяет направление движения дуги по заданной окружности. Второй параметр — это sweep-flag. Он определяет, должно ли движение дуги начинаться с положительных или отрицательных углов, что по сути выбирает, по какой из двух окружностей будет производиться обход. Приведенный ниже пример показывает все четыре возможные комбинации, а также две окружности для каждого случая.
<svg width="325" height="325" xmlns="http://www.w3.org/2000/svg"> <path d="M 80 80 A 45 45, 0, 0, 0, 125 125 L 125 80 Z" fill="green"/> <path d="M 230 80 A 45 45, 0, 1, 0, 275 125 L 275 80 Z" fill="red"/> <path d="M 80 230 A 45 45, 0, 0, 1, 125 275 L 125 230 Z" fill="purple"/> <path d="M 230 230 A 45 45, 0, 1, 1, 275 275 L 275 230 Z" fill="blue"/> </svg>
Дуги — это простой способ создания частей окружностей или эллипсов в чертежах. Например, для круговой диаграммы потребуется отдельная дуга для каждой части.
При переходе к SVG из <canvas> дуги могут оказаться самым сложным элементом для освоения, но также и гораздо более мощным инструментом. Полные окружности и эллипсы — единственные фигуры, с которыми SVG-дуги испытывают трудности при рисовании. Поскольку начальная и конечная точки любого пути по окружности являются одной и той же точкой, существует бесконечное число окружностей, которые можно выбрать, и сам путь неопределён. Можно аппроксимировать их, смещая немного начальную и конечную точки пути, а затем соединяя их другим отрезком пути. Например, можно создать окружность с дугой для каждой полуокружности. В этом случае часто проще использовать узел <circle> или <ellipse> вместо дуги. Эта интерактивная демонстрация может помочь в понимании концепций SVG-дуг: https://codepen.io/lingtalfi/pen/yaLWJG (тестировалось в Chrome и Firefox, возможно, не будет работать в вашем браузере)
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths