Чтобы заставить это работать, вам нужно понять, как работают objectBoundingBox
единицы в SVG, а также как работает preserveAspectRatio
.
Размер и содержимое градиентов, шаблонов и ряда других функций SVG можно указать в терминах размера объекта (path
, rect
, circle
), который рисуется, указав objectBoundingBox
в качестве единицы измерения. Противоположность всегда userSpaceOnUse
, которая использует систему координат, в которой рисуется фигура.
Единицы ограничивающей рамки объекта обычно используются по умолчанию для объявления размера и положения графического элемента заливки; вы можете изменить это, установив свойство patternUnits
для элемента <pattern>
. Однако единицы пользовательского пространства обычно используются по умолчанию для любых единиц, используемых в графике содержимого; чтобы изменить это, вы устанавливаете свойство patternContentUnits
.
Итак, первый шаг: Чтобы создать узор, полностью заполняющий фигуру, вам необходимо:
- Объявить высоту и ширину шаблона как 100% (или 1); они будут по умолчанию интерпретироваться относительно ограничивающей рамки).
- Объявить
patternContentUnits="objectBoundingBox"
.
- Измените размер содержимого (вашего изображения) так, чтобы его высота и ширина были равны 1.
Вы не можете использовать 100% в качестве синонима для 1 единицы ограничивающей рамки объекта в самом содержимом шаблона (т. е. размеры изображения); проценты интерпретируются относительно размера SVG, а не objectBoundingBox.*
Я должен упомянуть, поскольку вы говорите, что ваши фигуры состоят из <path>
элементов, что ограничивающая рамка объекта — это наименьший прямоугольник, который перпендикулярен системе координат, в которой нарисован путь, и содержит все точки пути. Это не включает инсульт. Например, прямая горизонтальная линия имеет ограничивающую рамку нулевой высоты; угловая линия имеет ограничивающий прямоугольник прямоугольника, так что линия является диагональю прямоугольника. Если ваши пути имеют неправильную форму и/или не очень хорошо выровнены с системой координат, ограничивающая рамка может быть намного больше, чем путь.
Свойство preserveAspectRatio
применяется к изображениям и любому элементу, который может иметь свойство viewBox
: родительскому <svg>
, вложенным <svg>
, <symbol>
, <marker>
и <pattern>
. Для изображений соотношение сторон рассчитывается на основе соотношения ширины и высоты изображения, для всех остальных оно рассчитывается на основе значений ширины и высоты в атрибут viewBox.
Для любого типа элемента, если вы объявляете высоту или ширину для элемента, который не соответствует соотношению сторон, свойство preserveAspectRatio
определяет, будет ли содержимое растянуто по размеру (none
), подогнано под одно измерение и обрезано по размеру. другое (slice
) или уменьшено для соответствия обоим размерам с дополнительным пространством (meet
); для параметров meet
и slice
вы также указываете, как выровнять содержимое в пространстве.
Однако важно отметить, что соотношение сторон доступного пространства рассчитывается в текущей системе координат, а не в пикселях экрана. Таким образом, если viewBox или преобразование более высокого уровня изменили соотношение сторон, все еще может быть искажено, даже если для текущего элемента задано свойство saveAspectRatio.
Также следует знать, что значение по умолчанию обычно не none
. Для элементов <image>
и <pattern>
по умолчанию используется значение xMidYMid meet
, т. е. сжатие по размеру и по центру. Конечно, это значение по умолчанию влияет на элементы шаблона только в том случае, если элемент шаблона имеет свойство viewBox
(в противном случае предполагается, что он не имеет соотношения сторон, которое необходимо сохранить).
Какое значение вы хотите использовать для preserveAspectRatio
, будет зависеть от изображения и дизайна:
- Следует ли растянуть изображение, чтобы оно соответствовало форме
preserveAspectRatio="none"
?
- Следует ли сохранять соотношение сторон изображения, но размер должен полностью вписываться в форму или покрывать ее?
В первом случае (растяжение) вам не нужно ничего делать с элементом <pattern>
(отсутствие viewBox означает отсутствие управления соотношением сторон), но вам необходимо специально отключить управление соотношением сторон на изображение.
Напротив, если вы хотите избежать искажения изображения, вам необходимо:
- Установите свойства
viewBox
и preserveAspectRatio
для элемента <pattern>
;
- Установите свойство
preserveAspectRatio
в <image>
, если вы хотите что-то отличное от значения по умолчанию.
Рабочий пример
Эта скрипка показывает три способа получения изображения шаблона для заполнения формы.
В верхнем ряду отключено управление соотношением сторон.
<!-- pattern1 - no aspect ratio control -->
<pattern id="pattern1" height="100%" width="100%"
patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="none"
xlink:href="/*url*/" />
</pattern>
Средняя строка имеет управление соотношением сторон в элементе <image>
, поэтому изображение обрезается, чтобы соответствовать шаблону, но изображение по-прежнему искажается, когда шаблон рисуется в прямоугольнике, потому что единицы objectBoundingBox
, которые определяют систему координат, отличаются для высоты и ширины. . (Изображение в круге не искажено, потому что ограничивающая рамка круга представляет собой квадрат.)
<!-- pattern2 - aspect ratio control on the image only -->
<pattern id="pattern2" height="100%" width="100%"
patternContentUnits="objectBoundingBox">
<image height="1" width="1" preserveAspectRatio="xMidYMid slice"
xlink:href="/*url*/" />
</pattern>
В нижней строке для изображения и для шаблона установлено значение preserveAspectRatio
(а также для шаблона установлено значение viewBox
). Изображение обрезается, но не растягивается.
<!-- pattern3 - aspect ratio control on both image and pattern -->
<pattern id="pattern3" height="100%" width="100%"
patternContentUnits="objectBoundingBox"
viewBox="0 0 1 1" preserveAspectRatio="xMidYMid slice">
<image height="1" width="1" preserveAspectRatio="xMidYMid slice"
xlink:href="/*url*/" />
</pattern>
![Результаты скрипта Вывод из примера скрипта JS, показывающий описанные изображения](https://i.stack.imgur.com/ikx46.png)
Исходное изображение Стефана Краузе, с Викисклада. Исходное соотношение сторон — портретный режим 4:6.
* Исправление от 03.04.2015
person
AmeliaBR
schedule
05.04.2014
<feImage>
. - person AmeliaBR   schedule 06.04.2014