Создание анимации Boids с учётом глубины в React

Стая с изюминкой (и параллакс-эффектом!)

Создание анимации Boids с учётом глубины в React: Стая с изюминкой (и параллакс!)

Добро пожаловать, цифровые орнитологи и любознательные разработчики React! 🪶 Сегодня мы увлекательно и подробно разберёмся, как я создал анимацию Boids с учётом глубины и параллакс-скоростью с помощью React и Framer Motion. Это не просто типичная "суп-из-боидов" на <canvas> — эта стая живёт, реагирует на касания и отлично впишется в ваш следующий современный React-проект.

Этот пост для разработчиков, которые обожают анимации, жаждут интерактивности или просто хотят, чтобы их лендинг тихонько говорил: «Да, я умею кодить.»


Что такое Boids?

Boids — это маленькие симулированные существа, придуманные Крейгом Рейнольдсом в 1986 году, чтобы имитировать движение птиц, рыб и прочих стайных животных. Магия кроется в трёх правилах:

  1. Разделение: Не толпись рядом с соседом.
  2. Выравнивание: Лети в том же направлении, что и твои друзья.
  3. Сцепление: Оставайся рядом с группой.

Результат? Эмерджентное реалистичное поведение стаи, любимое творческими программистами по всему миру.

Изображение boids
Изображение boids

Почему React для Boids?

Традиционно симуляции boids запускаются в <canvas> или WebGL. Но с сегодняшними мощными UI и такими инструментами, как Framer Motion, мы можем эффективно анимировать DOM-узлы — получая лёгкую интеграцию с React, интерактивность и даже эффекты, завязанные на прокрутку.

SEO-совет: Такой подход отлично подходит для сайтов и приложений, где важны SEO и доступность — ваши крутые визуализации больше не будут спрятаны в недоступном <canvas>!


Структура компонента

Вся логика формирования стаи заключена в одном React-компоненте <FlockingAnimation />. Код модульный и настраиваемый через пропсы, поддерживает:

  • Размер стаи (автоматический или фиксированный)
  • Максимальную скорость и силу
  • Вес правил
  • Кастомные классы для удобного стилизования

Props:

export type Props = {
  className?: string;
  initialCount?: number;
  maxSpeed?: number;
  maxForce?: number;
  weights?: Partial<Weights>;
};

Поведение Boid: алгоритм

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

Основная логика имитирует реальное движение стаи:

flock(boids, weights, maxSpeed, maxForce) {
  // 1. Вычислить векторы разделения, выравнивания, сцепления
  // 2. Взвесить и сложить их
  // 3. Применить к ускорению
  // 4. Ограничить ускорение по maxForce
}

Каждое правило анализирует соседей в определённом радиусе и вычисляет вектор управления:

  • Разделение: Отталкивается от слишком близких боидов.
  • Выравнивание: Усредняет скорости для совпадения направления.
  • Сцепление: Направляет к средней позиции.

Глубина и параллакс: добавляем эффект вау

При создании каждому боиду назначается случайная глубина от 0 до 1. Глубина влияет на три параметра:

  1. Параллакс-скорость: Боиды дальше движутся медленнее, ближе — быстрее.
  2. Масштаб: Боиды на переднем плане крупнее.
  3. Непрозрачность: Глубокие боиды полупрозрачны, ближние — насыщенные.

Это реализуется в цикле обновления:

const speedFactor = 1 + (1 - this.depth) * PARALLAX_FACTOR;
const dtScalar = dtBase * speedFactor;

При рендеринге масштаб и непрозрачность боидов отображаются в зависимости от глубины, создавая настоящий 3D-эффект. Это та же иммерсия, что и в VR, но без головной боли.


Делаем анимацию отзывчивой (и весёлой!)

  • Появление/исчезание при прокрутке: Используя useScroll() и useTransform(), анимация плавно исчезает при прокрутке, не задерживая пользователя.
  • Взаимодействие с курсором: Перетаскивайте мышкой или пальцем — и у курсора появится новый боид. Ведь кто не хочет почувствовать себя Властелином Стаи?
  • Случайное распределение: При монтировании боиды появляются группами в случайных точках, расползаясь естественным образом.

Пример создания боидов:

for (let j = 0; j < groupSize; j++) {
  const ang = Math.random() * Math.PI * 2;
  const rad = Math.random() * SPAWN_RADIUS;
  boidsRef.current.push(
    new Boid(center.x + Math.cos(ang) * rad, center.y + Math.sin(ang) * rad)
  );
}

Оптимизации и советы для разработчиков

  • Рендер с учётом видимости: Intersection Observer останавливает обновления, когда компонент не виден — экономия ресурсов и заряда батареи для мобильных и лэптопов.
  • Эффективное управление состоянием: React-состояние обновляется только при необходимости, уменьшая количество рендеров.
  • Motion Values: Функции motionValue и анимированные <motion.div> из Framer Motion обеспечивают плавные трансформации DOM.

Полный исходный код

Ссылка на полный, готовый к использованию код ниже! (Только подключите Framer Motion и Tailwind CSS.)

GitHub.


Заключение

Создавать стаи boids в React может показаться странным выбором, но с современными библиотеками анимации вы получаете интерактивность, производительность и ценнейший опыт разработчика — всё сразу.

Categories