Подтвердить что ты не робот

Обрезка, соответствующая шаблону svg

У меня есть шаблоны, каждый из которых имеет в себе одно изображение. Мне нужно, чтобы изображения масштабировались до полной ширины или высоты их контейнеров, которые являются дорожками, сохраняя при этом их пропорции. По существу, они должны вести себя как html-изображение, если вы установите min-width:100%; min-height:100%;

Я раньше не использовал svgs и не знаю, какие атрибуты нужно изменить, чтобы получить этот тип поведения. Я пробовал всевозможные комбинации viewBox, preserveAspectRatio, patternUnits и т.д., Но я не могу получить то, что хочу.

4b9b3361

Ответ 1

Чтобы это заработало, вам нужно понять, как objectBoundingBox объекты objectBoundingBox в SVG, а также как работает preserveAspectRatio.

Объекты, ограничивающие рамки

Размер и содержание градиентов, шаблонов и ряда других возможностей SVG можно указать в терминах размера объекта (path, rect, circle), который рисуется, указав в качестве единицы objectBoundingBox. Противоположностью всегда является userSpaceOnUse, который использует систему координат, в которой нарисована фигура.

Единицы ограничительной рамки объекта обычно используются по умолчанию для объявления размера и положения графического элемента заливки; вы изменяете это, устанавливая свойство patternUnits в patternUnits <pattern>. Тем не менее, единицы пространства пользователя обычно используются по умолчанию для любых единиц, используемых в графике контента; чтобы изменить это, вы устанавливаете свойство patternContentUnits.

Итак, первый шаг: чтобы создать шаблон, который полностью заполняет форму, вам необходимо:

  • Объявите высоту и ширину шаблона как 100% (или 1); по умолчанию они будут интерпретироваться относительно ограничительной рамки).
  • patternContentUnits="objectBoundingBox".
  • Увеличьте размер содержимого (вашего изображения), чтобы оно имело высоту и ширину 1.

Вы не можете использовать 100% в качестве синонима для 1 единицы ограничивающего прямоугольника объекта в самом содержимом шаблона (т.е. Измерениях изображения); проценты интерпретируются относительно размера SVG, а не objectBoundingBox. *

Я должен упомянуть, поскольку вы говорите, что ваши фигуры являются элементами <path>, что ограничивающий прямоугольник объекта - это наименьший прямоугольник, перпендикулярный системе координат, в которой нарисован путь, и содержит все точки пути. Это не включает инсульт. Например, прямая горизонтальная линия имеет ограничивающую рамку нулевой высоты; угловая линия имеет ограничивающий прямоугольник, такой, что линия является диагональю прямоугольника. Если ваши пути имеют неудобную форму и/или не очень хорошо выровнены с системой координат, ограничивающая рамка может быть намного больше, чем путь.

Сохранение пропорций

Свойство preserveAspectRatio применяется к изображениям и любому элементу, который может иметь свойство viewBox: родительский элемент <svg>, вложенные <svg>, <symbol>, <marker> и <pattern>. Для изображений соотношение сторон вычисляется из соотношения ширины и высоты изображения, для всех остальных оно рассчитывается из чисел width: height в атрибуте viewBox.

Для любого типа элемента, если вы объявляете высоту или ширину для элемента, который не соответствует соотношению сторон, свойство preserveAspectRatio определяет, будет ли содержимое растягиваться, чтобы соответствовать (none), иметь размер, подходящий для одного измерения, и обрезаться в другой (slice) или сжатый, чтобы вместить оба измерения с дополнительным пространством (meet); для параметров meet и slice вы также указываете, как выровнять содержимое в пространстве.

Однако важно отметить, что соотношение сторон доступного пространства рассчитывается в текущей системе координат, а не в пикселях экрана. Таким образом, если высокоуровневое viewBox или преобразование изменило соотношение сторон, вещи все равно могут быть искажены даже при наличии свойства preserveAspectRatio для текущего элемента.

Другая вещь, которую нужно знать, это то, что значением по умолчанию обычно не является none. Для элементов <image> и <pattern> по умолчанию является xMidYMid meet - то есть сжимается, чтобы уместить и xMidYMid meet. Конечно, это значение по умолчанию оказывает влияние на элементы шаблона только в viewBox случае, если элемент шаблона имеет свойство 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>
    

Output from the JS fiddle example, showing the images described

Исходное изображение Стефана Краузе из Wikimedia Commons. Исходное соотношение сторон составляет 4: 6 портретного режима.

* Исправление 2015-04-03