Home Menu Search

Saqwel

IT and other things blog

Элемент «path» документа SVG

Share

Элемент «path» самый гибкий элемент из всех элементов SVG. С его помощью можно нарисовать любой простой элемент, вроде круга, прямоугольника, эллипса и т.д. Хотя предназначен этот элемент для рисования сложных кривых.

Элемент «path» имеет два атрибута:

  • d – определяет контур фигуры и называется сегментом данных;
  • pathLength – общая длина элемента вычисленная автором, в пользовательских единицах. Насколько я понял, необходима для вычисления длины пути браузером в единицах браузера. Этот параметр имеет значение при создании эффектов текста, движения и различных операциях с чертами.

Атрибут d элемента «path» может содержать инструкции moveto, line, curve, arc, closepath.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
     xmlns="<a href="http://www.w3.org/2000/svg">
          http://www.w3.org/2000/svg</a>" version="1.1">
  <title>Example triangle01- simple example of a «path»</title>
  <desc>A path that draws a triangle</desc>

  <rect x="1" y="1" width="398" height="398"
        fill="none" stroke="blue" />
  <path d="M 100 100 L 300 100 L 200 300 z"
        fill="red" stroke="blue" stroke-width="3" />
</svg>
Должен получиться такой треугольник
Должен получиться такой треугольник

В сегменте данных d содержится несколько символов, обозначающих новую линию. Рекомендуется, чтобы описание каждой линии содержало не более 255 символов. Для оптимизации размера SVG можно использовать следующие приемы:

  • Все инструкции описываются одним символом (вместо moveto пишем M).
  • Лишние пробела и разделители можно удалять (например, “M 100 100 L 200 200” содержит пробелы, которые не нужны для восприятия его браузером, поэтому пишем так “M100 100L200 200”).
  • Можно не повторять командные символы, которые указаны в документе несколько раз подряд (“L” в этой строке повторяется дважды “M 100 200 L 200 100 L -100 -200”, поэтому можно писать так “M 100 200 L 200 100 -100 -200”.
  • Можно использовать командные символы в нижнем регистре для указания относительных координат.

Команда «moveto»

Команда «moveto» (M или m) устанавливает новую текущую точку. Можно представить себе, что при указании «moveto» автор поднимает карандаш и перемещает его на новое место. Сегмент данных d (если он один) всегда должен начинаться с команды «moveto». Если «moveto» не первая команда, то создается новый подэлемент элемента «path» (возникает разрыв между первым подэлементом начинающимся с «moveto» и следующим).

Команда «moveto» не имеет параметров.

Команда «closepath»

Команда ’closepath’ (Z или z) завершает текущий подэлемент элемента «path» и автоматически создает прямую линию, соединяющую текущую точку с точкой начала подэлемента элемента «path». Если «closepath» следует сразу после «moveto», то «moveto» становится точкой начала для следующего подэлемента. Если «closepath» следует за какой-то другой командой, то точкой начала нового подэлемента становится точка начала текущего подэлемента.

Команда «closepath» не имеет параметров.

Команда «lineto»

Команда «lineto» рисует линию из текущей точки в новую точку.

  • Команда: L или l
  • Имя: lineto
  • Параметры: (x,y)+
  • Описание: Рисует линию из текущей точки в указанные (x,y) координаты, которые становятся текущей точкой. L указывает координаты в абсолютной системе координат, l в относительной.
  • Команда: H или h
  • Имя: horizontal lineto
  • Параметры: x+
  • Описание: Рисует горизонтальную линию из текущей точки (xтек,yтек) в новую точку (x, yтек). H для абсолютной системы координат, h – для относительной.
  • Команда: V или v
  • Имя: vertical lineto
  • Параметры: y+
  • Описание: Рисует горизонтальную линию из текущей точки (xтек yтек) в новую точку (xтек y). V для абсолютной системы координат, v – для относительной.

Команды создания кривых

Всего три группы команд для рисования кривых:

  • Кубическая кривая Безье (C или c, S или s). Кубическая кривая Безье описывается начальной точкой, конечной точкой и двумя контрольными точками.
  • Квадратичная кривая Безье (Q или q, T или t). Квадратичная кривая Безье описывается начальной точкой, конечной точкой и одной контрольной точкой.
  • Дуга эллипса (A или a). Эта фигура отображает сегмент окружности.

Кубическая кривая Безье

  • Команда: C или c
  • Имя: curveto
  • Параметры: (x1 y1 x2 y2 x y)+
  • Описание: Рисует кубическую кривую Безье из текущей точки до точки (x y), используя (x1 y1) как контрольную точку начала кривой и (x2 y2) как контрольную точку конца кривой.
  • Команда: S или s
  • Имя: shorthand/smooth curveto
  • Параметры: (x2 y2 x y)+
  • Описание: Рисует кубическую кривую Безье из текущей точки до точки (x, y). Первая контрольная точка создается автоматически, в соответствии с тем, как расположена вторая контрольная точка предыдущей команды. Если предыдущей команды нет или предыдущая команда не C, c, S или s, то первая контрольная точка совпадает с текущей точкой. (x2 y2) – это координаты второй контрольной точки, то есть контрольной точки конца кривой.

Ниже представлен простой пример использования

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="5cm" height="4cm" viewBox="0 0 500 400"
     xmlns="<a href="http://www.w3.org/2000/svg">
          http://www.w3.org/2000/svg</a>" version="1.1">
  <title>Example cubic01- cubic Bezier commands in path data</title>
  <desc>Picture showing a simple example of path data
        using both a "C" and an "S" command,
        along with annotations showing the control points
        and end points</desc>
  <style type="text/css"><![CDATA[
    .Border { fill:none; stroke:blue; stroke-width:1 }
    .Connect { fill:none; stroke:#888888; stroke-width:2 }
    .SamplePath { fill:none; stroke:red; stroke-width:5 }
    .EndPoint { fill:none; stroke:#888888; stroke-width:2 }
    .CtlPoint { fill:#888888; stroke:none }
    .AutoCtlPoint { fill:none; stroke:blue; stroke-width:4 }
    .Label { font-size:22; font-family:Verdana }
  ]]></style>
  <rect class="Border" x="1" y="1" width="498" height="398" />
  <polyline class="Connect" points="100,200 100,100" />
  <polyline class="Connect" points="250,100 250,200" />
  <polyline class="Connect" points="250,200 250,300" />
  <polyline class="Connect" points="400,300 400,200" />
  <path class="SamplePath" d="M100,200 C100,100 250,100 250,200
                                       S400,300 400,200" />
  <circle class="EndPoint" cx="100" cy="200" r="10" />
  <circle class="EndPoint" cx="250" cy="200" r="10" />
  <circle class="EndPoint" cx="400" cy="200" r="10" />
  <circle class="CtlPoint" cx="100" cy="100" r="10" />
  <circle class="CtlPoint" cx="250" cy="100" r="10" />
  <circle class="CtlPoint" cx="400" cy="300" r="10" />
  <circle class="AutoCtlPoint" cx="250" cy="300" r="9" />
  <text class="Label" x="25" y="70">M100,200 C100,
    100 250,100 250,200</text>
  <text class="Label" x="325" y="350"
        style="text-anchor:middle">S400,300 400,200</text>
</svg>
Кубическая кривая Безье
Кубическая кривая Безье

Ниже представлена картина того, как расположение контрольных точек влияет на форму кривой. Первые пять примеров иллюстрируют одиночный сегмент кривой Безье. Справа снизу представлен пример использования команды S после команды C.

Примеры кривой Безье на одиночном сегменте
Примеры кривой Безье на одиночном сегменте

Квадратичная кривая Безье

  • Команда: Q или q
  • Имя: quadratic Bezier curveto
  • Параметры: (x1 y1 x y)+
  • Описание: Рисует квадратичную кривую Безье из текущей точки до точки (x y), используя (x1 y1) как контрольную точку.
  • Команда: T или t
  • Имя: Shorthand/smooth quadratic Bezier curveto
  • Параметры: (x y)+
  • Описание: Рисует квадратичную кривую Безье из текущей точки до точки (x y). Контрольная точка создается автоматически в соответствии с расположением контрольной точки предыдущей команды. Если до этого не было команды или предыдущая команда была не Q, q, T или t, то контрольная точка совпадает с текущей точкой.

Нижеследующий пример демонстрирует использование квадратичной кривой Безье.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="12cm" height="6cm" viewBox="0 0 1200 600"
     xmlns="<a href="http://www.w3.org/2000/svg">
          http://www.w3.org/2000/svg</a>" version="1.1">
  <title>Example quad01 -
    quadratic Bezier commands in path data</title>
  <desc>Picture showing a "Q" a "T" command,
        along with annotations showing the control points
        and end points</desc>
  <rect x="1" y="1" width="1198" height="598"
        fill="none" stroke="blue" stroke-width="1" />
  <path d="M200,300 Q400,50 600,300 T1000,300"
        fill="none" stroke="red" stroke-width="5"  />
  <!-- End points -->
  <g fill="black" >
    <circle cx="200" cy="300" r="10"/>
    <circle cx="600" cy="300" r="10"/>
    <circle cx="1000" cy="300" r="10"/>
  </g>
  <!-- Control points and lines from end points to control points -->
  <g fill="#888888" >
    <circle cx="400" cy="50" r="10"/>
    <circle cx="800" cy="550" r="10"/>
  </g>
  <path d="M200,300 L400,50 L600,300 
           L800,550 L1000,300"
        fill="none" stroke="#888888" stroke-width="2" />
</svg>
Квадратичная кривая Безье
Квадратичная кривая Безье

Дуга эллипса

  • Команда: A или a
  • Имя: elliptical arc
  • Параметры: (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
  • Описание: Рисует дугу из текущей точки (x y). Размер и ориентация определяются двумя радиусами (rx, ry) и x-axis-rotation, который указывает, как будет повернут эллипс относительно координатной плоскости. Центр эллипса вычисляется автоматически. large-arc-flag и sweep-flag помогают автоматическому подсчету и прорисовке дуги.

Пример.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="12cm" height="5.25cm" viewBox="0 0 1200 400"
     xmlns="<a href="http://www.w3.org/2000/svg">
          http://www.w3.org/2000/svg</a>" version="1.1">
  <title>Example arcs01 - arc commands in path data</title>
  <desc>Picture of a pie chart with two pie wedges and
        a picture of a line with arc blips</desc>
  <rect x="1" y="1" width="1198" height="398"
        fill="none" stroke="blue" stroke-width="1" />
  <path d="M300,200 h-150 a150,150 0 1,0 150,-150 z"
        fill="red" stroke="blue" stroke-width="5" />
  <path d="M275,175 v-150 a150,150 0 0,0 -150,150 z"
        fill="yellow" stroke="blue" stroke-width="5" />
  <path d="M600,350 l 50,-25 
           a25,25 -30 0,1 50,-25 l 50,-25 
           a25,50 -30 0,1 50,-25 l 50,-25 
           a25,75 -30 0,1 50,-25 l 50,-25 
           a25,100 -30 0,1 50,-25 l 50,-25"
        fill="none" stroke="red" stroke-width="5"  />
</svg>
Дуга эллипса
Дуга эллипса

Команда A или a рисует сегмент эллипса, который имеет некоторые ограничения

  • дуга начинается из текущей точки;
  • дуга заканчивается в точке (x y);
  • эллипс имеет два радиуса (rx ry);
  • поворот относительно оси x определяется параметром x-axis-rotation

В большинстве случаев существует четыре различные дуги (два эллипса каждый состоит из двух дуг), которые соответствуют этим ограничениям. large-arc-flag и sweep-flag указывают, какая из дуг будет нарисована.

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

Пример, в котором знаки вопроса ?,? заменяются последовательно на “0,0” “0,1” “1,0” and “1,1”

<path d="M 125,75 a100,50 0 ?,? 100,50"
      style="fill:none; stroke:red; stroke-width:6"/>
Четыре типа дуги
Четыре типа дуги

Leave a Reply