ScrollMagic сам по себе не создаёт графические эффекты — он управляет состояниями и временем выполнения анимаций в зависимости от прокрутки. Визуальная составляющая реализуется через интеграцию с CSS, Canvas, WebGL или сторонними библиотеками, такими как GSAP.
Ключевая идея: позиция скролла → триггер → изменение свойств DOM или графического контекста.
Шейдеры и сложные эффекты чаще всего реализуются через:
ScrollMagic используется как механизм синхронизации.
При использовании WebGL (через Three.js) ScrollMagic управляет параметрами сцены: камерой, объектами, uniform-переменными шейдеров.
const controller = new ScrollMagic.Controller();
const scene = new ScrollMagic.Scene({
triggerElement: "#trigger",
duration: 500
})
.on("progress", function (event) {
const progress = event.progress;
material.uniforms.uProgress.value = progress;
})
.addTo(controller);
Здесь значение progress (от 0 до 1) передаётся в шейдер
как uniform.
Шейдер — это программа, выполняемая на GPU. В WebGL используются два типа:
uniform float uProgress;
void main() {
vec3 color = vec3(uProgress, 0.0, 1.0 - uProgress);
gl_FragColor = vec4(color, 1.0);
}
ScrollMagic изменяет uProgress, создавая плавный переход
цвета при прокрутке.
Uniform-переменные — основной способ передачи данных в шейдер.
scene.on("progress", (e) => {
shaderMaterial.uniforms.time.value = e.progress * 10.0;
});
Используемые параметры:
progress — нормализованное значение (0–1)scrollPos — абсолютная позиция скроллаvelocity — скорость прокрутки (рассчитывается
вручную)Один из самых популярных эффектов — деформация изображения при прокрутке.
uniform sampler2D uTexture;
uniform float uProgress;
varying vec2 vUv;
void main() {
vec2 uv = vUv;
uv.y += sin(uv.x * 10.0 + uProgress * 5.0) * 0.05;
gl_FragColor = texture2D(uTexture, uv);
}
ScrollMagic изменяет uProgress, создавая анимацию
волны.
Классический параллакс можно значительно улучшить через шейдеры.
vec2 uv = vUv;
vec4 layer1 = texture2D(tex1, uv + uProgress * 0.1);
vec4 layer2 = texture2D(tex2, uv + uProgress * 0.2);
gl_FragColor = mix(layer1, layer2, 0.5);
ScrollMagic управляет uProgress, создавая глубину.
ScrollMagic идеально подходит для контроля переходов (image transitions).
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
void main() {
vec4 color1 = texture2D(from, vUv);
vec4 color2 = texture2D(to, vUv);
gl_FragColor = mix(color1, color2, progress);
}
scene.on("progress", (e) => {
material.uniforms.progress.value = e.progress;
});
Шум используется для создания органичных переходов и искажений.
float noise = sin(vUv.x * 10.0 + uProgress * 10.0);
vec2 uv = vUv + noise * 0.02;
Эффекты:
Популярный визуальный эффект — цифровое искажение.
float glitch = step(0.9, sin(uProgress * 50.0));
vec2 uv = vUv;
uv.x += glitch * 0.05;
gl_FragColor = texture2D(uTexture, uv);
ScrollMagic задаёт момент появления “сбоев”.
Если WebGL избыточен, можно использовать Canvas.
scene.on("progress", (e) => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const offset = e.progress * 100;
ctx.drawImage(image, offset, 0);
});
Возможности:
Простейшие эффекты достигаются без WebGL.
scene.on("progress", (e) => {
const blur = e.progress * 10;
element.style.filter = `blur(${blur}px)`;
});
Другие фильтры:
SVG позволяет создавать сложные эффекты без WebGL.
<filter id="distort">
<feTurbulence baseFrequency="0.01" numOctaves="2" result="turb"/>
<feDisplacementMap in="SourceGraphic" in2="turb" scale="20"/>
</filter>
ScrollMagic меняет параметр scale:
scene.on("progress", (e) => {
displacement.setAttribute("scale", e.progress * 50);
});
ScrollMagic часто используется с GSAP Timeline.
const tween = gsap.to(obj, {
value: 1,
onUpdate: () => {
material.uniforms.progress.value = obj.value;
}
});
new ScrollMagic.Scene({
duration: 500
})
.setTween(tween)
.addTo(controller);
Преимущества:
Работа с шейдерами и ScrollMagic требует внимания к производительности.
Минимизация обновлений
GPU-нагрузка
ScrollMagic
Несколько шейдеров могут быть синхронизированы одной сценой.
scene.on("progress", (e) => {
shader1.uniforms.uProgress.value = e.progress;
shader2.uniforms.uProgress.value = e.progress;
});
Позволяет создавать:
let lastScroll = 0;
scene.on("update", (e) => {
const velocity = e.scrollPos - lastScroll;
lastScroll = e.scrollPos;
material.uniforms.velocity.value = velocity;
});
Применение:
ScrollMagic управляет всеми параметрами одновременно, создавая сложные визуальные сцены.
Комбинация времени и прокрутки:
scene.on("progress", (e) => {
material.uniforms.time.value = performance.now() * 0.001;
material.uniforms.scroll.value = e.progress;
});
Даёт:
Типичная структура:
/js
scroll.js
shaders.js
scene.js
/shaders
vertex.glsl
fragment.glsl
Рекомендации:
Рывки анимации
Падение FPS
Несинхронность