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