Морфинг сложных форм — это анимация плавного преобразования одного SVG-контура в другой при прокрутке страницы. В контексте ScrollMagic морфинг не реализуется напрямую, а строится через интеграцию с анимационными библиотеками, такими как GSAP (GreenSock), где используется плагин MorphSVG.
Ключевая идея: ScrollMagic управляет таймингом анимации, а сама трансформация формы выполняется сторонним инструментом.
Для морфинга используются SVG-элементы <path>.
Успешность анимации напрямую зависит от структуры путей.
<path>transform) — все координаты
должны быть абсолютными<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);
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);
При указании 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);
MorphSVG позволяет контролировать соответствие точек.
gsap.to("#shape1", {
morphSVG: {
shape: "#shape2",
shapeIndex: 0
}
});
Если формы сильно отличаются, применяется автоматическая нормализация:
gsap.to("#shape1", {
morphSVG: {
shape: "#shape2",
type: "rotational"
}
});
Комбинирование с другими свойствами:
const tween = gsap.to("#shape1", {
morphSVG: "#shape2",
fill: "#ff0000",
scale: 1.2,
rotation: 45,
duration: 1
});
ScrollMagic синхронизирует все изменения одновременно.
Часто используется фиксация элемента:
new ScrollMagic.Scene({
triggerElement: "#trigger",
duration: 600
})
.setPin("#svg-container")
.setTween(tween)
.addTo(controller);
will-change для ускорения#shape1 {
will-change: transform;
}
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" }, "<");
"<")При динамической загрузке SVG необходимо:
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;
});
Для крупных проектов используется:
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 связывает обе анимации с прокруткой, создавая сложный визуальный эффект.
gsap.to("#shape1", {
morphSVG: "#shape2",
ease: "elastic.out(1, 0.3)"
});
Easing влияет на восприятие трансформации:
Использование <clipPath> или
<mask> для сложных переходов
tl.to("#shape1", { morphSVG: "#shape2", duration: 1 })
.to("#shape1", { morphSVG: "#shape3", duration: 1, delay: 0.2 });
scene.on("enter", () => {
console.log("Начало морфинга");
});
scene.on("progress", (event) => {
console.log(event.progress);
});
Позволяет отслеживать состояние анимации и синхронизировать другие элементы интерфейса.