Кастомные анимации

Chakra UI предоставляет гибкую систему для создания анимаций компонентов, опираясь на CSS-свойства и возможности фреймворка Framer Motion, интегрированного в библиотеку. В основе кастомных анимаций лежит компонент motion, который позволяет расширять стандартные элементы Chakra UI с поддержкой анимационных состояний.

import { Box } from "@chakra-ui/react";
import { motion } from "framer-motion";

const MotionBox = motion(Box);

<MotionBox
  initial={{ opacity: 0, y: -50 }}
  animate={{ opacity: 1, y: 0 }}
  transition={{ duration: 0.5 }}
>
  Анимированный контент
</MotionBox>
  • initial задаёт стартовое состояние компонента.
  • animate определяет конечное состояние.
  • transition управляет длительностью и типом анимации.

Создание повторяющихся анимаций

Для циклических или бесконечных анимаций используется свойство repeat в объекте transition. Также доступны параметры repeatType и repeatDelay для более точного контроля.

<MotionBox
  animate={{ x: [0, 50, 0] }}
  transition={{ duration: 2, repeat: Infinity, repeatType: "loop", repeatDelay: 0.5 }}
>
  Плавное движение
</MotionBox>
  • repeat: Infinity делает анимацию бесконечной.
  • repeatType: "loop" позволяет зацикливать анимацию.
  • repeatDelay задаёт паузу между циклами.

Использование пользовательских ключевых кадров

Chakra UI с Framer Motion позволяет создавать сложные анимации с помощью keyframes. Это особенно удобно для анимаций нескольких состояний без ручного управления переходами.

<MotionBox
  animate={{
    scale: [1, 1.2, 0.8, 1],
    rotate: [0, 15, -15, 0],
    borderRadius: ["20%", "50%", "20%", "50%"]
  }}
  transition={{ duration: 2, ease: "easeInOut", repeat: Infinity }}
>
  Ключевые кадры
</MotionBox>

Ключевые моменты:

  • Масштабирование и вращение могут комбинироваться.
  • borderRadius позволяет создавать эффект «пульсации» форм.
  • Использование массивов значений задаёт последовательность ключевых кадров.

Анимации при появлении и исчезновении компонентов

Компоненты Chakra UI легко интегрируются с анимациями появления и исчезновения, что полезно для модальных окон, всплывающих подсказок и уведомлений. Для этого используется комбинация initial, animate и exit вместе с AnimatePresence из Framer Motion.

import { AnimatePresence, motion } from "framer-motion";

<AnimatePresence>
  {isVisible && (
    <MotionBox
      initial={{ opacity: 0, y: -20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: 20 }}
      transition={{ duration: 0.4 }}
    >
      Появляющийся элемент
    </MotionBox>
  )}
</AnimatePresence>
  • exit задаёт анимацию при удалении компонента из DOM.
  • AnimatePresence управляет правильной последовательностью анимаций при монтировании и размонтировании.

Создание кастомных хуков для анимаций

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

import { useAnimation } from "framer-motion";

function usePulseAnimation() {
  const controls = useAnimation();

  React.useEffect(() => {
    controls.start({
      scale: [1, 1.1, 1],
      transition: { duration: 1, repeat: Infinity }
    });
  }, [controls]);

  return controls;
}

// Использование
<MotionBox animate={usePulseAnimation()}>
  Пульсирующая кнопка
</MotionBox>

Хуки позволяют:

  • Избегать дублирования кода.
  • Управлять сложными последовательностями анимаций.
  • Делать анимации условными, основанными на состоянии.

Интеграция с системами темы Chakra UI

Анимации можно настраивать с учётом темы Chakra UI, используя токены цвета, размера или стиля шрифтов. Это обеспечивает консистентность визуального оформления при кастомных эффектах.

import { useToken } from "@chakra-ui/react";

const primaryColor = useToken("colors", "brand.500");

<MotionBox
  animate={{ backgroundColor: [primaryColor, "#ffffff", primaryColor] }}
  transition={{ duration: 2, repeat: Infinity }}
>
  Анимация с цветами темы
</MotionBox>
  • useToken позволяет получать значения темы и использовать их в анимациях.
  • Цветовые переходы можно комбинировать с движением и трансформацией.

Производительность и оптимизация

Для крупных приложений важно контролировать производительность:

  • Минимизировать количество одновременно анимируемых компонентов.
  • Предпочитать трансформации (transform: scale/translate/rotate) вместо изменения свойств width/height или top/left.
  • Использовать will-change: transform для GPU-ускорения анимаций.

Комбинирование анимаций с условным рендерингом

Chakra UI и Framer Motion позволяют создавать комплексные интерактивные интерфейсы с множественными анимациями, которые зависят от состояния приложения.

<MotionBox
  animate={isActive ? { scale: 1.2, rotate: 10 } : { scale: 1, rotate: 0 }}
  transition={{ type: "spring", stiffness: 200 }}
>
  Интерактивный элемент
</MotionBox>
  • Использование spring даёт естественное, физически корректное движение.
  • Условное переключение состояний позволяет строить динамические интерфейсы без сложных таймеров.

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