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

180

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

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

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

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

  • 1
    попробуйте precents в ширину и высоту SVG.
  • 0
    @ncm Как бы это сделать с JS?
Теги:
svg
scaling

5 ответов

362
Лучший ответ

Чтобы указать координаты в изображении 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

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

<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%, но высоту 50 пикселей, он будет фактически масштабироваться только до высоты 50 пикселей (если у вас не очень узкое окно):

<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)

  • 1
    Как вы делаете не только viewBox preserveAspectRatio, но и основной блок? Я хочу ширину: 100%; высота: авто для него.
  • 1
    @Dude: Я думаю, что пример с width="100%" и без указания высоты делает то, что вы хотите. Я добавил изображения для демонстрации. Он имеет ширину 100% и пропорционально увеличивает высоту. Если это не то, что вы ищете, вы можете уточнить, что вы имели в виду?
Показать ещё 4 комментария
17

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

с 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%

  • 3
    Хорошо. Я не хочу JS в этом. Есть ли способ сделать так, чтобы он соответствовал родителю?
  • 0
    @bj setAttribute - это то же самое, что и <tag attribute = "value">
15

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

ПРИМЕЧАНИЕ. Этот образец написан с использованием React. Если вы не используете это, измените материал дела верблюда обратно на дефисы (то есть: измените 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, ширина и высота

т.е.: 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, но на нем есть дополнительные отступы, вы можете манипулировать этими числами, чтобы перемещать их внутри "окна просмотра".

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

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

СОХРАНЯТЬ АСПЕКТ

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 поддерживает свое собственное соотношение сторон, вам нужно только изменить ширину в родительском контейнере, и она изменит размер по желанию.

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

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

Изображение 5044

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

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

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

  • 0
    Очень хороший и подробный ответ!
10

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

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

Также, похоже, работает в FF + IE 11.

  • 0
    Это решило проблему для меня. Я только видел переполнение в iOS все же. Спасибо!
  • 4
    Использование max-width: 100% и max-height: 100% заставит svg всегда масштабироваться до контейнера без переполнения или потери соотношения сторон.
Показать ещё 1 комментарий
0

Настройка атрибута currentScale работает в IE (я тестировал IE 11), но не в Chrome.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню