Логотип Workflow

Article

Transforms Coordinate Systems

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>, происходит магия. Вы трансформируете не объекты внутри, а саму координатную сетку для этой группы.

Представьте лист миллиметровки:

  1. Вы рисуете на нем квадрат.
  2. Вы поворачиваете сам лист бумаги на 45 градусов.
  3. Теперь, если вы попросите нарисовать еще один квадрат и сдвинуть его "вправо" (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> влияют на всех детей, создавая вложенные ("локальные") системы координат.

Quiz

Проверьте, что вы усвоили

Авторизуйтесь чтоб пройти тесты