Морфинг между SVG-формами

GSAP (GreenSock Animation Platform) предоставляет мощные инструменты для анимации, включая возможность морфинга между различными SVG-формами. Морфинг представляет собой плавное преобразование одной формы в другую с сохранением визуальной целостности и динамики.

Для работы с морфингом необходимо, чтобы обе SVG-формы имели одинаковое количество контрольных точек (path-элементы с одинаковым числом команд M, L, C, Q и т.д.). Несоответствие количества точек может привести к некорректной анимации или визуальным артефактам.

import { gsap } from "gsap";
import { MorphSVGPlugin } from "gsap/MorphSVGPlugin";

gsap.registerPlugin(MorphSVGPlugin);

gsap.to("#shape1", {
  duration: 2,
  morphSVG: "#shape2",
  ease: "power2.inOut"
});

В примере выше #shape1 плавно преобразуется в форму #shape2 за 2 секунды с использованием кривой ускорения power2.inOut, что создаёт естественное движение.


Подготовка SVG для морфинга

Ключевые правила:

  1. Совпадение количества узлов Каждая форма должна содержать одинаковое количество точек. Если формы различаются по числу точек, GSAP не сможет корректно вычислить промежуточные состояния.

  2. Использование инструментов для выравнивания точек Векторные редакторы, такие как Adobe Illustrator или Inkscape, позволяют выравнивать точки между различными объектами. Также существует инструмент GSAP MorphSVGPlugin с функцией convertToPath(), которая помогает стандартизировать формы.

  3. Оптимизация форм Удаление лишних точек и упрощение кривых снижает нагрузку на браузер и делает анимацию более плавной.


Основные методы и свойства

morphSVG — главный параметр для морфинга. Он принимает:

  • ID другого SVG (#shape2)
  • Прямой объект SVG (document.querySelector("#shape2"))
  • Путь в формате строки ("M0,0 L50,50 ...")

Дополнительные свойства:

  • duration — длительность анимации в секундах
  • ease — функция сглаживания движения
  • repeat — количество повторов
  • yoyo — обратное воспроизведение анимации после завершения

Пример с циклической анимацией:

gsap.to("#shape1", {
  duration: 2,
  morphSVG: "#shape2",
  repeat: -1,
  yoyo: true,
  ease: "power1.inOut"
});

Морфинг нескольких форм

GSAP позволяет анимировать одну форму через несколько состояний:

gsap.to("#shape1", {
  duration: 3,
  morphSVG: [
    "#shape2",
    "#shape3",
    "#shape4"
  ],
  repeat: -1,
  yoyo: true,
  ease: "power2.inOut"
});

Последовательная анимация через массив форм создаёт эффект непрерывного преобразования, полезный для динамических графических интерфейсов.


Морфинг с кривыми и сложными контурами

Для сложных форм, содержащих кривые Безье (C), важно:

  1. Сохранять правильное направление кривых. Если кривые не совпадают по направлению, результат может быть зеркальным или изломанным.
  2. Использовать MorphSVGPlugin.convertToPath() для конвертации всех фигур в единственный стандартный путь.
MorphSVGPlugin.convertToPath("#complexShape");

Это превращает любые SVG-объекты (круги, эллипсы, линии) в совместимые пути, что делает морфинг надёжным даже для сложных контуров.


Анимация атрибутов вместе с морфингом

Помимо формы, можно одновременно анимировать другие свойства SVG:

gsap.to("#shape1", {
  duration: 2,
  morphSVG: "#shape2",
  fill: "#ff0000",
  strokeWidth: 5,
  ease: "power2.inOut"
});

Это позволяет создавать комплексные эффекты, где форма, цвет и толщина линий изменяются синхронно.


Производительность и оптимизация

  • Ограничение количества контрольных точек уменьшает нагрузку на браузер.
  • Для анимации на больших экранах или при множестве форм лучше использовать requestAnimationFrame через GSAP (это делается автоматически).
  • Использование transform-origin и scale вместо изменения координат точек для простых объектов снижает вычислительную нагрузку.
gsap.to("#shape1", {
  duration: 1,
  scale: 1.2,
  transformOrigin: "50% 50%"
});

Работа с реактивными интерфейсами

GSAP интегрируется с React, Vue и другими фреймворками. Морфинг SVG в реактивном компоненте:

useEffect(() => {
  gsap.to("#shapeRef", {
    duration: 2,
    morphSVG: "#targetShape",
    ease: "power2.inOut"
  });
}, []);

Использование useEffect гарантирует корректное выполнение анимации после рендера компонента.