Реклама
Селектел, перетяжка, 22.06
Селектел, перетяжка, 22.06
Селектел, перетяжка, 22.06

Как сделать 3D-вращение изображений при скролле: разбираем эффект от Codrops

Свежий туториал Codrops показывает, как превратить обычную галерею в кинематографичную ленту, где фотографии вращаются в 3D-пространстве по мере скролла. Разбираем математику, пять вариаций и код, который можно взять в свой проект.

Обложка: Как сделать 3D-вращение изображений при скролле: разбираем эффект от Codrops

Хотите, чтобы лендинг или портфолио запомнили с первого взгляда? Попробуйте добавить изображениям объёмное вращение при скролле. Эффект выглядит дорого и кинематографично, но под капотом — обычные CSS 3D-трансформации и немного JavaScript.

В начале июня команда Codrops опубликовала небольшую, но наглядную демонстрацию: галерея фотографий проезжает через вьюпорт, пока каждая картинка медленно кувыркается в трёхмерном пространстве. Идея позаимствована у аниматора Jason Booth, а код выложен на GitHub вместе с пятью готовыми вариациями.

В этой статье разберёмся, как устроен эффект, из чего состоит математика и как быстро повторить его у себя — без WebGL, Canvas и тяжёлых библиотек.

Ключевые выводы
Ключевые выводы

Эффект строится на CSS-свойствах perspective и transform-style: preserve-3d, а анимация крутит rotationX/Y/Z и translateZ по прогрессу скролла.

Для синхронизации с прокруткой используется GSAP ScrollTrigger с параметром scrub: true; плавность даёт библиотека Lenis.

Codrops предлагает пять вариаций: от мягкого волнообразного движения до агрессивного разворота с blur и изменением яркости.

Всего нужно три ингредиента: разметка с фоновыми изображениями, CSS для 3D-контекста и 30—40 строк JS, которые связывают скролл с трансформациями.

Как устроен базовый эффект

В основе лежит простая мысль: каждая картинка — это не плоский прямоугольник, а объект в 3D-пространстве. Пока пользователь скроллит страницу, объект проходит перед «камерой» и меняет ориентацию. Входная точка анимации начинается, когда элемент появляется снизу экрана, а заканчивается, когда уходит вверх.

Для реализации используется связка GSAP + ScrollTrigger. Параметр scrub: true привязывает анимацию напрямую к позиции скролла: чем дальше прокручено, тем сильнее трансформация. Библиотека Lenis отвечает за плавность: без неё колёсико мыши на Windows или трекпад на macOS могут давать рваное движение, и вся магия растворится.

Разметка и CSS

HTML минимален: контейнер .gallery и набор .gallery__item с фоновыми картинками. Главное — обернуть каждый item дополнительным .gallery__item-wrap и задать ему perspective. Именно обёртка создаёт 3D-контекст, внутри которого вращается сама картинка.

			.gallery__item-wrap {
  width: 100%;
  max-width: var(--item-width);
  perspective: 900px;
  margin-bottom: -5rem;
}

.gallery__item {
  width: 100%;
  aspect-ratio: var(--item-ar);
  background-size: cover;
  background-position: center;
  transform-style: preserve-3d;
  will-change: transform, filter;
}
		

Плавный скролл и триггеры

Перед запуском анимации инициализируем Lenis и связываем её с GSAP. Это стандартный «боеприпас» для большинства современных сайтов с анимацией по скроллу.

			import Lenis from 'lenis';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

gsap.registerPlugin(ScrollTrigger);

const lenis = new Lenis();

lenis.on('scroll', ScrollTrigger.update);

gsap.ticker.add((time) => {
  lenis.raf(time * 1000);
});

gsap.ticker.lagSmoothing(0);
		

Математика вращения

Каждой картинке случайно задаётся начальная ориентация по трём осям. Затем GSAP анимирует от этих значений до противоположных, создавая эффект «переворота» на 180°. В обработчике onUpdate вычисляется смещение по оси Z: чем ближе элемент к центру экрана, тем глубже он «погружается» в пространство.

			items.forEach((item) => {
  const rotationX = gsap.utils.random(70, 120);
  const rotationY = gsap.utils.random(-20, 20);
  const rotationZ = gsap.utils.random(-20, 20);
  const setZ = gsap.quickSetter(item, 'z', 'px');

  gsap.fromTo(
    item,
    { rotationX, rotationY, rotationZ },
    {
      rotationX: -rotationX,
      rotationY: -rotationY,
      rotationZ: -rotationZ,
      ease: 'none',
      scrollTrigger: {
        trigger: item,
        start: 'top bottom+=20%',
        end: 'bottom top-=20%',
        scrub: true,
        invalidateOnRefresh: true,
        onUpdate(self) {
          const progress = self.progress;
          const z = Math.sin(progress * Math.PI) * -50;
          setZ(z);
        },
      },
    }
  );
});
		
Совет: если вы убираете плавный скролл, протестируйте эффект на мобильном устройстве. Нативный скролл на iOS и Android может дать менее плавную картинку, и тогда имеет смысл оставить Lenis или добавить @media (prefers-reduced-motion) для доступности.

Пять вариаций одной идеи

Codrops не ограничивается одной анимацией: в репозитории пять HTML-файлов, каждый из которых демонстрирует, как одно и то же ядро превращается в разное настроение. Вот краткая карта отличий.

  • Вариант 1. Мягкое волнообразное расположение картинок по горизонтали, случайные углы rotationX 70—120° и небольшой зазор по Z (−50 px). Универсальная, спокойная подача.
  • Вариант 2. Больший размах по rotationX (240—290°) и усиленная глубина до −300 px. Картинки буквально переворачиваются перед глазами.
  • Вариант 3. Триггер вычисляет поворот через cos(progress * π), добавляет сдвиг по Y (yPercent) и фильтры saturate/brightness. Получается «подводное» движение.
  • Вариант 4. Акцент на скорости: в обработчике Lenis отслеживается velocity, и чем быстрее скролл, тем сильнее blur и ниже насыщенность. Динамично и спортивно.
  • Вариант 5. Агрессивное искажение масштаба: scaleX и scaleY меняются в противофазе, картинки растягиваются и сжимаются, проходя через центр экрана.

Мини-руководство: повторяем у себя

Чтобы не копировать всю демку целиком, можно взять только схему и адаптировать под свой проект. Ниже — самый короткий путь от макета до рабочей анимации.

Как добавить 3D-вращение картинок на свой сайт
  1. 01
    Подготовьте разметку

    Создайте контейнер и поместите внутрь блоки с фоновыми изображениями. Каждый блок оберните в div с perspective. Без этой обёртки 3D-поворот будет выглядеть плоским.

    			<div class="gallery">
      <div class="gallery__item-wrap">
        <div class="gallery__item" style="background-image: url(img/1.webp)"></div>
      </div>
      <!-- остальные items -->
    </div>
    		
  2. 02
    Задайте 3D-контекст в CSS

    Для обёртки укажите perspective, для самого item — transform-style: preserve-3d. Это минимальный набор, достаточный для объёмного вращения.

    			.wrap { perspective: 900px; }
    .item { transform-style: preserve-3d; }
    		
  3. 03
    Свяжите скролл с трансформациями

    Подключите GSAP, ScrollTrigger и Lenis. Для каждого item создайте gsap.fromTo с scrollTrigger: { scrub: true } и анимируйте нужные оси. Начните с rotationX, а потом экспериментируйте с Z и фильтрами.

    			gsap.fromTo(item,
      { rotationX: 90 },
      {
        rotationX: -90,
        scrollTrigger: {
          trigger: item,
          start: 'top bottom',
          end: 'bottom top',
          scrub: true,
        },
      }
    );
    		

FAQ

Часто задаваемые вопросы
1
Обязательно ли использовать GSAP?

Нет. Тот же эффект можно сделать и на чистом CSS с animation-timeline: view(), но пока поддержка во всех браузерах неполная. GSAP + ScrollTrigger даёт кроссбраузерность и точный контроль над каждым кадром.

2
Почему картинки выглядят плоскими, хотя код подключён?

Скорее всего, пропущено одно из двух: либо нет perspective на родителе, либо у самого элемента отсутствует transform-style: preserve-3d. Без этих свойств браузер рисует transform в плоской проекции.

3
Насколько это тяжело для производительности?

Всё зависит от количества изображений и сложности фильтров. Два простых правила: используйте will-change: transform, filter только на время анимации и не анимируйте box-shadow или width вместе с transform. На современных устройствах 15—20 картинок с rotationX/Y/Z идут плавно.

4
Будет ли работать на мобильных?

Да, но с оговорками. Сенсорный скролл менее плавный, чем колёсико мыши с Lenis, поэтому эффект может казаться менее «жидким». Протестируйте на реальных устройствах и при необходимости уменьшите амплитуду вращения для узких экранов.

Выводы

3D-анимации по скроллу — это способ сделать обычную галерею запоминающейся без тяжёлых WebGL-сцен. Хватает CSS-свойств perspective и transform-style, пары строк GSAP и библиотеки Lenis для плавности.

Главное, что предлагает Codrops, — не готовый плагин, а отправная точка. Пять вариаций показывают, как одну и ту же идею можно растянуть от спокойного волнообразного движения до агрессивного искажения с blur. Возьмите базовую схему, подберите углы и фильтры под свои картинки — и получите эффект, который будет выглядеть так, будто над ним работала целая команда аниматоров.

Пользователь не запоминает интерфейс, который просто красив. Он запоминает тот, который отзывается на его действия.
Дон Норманкогнитивист, Nielsen Norman Group

Источники: оригинальная статья Codrops, демо Rotating On-Scroll Animations и исходный код на GitHub.