Introdução ao Framer Motion - Animações React

Intermediário | 45 min leitura | 2025.12.07

O que você aprenderá neste tutorial

✓ Animações básicas
✓ Variants
✓ Gestos
✓ Animações de layout
✓ AnimatePresence

Step 1: Configuração

npm install framer-motion

Step 2: Animações Básicas

import { motion } from 'framer-motion';

function BasicAnimation() {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5 }}
    >
      Hello Animation!
    </motion.div>
  );
}

Step 3: Hover e Tap

function InteractiveBox() {
  return (
    <motion.button
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.95 }}
      className="px-4 py-2 bg-blue-500 text-white rounded"
    >
      Click me
    </motion.button>
  );
}

Step 4: Variants

const containerVariants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
    },
  },
};

const itemVariants = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1, y: 0 },
};

function StaggeredList() {
  const items = ['Item 1', 'Item 2', 'Item 3'];

  return (
    <motion.ul
      variants={containerVariants}
      initial="hidden"
      animate="visible"
    >
      {items.map((item, i) => (
        <motion.li key={i} variants={itemVariants}>
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

Step 5: AnimatePresence

import { motion, AnimatePresence } from 'framer-motion';
import { useState } from 'react';

function ToggleContent() {
  const [isVisible, setIsVisible] = useState(true);

  return (
    <div>
      <button onClick={() => setIsVisible(!isVisible)}>Toggle</button>

      <AnimatePresence>
        {isVisible && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: 'auto' }}
            exit={{ opacity: 0, height: 0 }}
          >
            Content here
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

Step 6: Animações de Layout

function LayoutAnimation() {
  const [selected, setSelected] = useState<number | null>(null);

  return (
    <div className="grid grid-cols-3 gap-4">
      {[1, 2, 3].map((item) => (
        <motion.div
          key={item}
          layout
          onClick={() => setSelected(selected === item ? null : item)}
          className={`p-4 bg-blue-500 rounded cursor-pointer ${
            selected === item ? 'col-span-3' : ''
          }`}
        >
          {item}
        </motion.div>
      ))}
    </div>
  );
}

Step 7: Animações de Scroll

import { motion, useScroll, useTransform } from 'framer-motion';

function ScrollAnimation() {
  const { scrollYProgress } = useScroll();
  const opacity = useTransform(scrollYProgress, [0, 0.5], [1, 0]);
  const scale = useTransform(scrollYProgress, [0, 0.5], [1, 0.8]);

  return (
    <motion.div style={{ opacity, scale }}>
      Scroll to see animation
    </motion.div>
  );
}

Step 8: Drag

function DraggableBox() {
  return (
    <motion.div
      drag
      dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
      dragElastic={0.2}
      whileDrag={{ scale: 1.1 }}
      className="w-20 h-20 bg-blue-500 rounded cursor-grab"
    />
  );
}

Resumo

Framer Motion permite implementar animações complexas facilmente com uma API declarativa. Crie UIs bonitas com variants e AnimatePresence.

← Voltar para a lista