Spec-Zone.ru › SVG

Шаблоны

Шаблоны

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

html
<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, мы можем поместить все элементы в одну систему единиц:

xml
 <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" , если это не обязательно.

Ни один из этих способов использования не является тем, о чём обычно думают, когда речь заходит о шаблонах. Шаблоны обычно имеют установленный размер и повторяются независимо от формы объекта. Чтобы создать что-то подобное, и шаблон, и его содержимое должны быть нарисованы в текущем пространстве пользователя, чтобы они не меняли форму при изменении объекта:

xml
 <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–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/Patterns

Spec-Zone.ru

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