Морфинг сложных форм

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

Ключевая идея: ScrollMagic управляет таймингом анимации, а сама трансформация формы выполняется сторонним инструментом.


Подготовка SVG-графики

Для морфинга используются SVG-элементы <path>. Успешность анимации напрямую зависит от структуры путей.

Требования к формам:

  • Оба контура должны быть представлены как <path>
  • Желательно одинаковое количество сегментов (или автоматическая нормализация через MorphSVG)
  • Схожее направление обхода (clockwise / counterclockwise)
  • Отсутствие трансформаций (transform) — все координаты должны быть абсолютными

Пример SVG:

<svg viewBox="0 0 200 200">
  <path id="shape1" d="M50,50 L150,50 L150,150 L50,150 Z" />
  <path id="shape2" d="M100,20 C140,20 180,60 100,180 C20,60 60,20 100,20 Z" style="visibility:hidden;" />
</svg>

Подключение зависимостей

<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/MorphSVGPlugin.min.js"></script>

Регистрация плагина:

gsap.registerPlugin(MorphSVGPlugin);

Создание контроллера ScrollMagic

const controller = new ScrollMagic.Controller();

Контроллер отслеживает прокрутку и управляет сценами.


Базовый морфинг при прокрутке

const tween = gsap.to("#shape1", {
  duration: 1,
  morphSVG: "#shape2",
  ease: "power1.inOut"
});

new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 300,
  triggerHook: 0.5
})
.setTween(tween)
.addTo(controller);

Ключевые параметры:

  • triggerElement — элемент, при достижении которого запускается сцена
  • duration — длина анимации относительно прокрутки
  • triggerHook — точка экрана (0–1), где срабатывает триггер

Синхронизация морфинга с прокруткой

При указании duration анимация становится “scrub”-анимацией — её прогресс зависит от положения скролла.

new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 500
})
.setTween(tween)
.addTo(controller);

В этом случае:

  • начало морфинга = начало сцены
  • завершение = конец сцены

Морфинг нескольких состояний

Сложные интерфейсы требуют цепочки трансформаций.

const timeline = gsap.timeline();

timeline
  .to("#shape1", { morphSVG: "#shape2", duration: 1 })
  .to("#shape1", { morphSVG: "#shape3", duration: 1 })
  .to("#shape1", { morphSVG: "#shape4", duration: 1 });

new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 800
})
.setTween(timeline)
.addTo(controller);

Особенности:

  • одна фигура проходит несколько состояний
  • timeline распределяется по всей длине сцены

Управление точками морфинга

MorphSVG позволяет контролировать соответствие точек.

gsap.to("#shape1", {
  morphSVG: {
    shape: "#shape2",
    shapeIndex: 0
  }
});

shapeIndex:

  • определяет способ сопоставления сегментов
  • помогает избежать “перекручивания” формы

Нормализация форм

Если формы сильно отличаются, применяется автоматическая нормализация:

gsap.to("#shape1", {
  morphSVG: {
    shape: "#shape2",
    type: "rotational"
  }
});

Типы:

  • rotational — учитывает вращение
  • linear — линейное сопоставление

Морфинг с дополнительными эффектами

Комбинирование с другими свойствами:

const tween = gsap.to("#shape1", {
  morphSVG: "#shape2",
  fill: "#ff0000",
  scale: 1.2,
  rotation: 45,
  duration: 1
});

ScrollMagic синхронизирует все изменения одновременно.


Закрепление (pin) во время морфинга

Часто используется фиксация элемента:

new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 600
})
.setPin("#svg-container")
.setTween(tween)
.addTo(controller);

Результат:

  • SVG остается на месте
  • морфинг происходит при прокрутке

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

Основные рекомендации:

  • минимизировать количество точек в SVG
  • избегать сложных фильтров (blur, shadow)
  • использовать will-change для ускорения
#shape1 {
  will-change: transform;
}

Оптимизация путей:

  • упрощение через SVG-редакторы (Illustrator, SVGOMG)
  • удаление лишних anchor points

Работа с responsive-дизайном

SVG автоматически масштабируется через viewBox, но важно:

  • избегать абсолютных размеров
  • учитывать соотношение сторон
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">

Дебаг сцен

Подключение индикаторов:

new ScrollMagic.Scene({
  triggerElement: "#trigger",
  duration: 300
})
.addIndicators()
.setTween(tween)
.addTo(controller);

Требуется дополнительный плагин:

<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/debug.addIndicators.min.js"></script>

Морфинг сложных композитных фигур

Если форма состоит из нескольких частей:

<g id="complexShape">
  <path id="part1" ... />
  <path id="part2" ... />
</g>

Анимация:

const tl = gsap.timeline();

tl.to("#part1", { morphSVG: "#target1" })
  .to("#part2", { morphSVG: "#target2" }, "<");

Особенности:

  • синхронный морфинг нескольких элементов
  • использование позиционных параметров timeline ("<")

Асинхронная подгрузка SVG

При динамической загрузке SVG необходимо:

  • дождаться вставки в DOM
  • затем инициализировать сцену
fetch("shapes.svg")
  .then(res => res.text())
  .then(svg => {
    document.querySelector("#container").innerHTML = svg;
    initScrollMagic();
  });

Управление прогрессом вручную

ScrollMagic позволяет контролировать прогресс сцены:

scene.progress(0.5);

Это полезно при:

  • синхронизации с другими событиями
  • создании кастомных интерфейсов

Интеграция с пользовательским скроллом

При использовании кастомных скролл-библиотек (например, smooth-scroll):

controller.scrollPos(function () {
  return customScrollInstance.scrollTop;
});

Ошибки и их устранение

Дергание формы:

  • несоответствие количества точек
  • неправильный shapeIndex

Инверсия анимации:

  • разные направления path
  • исправляется через reverse path в редакторе

Анимация не запускается:

  • неправильный triggerElement
  • отсутствует duration

Архитектура сложных морфинг-сцен

Для крупных проектов используется:

  • модульная структура сцен
  • отдельные timeline для каждой логики
  • единый controller
function createMorphScene(trigger, duration, tween) {
  return new ScrollMagic.Scene({
    triggerElement: trigger,
    duration: duration
  })
  .setTween(tween)
  .addTo(controller);
}

Комбинирование морфинга с параллаксом

const tl = gsap.timeline();

tl.to("#shape1", { morphSVG: "#shape2" })
  .to("#background", { y: "-50%" }, 0);

ScrollMagic связывает обе анимации с прокруткой, создавая сложный визуальный эффект.


Управление easing в морфинге

gsap.to("#shape1", {
  morphSVG: "#shape2",
  ease: "elastic.out(1, 0.3)"
});

Easing влияет на восприятие трансформации:

  • linear — равномерно
  • power — плавно
  • elastic — пружинящий эффект

Сценарии применения

  • интерактивные лендинги
  • визуализация данных
  • storytelling при прокрутке
  • анимация логотипов
  • переходы между состояниями UI

Расширенные техники

Морфинг текста в форму

  1. Конвертация текста в path
  2. Анимация как обычного SVG

Морфинг по маске

Использование <clipPath> или <mask> для сложных переходов

Морфинг с задержками

tl.to("#shape1", { morphSVG: "#shape2", duration: 1 })
  .to("#shape1", { morphSVG: "#shape3", duration: 1, delay: 0.2 });

Взаимодействие с событиями ScrollMagic

scene.on("enter", () => {
  console.log("Начало морфинга");
});

scene.on("progress", (event) => {
  console.log(event.progress);
});

Позволяет отслеживать состояние анимации и синхронизировать другие элементы интерфейса.