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

Автор: Евгений Рыжков и Тимур Лисица Дата публикации: 21.11.2010

В предыдущем примере, пропорции или соотношение ширины и высоты графического окна и viewBox были идентичными (4/5=64/80). Что же происходит, если пропорции области просмотра и viewBox будут разными? Например, где пропорциональность viewBox равна 1/1, а у области просмотра — 1/3?

<svg width="45px" height="135px" viewBox="0 0 90 90">

SVG в такой ситуации может пойти тремя путями:

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

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

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

Задаем выравнивание с preserveAspectRatio

Атрибут preserveAspectRatio позволяет определить выравнивание отмасштабированного изображения относительно области просмотра. Так же может сделать так чтобы изображение полностью соответствовало области просмотра или были обрезаны части изображения.

preserveAspectRatio="alignment [meet | slice]"

где alignment определяет ось и выравнивание. Принимает одно из значений: xMinYMin, xMinYMid, xMinYMax, xMidYMin, xMidYMid, xMidYMax, xMaxYMin, xMaxYMid или xMaxYMax. Эти значения приводят к одному из способов выравнивания, которые расписаны в таблице ниже.

Заметка

y-выравнивание начинается с заглавной буквы для удобство восприятия, т.к. x- и y- выравнивания пишутся одним словом.

Выравнивание по оси X
значениедействие
xMin выровнять в соответствии с минимальным значением x viewBox — левая граница области просмотра.
xMid выровнять в соответствии с центральной точкой по x viewBox — центр по оси X в области просмотра.
xMax выровнять в соответствии с максимальным значением x viewBox — правая граница области просмотра.
Выравнивание по оси Y
значениедействие
YMin выровнять в соответствии с минимальным значением y viewBox — верхняя граница области просмотра.
YMid выровнять в соответствии с центральной точкой по y viewBox — центр по оси Y в области просмотра.
YMax выровнять в соответствии с максимальным значением y viewBox — нижняя граница области просмотра.

Итак, если Вы хотите, чтобы изображение с viewBox= "0 0 90 90" полностью вместилось в область просмотра с width=45 и height=135, располагалось в верхнем левом углу, необходимо написать:

<svg width="45px" height="135px" viewBox="0 0 90 90" preserveAspectRatio="xMinYMin meet">

Заметка

В данном примере изображение получит ширину равную ширине области просмотра. В таком случае визуально получили бы такой же результат даже если задали значения xMidYmin или xMaxYMin. Но для большей корректности следует указывать одинаковые значения (min-min, mid-mid, max-max).

Но все это достаточно абстрактно и туманно. Нужны конкретные примеры, которые разъяснили бы всю эту мутную теорию. Вот несколько таких, которые показывают Вам, как срабатывает выравнивание в комбинации со спецификаторами meet и slice.

Использование спецификатора meet

Спецификатор meet указывает, что изображение должно сохранить свои пропорции и быть полностью видимым. Следующие примеры демонстрируют действие meet вместе с различными вариантами выравнивания:

<!-- высокое окно просмотра -->
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 90 90" width="45" height="135">
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 90 90" width="45" height="135">
<svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 90 90" width="45" height="135">
<!-- узкое окно просмотра -->
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 90 90" width="135" height="45">
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 90 90" width="135" height="45">
<svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 90 90" width="135" height="45">
Выравнивание в сочетании с meet Выравнивание в сочетании с meet

Использование спецификатора slice

Спецификатор slice означает, что изображение должно сохранить свои пропорции и будет отмасштабировано в соответствии с максимальным граничным значением области просмотра. Части изображения, которые не помещаются в область просмотра, будут обрезаны.

<!-- высокое окно просмотра -->
<svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 90 90" width="45" height="135">
<svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 90 90" width="45" height="135">
<svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 90 90" width="45" height="135">
<!-- узкое окно просмотра -->
<svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 90 90" width="135" height="45">
<svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 90 90" width="135" height="45">
<svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 90 90" width="135" height="45">
выравнивание в сочетании со slice Выравнивание в сочетании со slice

Использование спецификатора none

Спецификатор none означает, что изображение должно полностью отобразится в области просмотра даже если придется исказить пропорции изображения.

<!-- высокое окно просмотра -->
<svg preserveAspectRatio="none" viewBox="0 0 90 90" width="45" height="135">
<!-- узкое окно просмотра -->
<svg preserveAspectRatio="none" viewBox="0 0 90 90" width="135" height="45">
Выравнивание в сочетании с none Выравнивание в сочетании с none

Куда дальше