Как я могу сделать масштаб svg с его родительским контейнером?


Я хочу иметь встроенный масштаб содержимого элемента svg, когда размер не является родным. Конечно, я мог бы иметь его как отдельный файл и масштабировать его так.

.html:<img src="foo.svg" style="width: 100%;" />

фу.svg:<svg width="123" height="456"></svg>

тем не менее, я хочу добавить дополнительные стили в SVG через CSS, поэтому связывание внешнего не является опцией. Как сделать встроенную шкалу SVG?

4 163

4 ответа:

чтобы задать координаты в изображении SVG независимо от масштабируемого размера изображения, используйте viewBox атрибут на элементе SVG, чтобы определить, что ограничивающая рамка изображения находится в системе координат изображения, и использовать width и height атрибуты для определения ширины или высоты по отношению к содержащей странице.

например, если у вас есть следующие:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

он будет отображаться как 10px на 20px треугольник:

10x20 triangle

теперь, если вы установите только ширину и высоту, это изменит размер элемента SVG, но не масштабирует треугольник:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

10x20 triangle

если вы зададите поле просмотра, это приведет к преобразованию изображения таким образом, что данное поле (в системе координат изображения) масштабируется до размера, соответствующего заданной ширине и высоте (в системе координат страницы). Например, чтобы увеличить треугольник, чтобы быть 100 Пикс. по 50 пикселей:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 triangle

если вы хотите масштабировать его до ширины окна просмотра HTML:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x150 triangle

обратите внимание, что по умолчанию, соотношение сторон сохраняется. Поэтому, если вы укажете, что элемент должен иметь ширину 100%, но высоту 50px, он фактически будет масштабироваться только до высоты 50px (если у вас нет очень узкого окна):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 triangle

если вы на самом деле хотите, чтобы он растягивался по горизонтали, отключите сохранение соотношения сторон с помощью preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x50 triangle

(обратите внимание, что в моих примерах я использую синтаксис, который работает для встраивания HTML, чтобы включить примеры в качестве изображения в StackOverflow, я вместо этого встраиваю в другой SVG, поэтому мне нужно использовать допустимый синтаксис XML)

вы хотите сделать преобразование, как такой:

С JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

С CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

оберните свою страницу SVG в тег группы как таковой и нацельте его на управление всей страницей:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Примечание: масштаб 1.0 составляет 100%

возиться и нашел этот CSS, кажется, содержит SVG в браузере Chrome до точки, где контейнер больше, чем изображение:

div.inserted-svg-logo svg { max-width:100%; }

также, кажется, работает в FF + IE 11.

после 48 часов исследований, я закончил тем, что сделал это, чтобы получить пропорциональное масштабирование:

Примечание: этот образец написан с помощью React. Если вы не используете это, измените материал camel case обратно на дефисы (т. е.: change backgroundColor до background-color и изменить стиль Object обратно в String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

вот что происходит в приведенном выше примере кода:

VIEWBOX

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, ширина и высота

ie: viewbox= "0 0 1000 1000"

Viewbox является важным атрибутом, потому что он в основном говорит SVG, какой размер рисовать и где. Если вы использовали CSS для создания SVG 1000x1000 px, но ваш viewbox был 2000x2000, вы увидите верхняя левая четверть вашего SVG.

первые два числа, min-x и min-y, определите, должен ли SVG быть смещен внутри поля просмотра.

мой SVG должен сдвигаться вверх / вниз или влево/вправо

проверьте это: viewbox= "50 50 450 450"

первые два числа сдвинут ваш SVG влево на 50px и вверх на 50px, а вторые два числа-это размер окна просмотра: 450x450 px. Если ваш SVG 500x500, но на нем есть дополнительное дополнение, вы можете манипулировать этими числами, чтобы переместить его внутри "viewbox".

ваша цель на данный момент, чтобы изменить один из этих чисел и посмотреть, что происходит.

вы также можете полностью опустить поле просмотра, но тогда ваш пробег будет варьироваться в зависимости от всех других настроек, которые у вас есть в то время. По моему опыту, вы столкнетесь с проблемами сохранения соотношения сторон, потому что viewbox помогает определить соотношение сторон.

СОХРАНИТЬ СООТНОШЕНИЕ СТОРОН

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

на основе моих исследований, есть много различных параметров соотношения сторон, но по умолчанию один называется xMidYMid meet. Я надел его на себя, чтобы явно напомнить себе. xMidYMid meet делает его масштаб пропорционально на основе средней точки X и Y. Это означает, что он остается в центре поля просмотра.

ширина

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

посмотрите на мой пример кода выше. Обратите внимание, как я устанавливаю только ширину, без высоты. Я установил его на 100%, чтобы он заполнял контейнер, в котором он находится. Это то, что, вероятно, вносит наибольший вклад в ответ на этот вопрос переполнения стека.

вы можете изменить его на любое значение пикселя, которое вы хотите, но я бы рекомендовал использовать 100%, как я сделал, чтобы взорвать его до максимального размера, а затем управлять им с помощью CSS через родителя контейнер. Я рекомендую это, потому что вы получите "правильный" контроль. Вы можете использовать медиа-запросы, и вы можете контролировать размер без сумасшедшего JavaScript.

МАСШТАБИРОВАНИЕ С ПОМОЩЬЮ CSS

посмотрите на мой пример кода выше еще раз. Обратите внимание, как у меня есть эти свойства:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

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

мы оставляем высоту в покое и / или устанавливаем ее на авто, и мы контролируем изменение размера с шириной. Я выбрал ширину, потому что она часто более значима из-за отзывчивых конструкций.

вот изображение этих настроек используется:

enter image description here

если Вы читаете каждое решение в этом вопросе и все еще не знаете или не видите то, что вам нужно, проверить эта ссылка здесь. Я нашел это очень полезным:

https://css-tricks.com/scale-svg/

это массивная статья, но она ломается практически всеми возможными способами манипулировать SVG, с CSS или без него. Я рекомендую прочитать его во время небрежно пить кофе или ваш выбор избранных жидкостей.