Transforms & Coordinate Systems
(Трансформации и системы координат)
В SVG всё находится в системе координат. По умолчанию точка (0,0) — это верхний левый угол. Ось X идет вправо, ось Y — вниз.
Но самое интересное начинается, когда мы хотим изменить положение, размер или наклон объектов, не меняя их исходные координаты (x, y, cx, cy), а изменяя само пространство вокруг них. Для этого используется атрибут transform.
1. Атрибут transform
Этот атрибут работает похоже на CSS свойство transform, но применяется прямо к SVG-тегам. Внутри атрибута можно перечислить одну или несколько функций подряд.
translate(tx, ty) — Перемещение
Сдвигает систему координат объекта.
tx— сдвиг по оси X.ty— сдвиг по оси Y (необязательно, если не указан, считается 0).
<svg width="200" height="100" viewBox="0 0 200 100">
<!-- Исходный квадрат (полупрозрачный) -->
<rect x="0" y="0" width="40" height="40" fill="crimson"/>
</svg>
<svg width="200" height="100" viewBox="0 0 200 100">
<!-- Сдвинутый квадрат -->
<rect x="0" y="0" width="40" height="40" fill="crimson"
transform="translate(50, 20)" />
</svg>
rotate(angle) — Вращение
Поворачивает объект на заданное количество градусов по часовой стрелке.
angle— угол в градусах (45, -90 и т.д.).
scale(sx, sy) — Масштабирование
Увеличивает или уменьшает объект.
sx— множитель по X.sy— множитель по Y (если не указан, равенsx).
Важный нюанс: scale масштабирует всё, включая координаты и толщину обводки. Если вы увеличите круг в 2 раза (scale(2)), его обводка stroke-width="1" визуально превратится в 2.
skewX(angle) и skewY(angle) — Наклон
Искажает объект по осям.
2. Проблема transform-origin (Точка вращения)
Это самая частая боль новичков в SVG.
- В CSS (HTML): Если вы крутите
<div>, он крутится вокруг своего центра. - В SVG (по умолчанию): Объекты крутятся вокруг точки
(0,0)всего холста (верхнего левого угла SVG).
Если ваш квадрат стоит в координатах x="100", и вы напишете rotate(45), он не просто повернется, он "улетит" по дуге вокруг начала координат.
Как это исправить?
Способ 1: Старый SVG-стиль (в атрибуте)
Функция rotate в SVG принимает необязательные 2-й и 3-й параметры: координаты центра вращения rotate(angle, cx, cy).
<!-- Вращаем квадрат 50x50 вокруг его центра (25, 25) -->
<rect x="0" y="0" width="50" height="50" transform="rotate(45, 25, 25)" />
Способ 2: Современный CSS (Рекомендуемый)
Если вы стилизуете SVG через CSS, используйте свойство transform-box. Оно говорит браузеру: "считай центром сам объект, а не весь SVG".
.my-element {
/* Указываем, что origin рассчитывается относительно границ самого объекта */
transform-box: fill-box;
/* Теперь центр работает как ожидается */
transform-origin: center;
transform: rotate(45deg);
}
3. Вложенные системы координат
Когда вы применяете трансформацию к группе <g>, происходит магия. Вы трансформируете не объекты внутри, а саму координатную сетку для этой группы.
Представьте лист миллиметровки:
- Вы рисуете на нем квадрат.
- Вы поворачиваете сам лист бумаги на 45 градусов.
- Теперь, если вы попросите нарисовать еще один квадрат и сдвинуть его "вправо" (
translate(10, 0)), он визуально поедет по диагонали, потому что ось X на этом листе теперь смотрит по диагонали.
<svg width="300" height="200" viewBox="0 0 300 200">
<!-- Группа сдвинута и повернута -->
<g transform="translate(100, 50) rotate(45)">
<!-- Квадрат рисуется в точке 0,0 ВНУТРИ группы.
Но визуально он будет в центре холста и повернут. -->
<rect x="0" y="0" width="50" height="50" fill="purple" />
<!-- Текст тоже подчиняется правилам группы -->
<text x="0" y="70">Я тоже повернут!</text>
</g>
</svg>
Порядок имеет значение!
transform="translate(50, 0) rotate(45)"— Сначала сдвинуть вправо, потом повернуть там.transform="rotate(45) translate(50, 0)"— Сначала повернуть систему координат, потом сдвинуть по уже повернутой оси X (то есть по диагонали).
Итог
translateдвигает,rotateвращает,scaleменяет размер (вместе с толщиной линий!).- По умолчанию вращение происходит вокруг
(0,0)(левый верхний угол SVG), а не вокруг центра фигуры. - Чтобы вращать вокруг центра, используйте CSS:
transform-box: fill-box; transform-origin: center;или аргументы в атрибутеrotate(deg, cx, cy). - Трансформации групп
<g>влияют на всех детей, создавая вложенные ("локальные") системы координат.