Spec-Zone.ru › SVG

Узоры

Узоры

Узоры, пожалуй, относятся к одним из самых запутанных типов заливки в SVG. Они также очень мощные, поэтому стоит поговорить о них и хотя бы получить общее представление. Как и градиенты, элемент <pattern> следует помещать в раздел <defs> вашего SVG-файла.

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="Gradient1">
      <stop offset="5%" stop-color="white" />
      <stop offset="95%" stop-color="blue" />
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
      <stop offset="5%" stop-color="red" />
      <stop offset="95%" stop-color="orange" />
    </linearGradient>

    <pattern id="Pattern" x="0" y="0" width=".25" height=".25">
      <rect x="0" y="0" width="50" height="50" fill="skyblue" />
      <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)" />
      <circle
        cx="25"
        cy="25"
        r="20"
        fill="url(#Gradient1)"
        fill-opacity="0.5" />
    </pattern>
  </defs>

  <rect fill="url(#Pattern)" stroke="black" width="200" height="200" />
</svg>

Внутри элемента <pattern> можно добавлять любые другие базовые фигуры, которые вы уже использовали ранее, и задавать стиль каждой из них с помощью любых ранее изученных свойств, включая градиенты и прозрачность. Здесь мы просто нарисовали внутри узора два прямоугольника (они перекрываются, один из них вдвое больше другого и используется для заполнения всего узора) и один круг.

Запутаться можно при определении системы единиц измерения и размера узора. В примере выше мы задали атрибуты width и height элемента узора, чтобы определить, как далеко должен простираться узор, прежде чем начать повторяться. Также доступны атрибуты x и y, если нужно сместить начальную точку этого прямоугольника в пределах рисунка. Причина их использования описана ниже.

Как и атрибут gradientUnits, использованный выше, у узоров есть атрибут patternUnits, который задаёт единицы измерения для этих атрибутов. По умолчанию используется значение "objectBoundingBox", как и выше, поэтому значение 1 масштабируется относительно width и height объекта, к которому применяется узор. Поскольку в данном случае мы хотели, чтобы узор повторялся 4 раза по горизонтали и вертикали, значения height и width равны 0.25. Это означает, что width и height узора составляют лишь 0.25 от общего размера прямоугольника.

В отличие от градиентов, у узоров есть второй атрибут — patternContentUnits, который задаёт систему единиц измерения внутри элемента узора для самих базовых фигур. По умолчанию этому атрибуту присвоено значение "userSpaceOnUse" — противоположное значению атрибута patternUnits. Это означает, что, если не указать один или оба этих атрибута (patternContentUnits и patternUnits), фигуры, нарисованные внутри узора, будут использовать другую систему координат, нежели элемент узора. Из-за этого может быть немного сложно вручную составлять такой код.

Чтобы добиться нужного результата в примере выше, нужно было учесть размер нашего прямоугольника (200 пикселей) и то, что мы хотели, чтобы узор повторялся 4 раза по горизонтали и вертикали. Значит, каждый элемент узора представлял собой квадрат размером 50×50. Затем размер двух прямоугольников и круга внутри узора был подобран так, чтобы они помещались в квадрат 50×50. Всё, что было бы нарисовано за его пределами, не отображалось бы. Также узор пришлось сместить на 10 пикселей, чтобы он начинался в левом верхнем углу нашего прямоугольника, поэтому атрибуты x и y элемента pattern нужно было настроить на значение 10÷200 = 0.05.

Оговорка заключается в том, что при изменении размера объекта масштабируется и сам узор, но находящиеся внутри него объекты — нет. Поэтому, хотя в узоре по-прежнему будет 4 повторяющихся элемента, объекты, составляющие этот узор, сохранят исходный размер, и между ними останутся большие пустые области. Изменив атрибут patternContentUnits, мы можем задать для всех элементов одну и ту же систему единиц измерения:

 <pattern id="Pattern" width=".25" height=".25" patternContentUnits="objectBoundingBox">
   <rect x="0" y="0" width=".25" height=".25" fill="skyblue"/>
   <rect x="0" y="0" width=".125" height=".125" fill="url(#Gradient2)"/>
   <circle cx=".125" cy=".125" r=".1" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

Теперь, поскольку содержимое узора использует ту же систему единиц измерения, что и сам узор, нам не нужно смещать прямоугольник, чтобы узор начинался в нужном месте. А если увеличить размер объекта, узор автоматически масштабируется так, чтобы внутри него осталось то же количество объектов и повторов. Это отличается от системы "userSpaceOnUse": при изменении размера объекта узор останется прежним и просто будет повторяться большее количество раз, чтобы заполнить прямоугольник.

Небольшое отступление: в Gecko, похоже, возникают проблемы с отображением кругов, если их радиус меньше 0.075 (пока неизвестно, является ли это ошибкой элемента узора). Чтобы обойти эту проблему, вероятно, лучше не рисовать в единицах "objectBoundingBox", если в этом нет необходимости.

Обычно, говоря об узоре, имеют в виду нечто иное, чем любой из этих вариантов. Как правило, узоры имеют заданный размер и повторяются независимо от формы объекта. Чтобы создать нечто подобное, и узор, и его содержимое нужно рисовать в текущей пользовательской системе координат (userSpace), чтобы их форма не менялась при изменении объекта:

 <pattern id="Pattern" x="10" y="10" width="50" height="50" patternUnits="userSpaceOnUse">
   <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
   <rect x="0" y="0" width="25" height="25" fill="url(#Gradient2)"/>
   <circle cx="25" cy="25" r="20" fill="url(#Gradient1)" fill-opacity="0.5"/>
 </pattern>

Разумеется, это означает, что узор не будет масштабироваться при последующем изменении размера объекта. Ниже показаны все три предыдущих примера на прямоугольнике, немного вытянутом до height, равного 300px, однако следует отметить, что это не исчерпывающий обзор: в зависимости от вашего приложения доступны и другие варианты.

Three examples showing patternUnits values of default and userSpaceOnUse and patternContentUnits values of default and objectBoundingBox. When both are set to default, the aspect ratio is maintained with white space visible. Setting patternContentUnits to objectBoundingBox effects the aspect ratio to remove white space. Setting patternUnits to userSpaceOnUse maintains the aspect ratio while eliminating white space.

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Patterns

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API