Framer Motion для React — руководство по анимации
Кратко
Framer Motion — библиотека для React, упрощающая создание отзывчивых, управляемых состоянием анимаций. В этой статье вы найдёте пошаговый старт, примеры кнопки и модального окна, приёмы для анимации при скролле, рекомендации по доступности, производительности, альтернативы и практический план внедрения.
Важно: статья ориентирована на разработчиков, знакомых с React и npm/Yarn. Перед началом убедитесь, что у вас установлен Node.js и менеджер пакетов (yarn или npm).
Что такое Framer Motion и зачем он нужен
Framer Motion — это декларативная библиотека анимаций для React. Она предоставляет набор «motion»-компонентов и хуков, которые интегрируются с состоянием React и позволяют описывать анимации как свойства компонентов. Ключевые преимущества:
- Простой API: animate, initial, exit, variants, gesture props.
- Интеграция со стейтом React — анимации привязаны к props/state.
- Поддержка сложных сценариев: ключевые кадры, переходы spring/ease, управление видимостью с AnimatePresence.
Краткое определение: Framer Motion — инструмент для создания реактивных анимаций в React-приложениях.
Быстрый старт — клонирование и запуск демо
Откройте терминал и выполните:
git clone git@github.com:makeuseofcode/framer-motion-app.git
cd framer-motion-app
yarn
yarn devОткройте http://localhost:5173 в браузере — вы увидите стартовый экран проекта:

Основные концепции и API
Motion-компоненты
Любой HTML/SVG-элемент может быть заменён на motion-версию:
Обычный div:
Эквивалент Framer Motion:
Motion-компоненты принимают props, связанные с анимацией и жестами: animate, initial, exit, whileHover, whileTap, whileInView и т.д.
Props: initial, animate, exit
- initial — стартовое состояние компонента перед анимацией.
- animate — целевое состояние (или набор состояний) для анимации.
- exit — состояние при выходе компонента (работает с AnimatePresence).
Variants
Variants — это именованные наборы состояний. Они удобны при повторном использовании и синхронизации анимаций между дочерними элементами.
const variants = {
initial: { y: '-200%', opacity: 0 },
visible: { y: '50%', opacity: 1, transition: { type: 'spring', damping: 32, stiffness: 500 } },
exit: { y: '200%', opacity: 0 }
}Жесты и триггеры
- whileHover — анимация при наведении курсора
- whileTap — анимация при клике/тапе
- whileInView — анимация, когда элемент попадает в viewport
- useAnimate, useMotionValue — хуки для сложных сценариев и контроля значений
Пример 1 — простая кнопка с эффектом hover
В App.jsx импортируйте и отрисуйте компонент Button:
Animated Button
Move your mouse over the button to see the effect
В Button.jsx:
import { motion } from 'framer-motion';
export default function Button({ text }) {
return (
{text}
);
}Почему не CSS? Framer Motion удобнее интегрировать с логикой React (state, события), проще описывать переходы и управлять жизненным циклом анимаций.
Пример 2 — модальное окно с AnimatePresence и Backdrop
Backdrop.jsx (обёртка для модалки):
import { motion } from 'framer-motion';
export default function Backdrop({ onClick, children }) {
return (
{children}
);
}Modal.jsx:
import { motion } from 'framer-motion';
import Backdrop from './Backdrop';
const variants = {
initial: { y: '-200%', opacity: 0 },
visible: {
y: '50%',
opacity: 1,
transition: { duration: 0.1, type: 'spring', damping: 32, stiffness: 500 }
},
exit: { y: '200%', opacity: 0 }
};
export default function Modal({ closeModal, text }) {
return (
e.stopPropagation()}
className="modal"
variants={variants}
initial="initial"
animate="visible"
exit="exit"
>
{text}
);
}В App.jsx контролируйте состояние модалки:
import { useState } from 'react';
import Modal from './components/Modal';
import { AnimatePresence } from 'framer-motion';
export default function App() {
const [modalOpen, setModalOpen] = useState(false);
function closeModal() { setModalOpen(false); }
return (
<>
{modalOpen && }
>
);
}AnimatePresence гарантирует, что exit-анимация завершится до удаления компонента из DOM.
Анимация при скролле
Используйте whileInView и viewport:
Scroll Element
В App.jsx можно генерировать несколько элементов:
let scrollElementCount = 14;
{[...Array(scrollElementCount)].map((x, i) => )}viewport={{ once: true }} означает: анимация произойдёт только при первом попадании в окно просмотра.
Доступность и предпочитаемые настройки пользователя
Важно учитывать пользователей, предпочитающих уменьшенную анимацию:
Рекомендации:
- Поддерживайте медиа-запрос prefers-reduced-motion и отключайте ненужные переходы.
- Не полагайтесь только на анимацию для передачи ключевой информации — добавляйте ARIA-атрибуты и текстовую обратную связь.
Производительность и оптимизация
Советы по производительности:
- Минимизируйте количество одновременно анимируемых свойств, особенно layout-affecting (width/height/left/top). Предпочитайте transform и opacity.
- Используйте will-change аккуратно.
- Для длинных списков применяйте ленивую загрузку и анимацию при вхождении в viewport.
- Профилируйте браузер (Performance tab) и следите за частотой кадров.
Важно: фильтры и backdropFilter могут быть тяжёлыми на слабых устройствах.
Тестирование и критерии приёмки
Критерии приёмки для анимаций:
- Анимация запускается при ожидаемом событии (hover, click, scroll).
- Время анимации и easing соответствуют дизайн-гайдам.
- При закрытии через AnimatePresence видна exit-анимация.
- На устройствах с prefers-reduced-motion анимации отключены.
- Нет заметных просадок FPS при типичной нагрузке.
Примеры тест-кейсов:
- Наведение на кнопку — scale достигает 1.1.
- Открытие модалки — виден backdrop и modal плавно появляется.
- Быстрое открытие/закрытие модалки — анимации не ломают состояние приложения.
Роль-ориентированные чек-листы
Для разработчика:
- Проверить импорт { motion } и { AnimatePresence }.
- Убедиться, что variants описаны и используются.
- Тестировать на desktop, мобильных и слабых устройствах.
Для дизайнера:
- Уточнить длительности и easing у анимаций.
- Предоставить варианты для reduced-motion.
Для QA:
- Прогнать тесты на анимации (визуальные и поведенческие).
- Проверить доступность (screen readers, keyboard navigation).
Когда Framer Motion не подходит — контрпримеры
- Простая статичная анимация (например, CSS-only hover без связи со стейтом) — проще сделать на чистом CSS.
- Проекты с нативным рендером вне браузера или строго ограниченным бандлом могут требовать альтернатив.
- Высокопроизводительные игровые визуализации — лучше специализированные рендереры (WebGL/Canvas).
Альтернативы
- React Spring — физически основанные анимации, полезны для больших переходов и физики.
- GreenSock (GSAP) — мощная библиотека с обширным функционалом, коммерческая лицензия в некоторых случаях.
- Чистый CSS — найлегчайший вариант для простых переходов и анимаций.
Выбор зависит от требований: интеграция со стейтом, сложность анимаций, производительность, размер бандла.
Ментальные модели и эвристики
- State-first: описывайте анимацию как функцию состояния — animation = f(state).
- Избегайте анимаций, которые меняют layout существенно — они дороже по производительности.
- Предпочитайте композицию: простые анимации у дочерних элементов чаще легче контролировать.
Мини-методология внедрения анимаций (пошагово)
- Определите цель каждой анимации (обратная связь, фокус, навигация).
- Согласуйте длительности и easing с дизайном.
- Реализуйте минимально жизнеспособную анимацию (MVP).
- Протестируйте на разных устройствах и с prefers-reduced-motion.
- Профилируйте и оптимизируйте.
- Документируйте в design system.
Playbook: проверка модалки (SOP)
- Создать Backdrop с initial/animate/exit.
- Создать Modal с variants (initial/visible/exit).
- Обернуть Modal в AnimatePresence.
- Триггерить показ модалки через state в App.
- Добавить управление закрытием клавишей Escape и фокус-менеджмент.
- Тестировать: keyboard, mouse, touch, reduced motion.
Совместимость и миграция
- Framer Motion поддерживает React 16.8+ (hooks). При работе с SSR учитывайте, что AnimatePresence ведёт себя иначе на сервере — убедитесь, что initial={false} выставлен правильно.
- При переходе с CSS на Framer Motion: переносите логику анимаций в компоненты постепенно, оставляя критичные переходы на CSS при необходимости.
Сниппет: чек-лист для PR, внедряющего анимацию
- Описаны цели анимации в описании PR
- Есть скриншоты/видео работы анимации
- Пройдены тесты accessibility
- Производительность в пределах ожидаемого
- Покрыты кейсы reduced-motion
Маленький словарь терминов
- Motion-компонент — компонент из framer-motion: motion.div, motion.button.
- Variant — именованный набор состояний для animation.
- AnimatePresence — компонент для управления enter/exit-анимациями в React.
- whileInView — анимация, триггерящаяся при появлении в видимой области.
Сравнение: когда CSS, когда Framer Motion
- CSS: простые hover/toggle-переходы, минимальные зависимости.
- Framer Motion: анимации, тесно связанные со стейтом, последовательности, синхронизация вход/выход.
Рекомендации по дизайну и UX
- Используйте анимации для усиления обратной связи, а не для отвлечения.
- Длительности: микровзаимодействия 50–200 мс, заметные переходы 200–500 мс, сложные переходы — до 700–1000 мс с spring.
- Единый набор easing и длительностей в дизайн-системе.
Образец решения проблемы: модалка не анимируется при закрытии
Причина: Modal удаляется из DOM до завершения exit-анимации. Решение: обернуть компонент в AnimatePresence и использовать exit-variant; установить initial={false}, mode=”wait” при необходимости.
Decision flow (упрощённый)
flowchart TD
A[Нужно анимировать?] -->|Да| B{Требуется ли связь с state?}
B -->|Да| C[Использовать Framer Motion]
B -->|Нет| D{Простая транcформация?}
D -->|Да| E[Использовать CSS]
D -->|Нет| F[Рассмотреть GSAP или React Spring]
A -->|Нет| G[Не анимировать]Риски и смягчение
- Перегрузка анимациями: проводить UX-ревью, ограничивать количество параллельных анимаций.
- Производительность: профилировать, использовать transform/opacity.
- Доступность: всегда поддерживать prefers-reduced-motion и альтернативную обратную связь.
Короткий план внедрения на проекте (roadmap)
- Провести аудит текущих анимаций.
- Выбрать набор базовых motion-компонентов и variants.
- Внедрить для микровзаимодействий (кнопки, тулы).
- Расширить на модалки, переходы страниц.
- Документировать в design system.
Итог
Framer Motion даёт мощный и удобный инструмент для создания анимаций в React-приложениях. Он удобен там, где анимации связаны со стейтом и жизненным циклом компонентов. При внедрении важно учитывать доступность, производительность и согласованность с дизайн-гайдами.
Короткое резюме
- Framer Motion = декларативные анимации для React.
- Используйте motion-компоненты, variants и AnimatePresence.
- Поддерживайте prefers-reduced-motion и профилируйте производительность.
Дополнительные материалы: официальный сайт Framer Motion и документация по API помогут углубиться в конкретные хуки и advanced patterns.
Похожие материалы
Папка профиля Firefox: где найти и как восстановить
Исправить: USB-устройство не распознано — контроллер Xbox One
Сборка Ender 3 V2 — пошаговая инструкция
Добавить Google Alerts в RSS-ленту
Идеальное резюме в Canva: поиск и настройка