Трансформация в SVG: масштабирование

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

Масштаб SVG объектов происходит аналогично перемещению — с помощью изменения параметров локальной системы координат (в данном случае это будет масштабирование). Для этого используем значение scale атрибута transform:

transform="scale(value)"

умножаем координаты х и у на указанное value.

transform="scale(x-value, y-value)"

координаты x умножаются на x-value, y — на y-value.

Рассмотрим пример пропорционального масштабирования, в котором значение по обеим осям умножается на 2 (пунктирные линии с точками на рисунке показывают интересующую нас зону холста). Левый верхний угол квадрата имеет координаты (10, 10).

<svg width="200px" height="200px" viewBox="0 0 200 200">
<g id="square">
	<rect x="10" y="10" width="20" height="20" style="fill: none; stroke: black;"/>
</g>
<use xlink:href="#square" transform="scale(2)"/>
</svg>
равномерный масштаб изображения

Хм...Квадрат стал больше — это ожидалось. А вот почему он находится в другом месте?. Все становиться ясно, когда посмотрим на следующий рисунок.

равномерный масштаб изображения

Координатная сетка не переместилась: точка (0, 0) в системе координат находиться на том же месте. Но каждая координата стала в 2 раза больше, чем была — произошло увеличение всей координатной сетки. На рисунке по линиям видно, что левый верхний угол прямоугольника все еще в точке (10, 10) — объект не был перемещен.

Масштаб системы координат также объясняет, почему контур увеличенного квадрата стал толще. Stroke-width измеряется в системе координат пользователя и эта единица тоже стала в 2 раза больше. Соответственно и кисть стала толще.

Следует запомнить

Трансформация scale (масштабирование) не изменяет ни размеры объекта, ни ширину кисти — меняется только размер системы координат по отношению к холсту.

А что же получится, если задать разные коэффициенты масштабирования? Пробуем: по оси х коэффициент равен 3, по у — 1,5.

неравномерное масштабирование

Оказывается толщина кисти элемента, как и сам элемент, также масштабируется неравномерно.

В выше приведенных примерах мы применяли атрибут transform к элементу <use>. Но с таким же успехом его можно применить трансформацию и к группе элементов:

<g id="group1" transform="translate(3, 5)">
	<line x1="10" y1="10" x1="30" y2="30"/>
	<circle cx="20" cy="20" r="10"/>
</g>

Можете применить трансформацию и к отдельному объекту:

<rect x="15" y="20" width="10" height="5" transform="scale(3)" style="fill: none; stroke: black;"/>

В этом примере ширина и высота масштабированного прямоугольника должна стать в 3 раза больше, чем была. Но пример интресен еще и таким вопросом: координаты х и у определяются до или после того, как прямоугольник масштабируется? Т.е. будет ли объект «пермещен»? Ответ — SVG применяет трансформацию к системе координат до того, как будет отрисована фигура, т.е. фигура будет «перемещена» относительно немасштабируемых объектов. Следующий пример демонстрирует масштабирование прямоугольника отдельно от остальных элементов:

<!-- линии в немасштабируемой системе кординат -->
<line x1="0" y1="0" x2="100" y2="0" style="stroke: black;"/>
<line x1="0" y1="0" x2="0" y2="100" style="stroke: black;"/>
<line x1="45" y1="0" x2="45" y2="100" style="stroke: gray;"/>
<line x1="0" y1="60" x2="100" y2="60" style="stroke: gray;"/>
<!-- масштабируемый прямоугольник -->
<rect x="15" y="20" width="10" height="5" transform="scale(3)" style="fill: none; stroke: black;"/>

Результат на демо примере или рисунке ниже. Координатная сетка нарисована линиями в немасштабируемой системе координат.

масштабирование одной фигуры

Эффект масштабирования к конкретным фигурам такой же, если бы трансформация была применена к группе:

<g transform="scale(3)">
	<rect x="15" y="20" width="10" height="5" style="fill: none; stroke: black;"/>
</g>

Куда дальше