Трансформация изображений SVG при изменении параметров Viewbox

  1. Введение
  2. SVG viewport
  3. SVG viewBox
  4. Процесс взаимодействия viewport и viewBox
    1. Смещение начала координат viewBox по одной оси
    2. Смещение начала координат viewBox по двум осям
  5. Изменение масштаба с помощью viewBox
    1. Увеличение масштаба М2:1
    2. Уменьшение масштаба М1:2

Введение

Изменение параметров viewBox – атрибута элемента SVG позволяет масштабировать, фрагментировать, перемещать исходное изображение вдоль осей координат. Но довольно часто возникают вопросы: “Почему, изменив параметры viewBox, я получаю совсем не то, что ожидал увидеть?”. Вместо увеличения картинки в 2 раза, она совсем пропадает с дисплея или сдвигается не в ту сторону и т.д. Чтобы разобраться в причинах этих “аномалий” рассмотрим подробно процессы взаимодействия областей просмотра элемента SVG и его параметра viewBox.

Лист.1

2. SVG viewport

В фрагменте кода (см. Лист.1) третья строка определяет прямоугольную область просмотра – SVG viewport и систему координат viewport coordinate system с началом координат (0,0) в левом верхнем углу, положительным направлением оси абцисс “X” – вправо и положительным направлением оси ординат “Y” – вниз. В нашем примере ширина прямоугольной области просмотра – width=”400px” и высота – height=”400px”. По умолчанию ед. измерения в пикселях и поэтому “px” можно не указывать. Также могут применяться и другие единицы измерения, например дюймы: <svg width=”20in” height=”20in” …>(см. Лист.2)

Лист.2

3. SVG viewBox

4-я строка кода см. Лист. 1 , – viewBox=”0 0 400 400″ – определяет пользовательскую область просмотра –User Space с пользовательской системой координат – User Coordinate system. Так как viewPort является предком для viewBox, то начало системы координат viewBox, по умолчанию, также как и системы координат viewPort находится в левом верхнем углу (0,0) и положительное направление оси “X” – будет также вправо, а оси “Y” – вниз.
Первые два числа ViewBox = “min-x” и “min-y” задают начало пользовательской системы координат, “width” и “height” – определяют ширину и высоту “пользовательской области просмотра” и одновременно отвечают за масштабирование изображения.
Четыре параметра viewBox разделяют пробелами или запятыми.

Лист.3
“Пользовательская область просмотра”, создаваемая параметром viewBox, является виртуальной, невидимой областью для пользователя и служит для трансформации изображения, получаемого из области просмотра SVG viewport.
Другими словами, при наличии в коде файла SVG объявления viewBox=”….”, всегда есть две области просмотра, каждая со своими осями и своим началом координат.

4. Процесс взаимодействия viewport и viewBox

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

Далее в тексте и на рисунках для обозначения ширины и высоты приняты следующие сокращения:

  1. для области просмотра ” SVG viewport” – “SVG width” и “SVG height
  2. для области просмотра “viewBox” – “viewBox width” и “viewBox height

Рассмотрим пример, когда параметры этих областей просмотра совпадают. Всё, что находится вне области, ограниченной осями “SVG width” и “SVG height” не отображается.
Например: большая часть прямоугольника “5” красного цвета см. Лист.4 и Рис.1

Лист.4
не попадает в область просмотра, так как он имеет начало координат по оси Х=390px, ширина его 100px, поэтому от прямоугольника остается в видимой области по ширине только: 400px-390px=10px. Остальные 90px вне области видимости.
Вторая область – viewBox служит для трансформации векторной графики полученной от SVG viewport – первой области просмотра.
В процессе согласования – “by a negotiation process” сравниваются параметры двух областей просмотра: SVG viewport и viewBox. Если они полностью совпадают, как в нашем примере, то графика от viewBox без изменений передается обратно в первую область просмотра viewport см. Рис.1

ViewPort = ViewBox
Рис.1

Прерывистый голубой контур и квадратики показывают границы и область просмотра SVG viewport.

4а. Смещение начала координат viewBox по одной оси

Изменяя параметры viewBox: min-x, min-y, можно сместить начало пользовательских координат относительно начала координат SVG viewport.
viewBox=”70px, 0, 400px, 400px” см. Рис.2

пользовательская система координат ViewBox
Рис.2

На Рис.2 начало пользовательских координат сдвигается вправо на 70px, тем самым сдвигая вправо по оси абцисс всю прямоугольную область просмотра viewBox (400 x 400px). При этом происходит захват изображения фрагмента документа SVG, который находится под viewBox, а далее область просмотра viewBox, с захваченным фрагментом, обратно совмещается с неподвижной областью просмотра viewport с началом координат (0,0) в левом верхнем углу. Координаты фигур пересчитываются с учетом последнего сдвига на 70px влево. Формально получается, что в неподвижной области просмотра viewport, при применении viewBox, фрагмент документа SVG сдвинулся влево.
Поэтому в нашем примере на ширине 70px появляется, скрытая ранее, большая часть красного прямоугльника – 5, а зелёный и жёлтый круг обрезаются слева по ширине на 70px. см. Рис.3

Рис.3

Посмотреть, как это происходит можно на демо.

4б. Смещение начала координат viewBox по двум осям

Теперь переместим начало координат по двум осям сразу в точку (70,70):
viewBox=”70px, 70px, 400px, 400px”. Для наглядности добавим внизу еще один красный прямоугольник – (6). см.Рис.4

После переноса начала координат в область видимости viewBox попадает прямоугольный (400×400)px фрагмент SVG документа с отсчетом ширины и высоты от начала координат (70,70). Происходит захват изображения. Далее начало координат viewBox (70,70) совмещается с началом координат viewport (0,0). Координаты фигур пересчитываются.

Изменение начала координат viewBox одновременно по осям X и Y
Рис.4

Поэтому становятся полностью видны красные прямоугольники 5 и 6. Всё, что не попадает в эту область, отсекается. Например, часть площадей цветных окружностей 1,2 и 4.

Изменение координат viewBox произведено
Рис.5

Другими словами, перемещая начало координат viewBox вправо и вниз на 70px, в итоге получаем перемещение фрагмента документа SVG в области просмотра viewport влево и вверх.

5. Изменение масштаба с помощью viewBox

За масштаб фрагмента документа SVG отвечает пропорциональное соотношение ширин и высот соответственно двух областей просмотра: viewport и viewBox. Если соотношение сторон равны 1, то конечное изображение будет передано в масштабе 1:1, то есть без трансформации.

Рис.6

Если соотношение сторон будет отличаться от единицы, то масштаб будет меняться в сторону увеличения или уменьшения.

5.а Увеличение масштаба М2:1

Соотношение сторон областей просмотра, в этом примере, равно 400 / 200=2, поэтому масштаб фрагмента изображения досумента SVG будет М2:1.

Рис.7

Как происходит увеличение масштаба поясняют рисунки 7 и 8. Прямоугольная область просмотра viewBox захватывает фрагмент изображения (200 х 200)px.

Рис.8

При совмещении с первой областью просмотра происходит растягивание захваченного изображения до границ SVG viewport (400 x 400)px. Один пиксель viewBox занимает теперь два пикселя SVG viewport. Все размеры фигур пересчитываются умножением на х 2.

5.б Уменьшение масштаба М1:2

Соотношение сторон областей, в этом примере, равно 400 / 800=1/2, поэтому масштаб фрагмента изображения досумента SVG будет М1:2.

Рис.9

viewBox захватывает прямоугольный фрагмент (800 х 800)px, то есть всю область видимости SVG viewport (400 x 400)px и дополнительно по 400px справа и снизу от viewport.

Рис.10

При обратном совмещении, захваченного фрагмента изображения (800 x 800)px с областью видимости SVG viewport (400 x 400)px, происходит уменьшение масштаба изображения М1:2, так как 2 пикселя viewBox совмещаются c 1 пикселем SVG viewport.

⇚ Как добавить SVG в HTML5 страницу SVG marker ⇛

Трансформация изображений SVG при изменении параметров Viewbox: 8 комментариев

  1. Пацан! Афигенно! Ты только болт на проект не клади, а ещё публикуйся на http://habrahabr.ru/ с линковками сюда. В общем ты делаешь серьёзное и важное дело – тебе бы как-то «обаблоситься» по этому направлению…

  2. Народ, вы понимаете сколько нужно было читать доки чтобы написать такой концентрат. Спасибо тебе добрый человек.

  3. Ломал голову над viewBox, не понимал как работает, но после Вашей статьи все теперь ясно, гигантское спасибо!

  4. Спасибо автору, годная статья! Мне понравилась.
    Всё довольно подробно расписанно и разжёвано!
    Вы сделали большую работу )

  5. Великолепная статья! Все понял с первого раза! Автору огромное спасибо!

Добавить комментарий