Как трансформировать SVG через translate, scale, rotate и skew

SVG-трансформации меняют отображение графических элементов без переписывания их геометрии. Используйте атрибут transform, чтобы перемещать, изменять размер, поворачивать или наклонять SVG-фигуры с помощью функций translate(), scale(), rotate(), skewX() и skewY(). Матричную форму той же идеи смотрите в статье Матрица трансформации.

В этой статье вы узнаете, как:

  • перемещать SVG-элементы с помощью translate();
  • изменять размер SVG-элементов с помощью scale();
  • поворачивать SVG-элементы вокруг начала координат или выбранной точки;
  • наклонять SVG-графику с помощью skewX() и skewY();
  • понимать, почему порядок transform-функций важен при их объединении.

Как трансформировать SVG-элементы

  1. Выберите SVG-элемент или группу, которую нужно трансформировать.
  2. Добавьте атрибут transform к этому элементу или к родительской группе <g>.
  3. Используйте translate(tx, ty), чтобы переместить элемент.
  4. Используйте scale(sx, sy), rotate(angle cx cy), skewX(angle) или skewY(angle), чтобы изменить видимую геометрию.
  5. Объединяйте transform-функции только тогда, когда нужен комбинированный эффект, и внимательно проверяйте порядок.
  6. Используйте matrix(a,b,c,d,e,f) только тогда, когда одна матрица понятнее, чем отдельные transform-функции.

Перемещение SVG с translate()

Перемещение сдвигает каждую точку элемента на одно и то же расстояние. Функция translate(tx, ty) перемещает элемент на tx вдоль оси x и на ty вдоль оси y. Если ty не указан, он считается равным 0.

ПараметрОписание
txГоризонтальное смещение, положительное значение – вправо, отрицательное – влево
tyВертикальное смещение, положительное значение – вниз, отрицательное – вверх

Действие атрибута transform="translate(tx, ty)" означает изменение координат объекта по формулам:

x(new) = x(old) + tx

y(new) = y(old) + ty

Простой пример:

 1<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> 
 2    <g fill="none">
 3        <!-- no translation -->
 4        <circle cx="15" cy="15" r="10" stroke="blue" />
 5        <!-- horizontal translation -->
 6        <circle cx="15" cy="15" r="10" stroke="black" transform="translate(22)" />
 7        <circle cx="15" cy="15" r="10" stroke="red" transform="translate(44)" />
 8        <!-- both horizontal and vertical translation -->
 9        <circle cx="15" cy="15" r="10" stroke="green" transform="translate(33,13)" />
10        <circle cx="15" cy="15" r="10" stroke="yellow" transform="translate(11,13)" />
11	</g>
12</svg>

В примере элемент <g> группирует круги, а fill="none" применяется ко всем кругам внутри группы. Изображение ниже показывает исходный круг и его смещенные копии ( translation.svg):

Пять олимпийских колец как пример SVG-перемещения через translate

Масштабирование SVG с scale()

Масштабирование увеличивает или уменьшает элемент на заданный коэффициент. Функция scale(sx, sy) умножает ширину элемента на sx, а высоту – на sy. Если sy не указан, SVG использует то же значение, что и sx, поэтому элемент масштабируется равномерно.

ПараметрОписание
sxКоэффициент масштабирования по горизонтали
syКоэффициент масштабирования по вертикали, необязательный
 1<svg viewBox="-50 -50 200 200" xmlns="http://www.w3.org/2000/svg">
 2    <!-- uniform scale -->
 3    <circle cx="0" cy="0" r="10" fill="#B0C4DE" transform="scale(4)" />
 4    <circle cx="0" cy="0" r="10" fill="#DDA0DD" transform="scale(3)" />
 5    <circle cx="0" cy="0" r="10" fill="#FFB6C1" transform="scale(2)" />
 6    <!-- no scale -->
 7    <circle cx="0" cy="0" r="10" fill="#5F9EA0" />
 8    <g transform="translate(100)">
 9        <!-- uniform scale -->
10        <circle cx="0" cy="0" r="10" fill="#B0C4DE" transform="scale(4)" />
11        <!-- vertical scale -->
12        <circle cx="0" cy="0" r="10" fill="#DDA0DD" transform="scale(1,4)" />
13        <!-- horizontal scale -->
14        <circle cx="0" cy="0" r="10" fill="#FFB6C1" transform="scale(4,1)" />
15        <!-- no scale -->
16        <circle cx="0" cy="0" r="10" fill="#5F9EA0" />
17    </g>
18</svg>

Результат выглядит так ( scaling.svg):

Четыре цветных круга, показывающие равномерное и направленное масштабирование SVG

Код выше использует scale() и translate(). Первая группа показывает равномерное масштабирование, где обе оси используют один коэффициент. Вторая группа показывает направленное масштабирование: scale(1,4) растягивает круг по вертикали, а scale(4,1) – по горизонтали.

Поворот SVG с rotate()

Функция rotate(angle, cx, cy) поворачивает элемент на angle градусов вокруг точки (cx, cy). Если cx и cy не указаны, SVG поворачивает элемент вокруг (0, 0) в текущей системе координат.

ПараметрОписание
angleУгол поворота в градусах, положительное значение – по часовой стрелке
cxX-координата центра поворота, необязательная
cyY-координата центра поворота, необязательная

Все значения углов для rotate() и skew задаются в градусах; другие CSS-единицы для этих функций SVG не используются. Положительный угол дает поворот по часовой стрелке, отрицательный – против часовой стрелки.

Примечание: rotate(angle cx) недействителен. Если вы задаете центр поворота, укажите обе координаты: cx и cy.

Как и перемещение, поворот не искажает элемент. Он сохраняет расстояния, углы и параллельные линии.

1<svg width="450" height="450" xmlns="http://www.w3.org/2000/svg">
2    <rect x="100" y="250" width="200" height="30" fill="CadetBlue" />
3    <rect x="100" y="250" width="200" height="30" fill="#DDA0DD" transform ="rotate(-45 200 265)" />
4    <rect x="100" y="250" width="200" height="30" fill="Pink" transform ="rotate(-90 200 265)" />
5    <rect x="100" y="250" width="200" height="30" fill="#B0C4DE" transform ="rotate(45 200 265)" />
6    <rect x="100" y="250" width="200" height="30" fill="CadetBlue" transform ="rotate(-35)" />
7</svg>

Функция transform="rotate(-90 200 265)" поворачивает розовый прямоугольник на 90 градусов против часовой стрелки вокруг точки (200, 265). Последний прямоугольник использует rotate(-35) без центра поворота, поэтому SVG поворачивает его вокруг (0, 0). Результат показан ниже:

Пять заполненных прямоугольников, показывающих поворот SVG вокруг точки и вокруг начала координат

Файл rotation.svg содержит пример SVG-поворота.

Наклон SVG с skewX() и skewY()

Наклон изменяет одну координатную ось и визуально скашивает элемент. Используйте skewX(angle), чтобы наклонить элемент вдоль оси x, и skewY(angle), чтобы наклонить элемент вдоль оси y. Угол задается в градусах. При skewX(angle) меняются координаты x, а координаты y остаются прежними; при skewY(angle) меняются координаты y, а координаты x остаются прежними.

Ниже показан пример круга со значением skewX(55) ( skew-x.svg):

1<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
2    <circle cx="20" cy="20" r="15" stroke="blue" fill="none" />
3    <circle cx="20" cy="20" r="15" stroke="grey" stroke-opacity="0.7" fill="none" transform="skewX(55)" />
4</svg>

Простой пример прямоугольника, наклоненного функцией skewY(35) ( skew-y.svg):

1<svg  width="800" height="800" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
2   <rect x="20" y="20" width="30" height="30" stroke="blue" stroke-opacity="1" fill="none" />
3   <rect x="20" y="20" width="30" height="30" stroke="grey" stroke-opacity="0.5" fill="none" transform="skewY(35)" />
4 </svg>

Отрисованные примеры выглядят так:

Круг и прямоугольник до и после применения функций skewX и skewY

Типичные ошибки и исправления

ПроблемаПричинаРешение
Прямоугольник не перемещается после translateАтрибут transform написан с ошибкой или без кавычекУбедитесь, что на элементе корректно задано transform="translate(150,50)"
Перемещение не применяетсяАтрибут transform задан на родительском элементе вместо целевогоЗадайте transform прямо на элементе, который нужно переместить, например на <rect>
Поворот идет не в ту сторонуЗнак угла интерпретирован не так, как ожидалосьИспользуйте положительные значения для поворота по часовой стрелке и отрицательные – против часовой стрелки
Поворот происходит вокруг неправильной точкиcx/cy пропущены или заданы как origin элементаУкажите явные координаты центра поворота или примените предварительное перемещение для сдвига pivot
Наклон выглядит слишком сильнымУгол задан в радианах вместо градусовУказывайте углы в градусах, например skewX(30)
Элемент исчезает после масштабированияКоэффициент масштабирования случайно равен 0 или отрицательныйИспользуйте положительные ненулевые значения scale и проверьте порядок transform-функций, если они объединены
Комбинированные transform дают неверный результатПорядок функций обратный нужномуПомните, что transform применяются справа налево; запись translate(...) rotate(...) сначала поворачивает, затем перемещает

Быстрые рецепты

ЭффектSVG-код для копирования
Переместить вправо на 50 px и вниз на 30 px<rect x="10" y="10" width="40" height="20" transform="translate(50,30)" />
Увеличить в 2 раза равномерно<circle cx="20" cy="20" r="10" transform="scale(2)" />
Растянуть по горизонтали в 3 раза<rect x="0" y="0" width="20" height="20" transform="scale(3,1)" />
Повернуть на 45 градусов вокруг центра (100,100)<polygon points="90,90 110,90 100,110" transform="rotate(45 100 100)" />
Повернуть на 90 градусов по часовой стрелке вокруг начала координат<line x1="0" y1="0" x2="50" y2="0" stroke="black" transform="rotate(90)" />
Наклонить по X на 30 градусов<rect x="10" y="10" width="30" height="30" transform="skewX(30)" />
Наклонить по Y на -20 градусов<circle cx="25" cy="25" r="15" transform="skewY(-20)" />
Цепочка: перемещение и поворот<g transform="translate(100,50) rotate(30)"><rect width="40" height="10" fill="red"/></g>

FAQ – SVG-трансформации

Что делает атрибут transform в SVG?

Атрибут transform применяет геометрическое преобразование к SVG-элементу или группе. Он меняет отображение элемента, но не переписывает атрибуты вроде x, y, cx, cy или path data.

Чем отличаются translate и scale?

translate(tx, ty) перемещает элемент, не меняя его размер. scale(sx, sy) меняет размер элемента и может также сдвинуть видимое положение, потому что масштабирование выполняется относительно начала системы координат.

Как повернуть SVG вокруг центральной точки?

Используйте rotate(angle cx cy) и укажите обе координаты центра. Например, transform="rotate(45 100 100)" поворачивает элемент на 45 градусов вокруг точки (100, 100).

Когда использовать matrix вместо отдельных transform-функций?

Используйте отдельные функции translate(), scale() и rotate(), когда важна читаемость. Используйте matrix(a,b,c,d,e,f), когда нужен один объединенный transform или значения, рассчитанные другим инструментом или API.

Спецификация и связанные ресурсы