Карманное руководство по написанию SVG. Глава 3
Перевод книги Pocket Guide to Writing SVG, c разрешения автора — Джони Трайтел.
|
Глава 3. Рабочая область
Пожалуй, самым важным аспектом SVG, после понимания его главной структуры и умения создавать основные фигуры, является получение представления об используемой рабочей области, или другими словами, системы координат, в которой будет отображаться графика.
Понимание рабочей области SVG полезно в правильной отрисовке вашего графического объекта, но становится решающим, как только вы столкнётесь с более продвинутыми возможностями SVG. Например, отображение градиентов и паттернов в значительной степени зависит от установленной системы координат. Рабочая область определяется размерами области просмотра и атрибутами viewBox
.
У этой груши, к счастью, область просмотра и viewBox
совпадают:
<svg width="115" height="190" viewBox="0 0 115 190"> <!--<path <контур изображения груши> />--> </svg>
Вся груша видна в браузере и будет масштабироваться соответственно при изменении размеров области просмотра.
Область просмотра
Область просмотра является видимой частью SVG. Хотя SVG может быть какой угодно ширины или высоты, ограничение области просмотра будет означать, что в любой момент времени может быть видна только часть изображения.
Область просмотра устанавливается атрибутами height
и width
в элементе <svg>
.
Если эти значения не заданы, размеры рабочей области обычно будут определены по другим показателям в SVG, например, по ширине самого внешнего элемента SVG. Однако, без указания этих значений есть риск, что графический объект обрежется.
viewBox
viewBox
дает возможность указать, что данный набор графических элементов растягивается, чтобы уместиться в определенный элемент-контейнер. Эти значения включают четыре числа, разделённые запятыми или пробелами: min-x
, min-y
, width
и height
которым чаще всего следует задать значения границ области просмотра.
Значения min
определяют, в какой точке внутри изображения должен начинаться viewBox, в то время как width
и height
устанавливают размер блока.
Если мы решим не определять viewBox
, тогда изображение не будет масштабироваться, чтобы совпадать с границами установленными областью просмотра.
Если отнять по 50px от width
— и height
-составляющих viewBox
изображения груши, видимая часть груши уменьшится, но затем эта оставшаяся видимая часть отмасштабируется, чтобы вписаться в границы области просмотра.
<svg width="115px" height="190px" viewBox="0 0 65 140"> <!--<path <контур изображения груши> />--> </svg>
Значения min
во viewBox
определяют начало viewBox
в пределах родительского элемента. Другими словами, точку во viewBox
, в которой вы хотите, чтобы начиналась область просмотра. Чуть выше в изображении груши значения min установлены в 0, 0 (верхний левый угол). Давайте изменим их на 50, 30: viewBox="50 30 115 190"
.
<svg width="115" height="190" viewBox="50 30 115 190"> <!--<path <контур изображения груши> />--> </svg>
Теперь viewBox
начинается с 50px по оси х
и с 30px по оси y
. В ходе редактирования этих значений та часть груши, которая находится в фокусе, изменилась.
preserveAspectRatio
Если пропорции ширины и высоты области просмотра и viewBox
не совпадают, то артибут preserveAspectRatio
указывает браузеру, как отображать рисунок.
preserveAspectRatio
принимает два параметра, <align>
и <meetOrSlice>
. Первый состоит из двух частей и задаёт выравнивание viewBox
в области просмотра. Второй является необязательным и указывает, как пропорции должны быть сохранены.
preserveAspectRatio="xMaxYMax meet"
Эти значения выравнивают нижний правый угол viewBox
по нижнему правому углу области просмотра. meet
сохраняет пропорции, масштабируя viewBox
, чтобы уместиться в область просмотра насколько это возможно.
У атрибута <meetOrSlice>
может быть одно из трех значений: meet (по умолчанию), slice, и none. В то время как meet
гарантирует полную видимость графики (насколько это возможно), slice
старается заполнить область просмотра с viewBox
и затем обрезать все части изображения, которые не поместились в область просмотра после этого масштабирования. none
не сохраняет пропорции и скорее всего исказит изображение.
Возможно самое незамысловатое значение здесь – это «none», которое показывает, что масштабирование не должно быть равномерным. Если мы увеличим пиксельные значения области просмотра на следующем изображении вишенок, то оно будет неравномерно растянуто и выглядеть искажённым.
<svg width="500" height="400" viewBox="0 0 250 600" preserveAspectRatio="none"> <!--<path <контур изображения вишенок> />--> </svg>
preserveAspectRatio
для изображения ниже установлен в xMinYMax meet
и выравнивает нижний левый угол viewBox
по нижнему левому углу области просмотра (которая теперь обведена). meet
гарантирует, что изображение отмасштабируется таким образом, чтобы вместиться в область просмотра насколько это возможно.
<svg width="350" height="150" viewBox="0 0 300 300" preserveAspectRatio="xMinYMax meet" style="border: 1px solid #333333;"> <!--<path <контур изображения вишенок> />--> </svg>
Здесь те же самые вишенки, но meet
изменён на slice
:
<svg width="350" height="150" viewBox="0 0 300 300" preserveAspectRatio="xMinYMax slice" style="border: 1px solid #333333;"> <!--<path <контур изображения вишенок> />--> </svg>
Заметьте, что значения выравнивания не зависят друг от друга.
<svg width="350" height="150" viewBox="0 0 300 300" preserveAspectRatio="xMinYMid slice" style="border: 1px solid #333333;"> <!--<path <контур изображения вишенок> />--> </svg>
В примере выше значения preserveAspectRatio
установлены в xMinYMid slice
; теперь вишенки выравнены по середине оси y
области просмотра.
Преобразования системы координат
SVG включает дополнительные возможности изменения графики, такие как вращение, масштабирование, перемещение и наклон при помощи трансформации. SVG-автор может добавить трансформации к определённым элементом или к целой группе элементов.
Эти функции включены в управляемый элемент и находятся в атрибуте <transform>
. Можно использовать и множественные трансформации, подключив несколько функций внутри этого атрибута. Например: transform="translate(<tx>,<ty>) rotate(<угол поворота>)" />
.
При трансформации SVG важно учитывать то, что она влияет на вашу систему координат, т.е. на рабочую область. Это происходит потому, что трансформация создаёт новую действующую систему координат SVG-элемента, фактически копируя оригинал, а затем накладывая трансформацию на новую систему координат.
Следующая картинка показывает трансформацию системы координат, происходящую при наложении сдвига на (100,100) на группу с графикой:
Сама система координат переместилась, а изображение лайма и лимона сохранило своё исходное местоположение в системе. Новая действующая система координат начинается в точке (100,100) в исходной системе координат.
Из-за этой связи с системой координат, многие из этих функций будут передвигать графику даже без явного задания сдвига для нее. Например, при попытке увеличить размер изображения в три раза, путём установки scale
в значение «3», на «3» умножатся и координаты x
и y
, а изображение отмасштабируется вместе с ними, сместившись по экрану при этом.
В случае вложенных трансформаций эффекты накапливаются, поэтому окончательная трансформация на дочернем элементе будет основываться на суммарном эффекте трансформаций его предков.
translate
Функция translate
задаёт подробности сдвига фигуры, а два числовых значения, используемые здесь, управляют сдвигом самой фигуры вдоль x
— и y
-осей: transform="translate(<tx>,<ty>)"
. Эти значения могут быть разделены пробелом или запятой.
Значение y
является необязательным, и если оно опущено, то предполагается, что оно равно «0».
rotate
Значение в rotate
указывает поворот фигуры вокруг ее начальной точки (в градусах), которой в SVG является 0, 0 (левый верхний угол): transform="rotate(<угол поворота>)"
.
Также здесь есть возможность добавить значения x
и y
: transform=rotate(<угол поворота> [<cx>,<cy>])
. Если эти значения выставлены, то они определяют новые координаты центра поворота, отличные от тех, которые выставлены по умолчанию (т.е. 0, 0).
На рисунке ниже изображено два состояния яблока до и после применения к нему поворота в 20 градусов: transform="rotate(20)"
. Заметьте, что это изображение не отражает изменение координат, которое происходит вследствие этой трансформации.
scale
Масштабирование позволяет изменять размеры SVG-элемента при помощи функции scale
. Эта функция принимает одно или два значения, которые указывают горизонтальный и вертикальный масштаб вдоль соответствующей оси: transform="scale(<sx> [<sy>])"
.
Значение sy
является необязательным, и если оно не указано, то предполагается, что оно равно sx
, что гарантирует пропорциональное изменение размеров.
Значение масштаба ".5" отобразит графику вполовину от ее исходного размера, тогда как значение "3" увеличит исходный размер втрое. Значение "4,2" отмасштабирует графику вчетверо по ширине и вдвое по высоте относительно исходных размеров.
skew
SVG-элемент может быть наклонён или скошен набок при помощи функций skewX
и skewY
. Значение, включённое в эти функции представляет трансформацию наклона в градусах вдоль соответствующей оси.
На рисунке ниже изображено два состояния яблока до и после добавления ему skewX
в значении «20»: transform="skewX(20)"
. Заметьте, что это изображение не отражает изменение координат, которое происходит вследствие этой трансформации.
Публикуется под лицензией Attribution-NonCommercial-ShareAlike 4.0
P.S. Это тоже может быть интересно:
Видимо, здесь ошибка, в оригинале сказано про разделение пробелами и запятыми.
В целом же очень хороший перевод полезного материала, спасибо!
Да, точно! Спасибо вам большое за найденный ляп. Исправили:)
В спецификации ещё xMidYMid есть — очень полезное значение!
Кстати, почему до сих пор не введёте disqus?
Большое спасибо! Очень полезно!
Все искал этот атрибут:
preserveAspectRatio="none"
Давно хотел разобраться с svg, прошу поправить и объяснить правильно, чтобы в дальнейшем не пришлось переобдумывать заново )), вот насколько мне удалось понять про пропорции,а именно про параметры meet? если viewport, к примеру имеет w=150 h=300, viewbox w=300 h=500( в пропорциях (w=1/2, h=3/5)), то стороны изображение будут подстраиваться только под наименьшую сторону, то есть, в данном случае ширина меньше(0.5<0.6) высоты, и значит что высота viewboxa будет подстраиваться под значения ширины, но только до тех пор, пока, например, высоту мы не перевалим за 1/2, то есть все что меньше, а это 1/3 и т.п. и как только высота, например, будет установлена 1/3 в пропорциях, вся область будет уже пропроционировать относительно этой самой высоты, а не ширины, и ни капли больше или меньше(на примере, есть фигура 100×100, уменьшив ее сторону до 100×50, обе стороны приравняются к меньшему числу и будет 50×50??). Что касается slice, то все с точностью да наоборот, то есть у нас viewport w=150 h=300, viewbox w=150 h=10000, естественно уменьшить меньше чем на 100%(1/1) мы не силах, потому что стороны приравниваются к самой большей, к примеру, если увеличена одна стороны в соотношении (viewport)5/3(viewbox), а другая 5/4, то обе стороны будут 5/3(на примере, фигура 150×100, будет спроецирована как 150×150 это при slice, а при meet 100×100)? правильно переварил, или что-то упустил?
Тут должно 4 человека переварить и проверить то, что вы ( или ты ) написал(и).
Интересно, но слишком сложно.
А есть способы попроще?
В функциях rotate, scale значения дублируются закрывающими, если правильно понял это опечатки.
Спасибо! Fixed.