Tips & Tricks

Framer Motion con Claude Code

Aprenda sobre Framer Motion usando Claude Code. Incluye consejos practicos y ejemplos de codigo.

Construyendo animaciones sofisticadas con Framer Motion

Framer Motion es una libreria de animaciones declarativas para React. Permite implementar interacciones complejas y animaciones de layout que son dificiles con CSS animations, usando una API intuitiva. Claude Code brinda soporte preciso desde el diseno de animaciones hasta ajustes finos de easing.

Animaciones basicas

Solicitemos a Claude Code componentes con animaciones.

> Crea animaciones de lista de tarjetas con Framer Motion.
> Con display escalonado al montar, ampliacion al pasar el cursor y feedback al hacer clic.
import { motion, AnimatePresence } from "framer-motion";

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

const cardVariants = {
  hidden: { opacity: 0, y: 20 },
  visible: {
    opacity: 1,
    y: 0,
    transition: { duration: 0.4, ease: "easeOut" },
  },
};

function CardList({ items }: { items: Item[] }) {
  return (
    <motion.div
      variants={containerVariants}
      initial="hidden"
      animate="visible"
      className="grid grid-cols-3 gap-4"
    >
      {items.map((item) => (
        <motion.div
          key={item.id}
          variants={cardVariants}
          whileHover={{ scale: 1.03, boxShadow: "0 8px 30px rgba(0,0,0,0.12)" }}
          whileTap={{ scale: 0.98 }}
          className="p-6 bg-white rounded-lg shadow"
        >
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </motion.div>
      ))}
    </motion.div>
  );
}

Montar y desmontar con AnimatePresence

Patron para agregar animaciones al agregar y eliminar elementos.

function NotificationStack({ notifications }: { notifications: Notification[] }) {
  return (
    <div className="fixed top-4 right-4 space-y-2">
      <AnimatePresence mode="popLayout">
        {notifications.map((notification) => (
          <motion.div
            key={notification.id}
            initial={{ opacity: 0, x: 100, scale: 0.9 }}
            animate={{ opacity: 1, x: 0, scale: 1 }}
            exit={{ opacity: 0, x: 100, scale: 0.9 }}
            transition={{ type: "spring", stiffness: 300, damping: 25 }}
            layout
            className="bg-white p-4 rounded-lg shadow-lg min-w-[300px]"
          >
            <p>{notification.message}</p>
          </motion.div>
        ))}
      </AnimatePresence>
    </div>
  );
}

Animaciones de layout

Con la propiedad layout, puede lograr animaciones suaves al cambiar el layout.

function FilterableGrid({ items }: { items: Item[] }) {
  const [filter, setFilter] = useState("all");

  const filteredItems = items.filter(
    (item) => filter === "all" || item.category === filter
  );

  return (
    <div>
      <div className="flex gap-2 mb-4">
        {["all", "design", "dev", "marketing"].map((f) => (
          <motion.button
            key={f}
            onClick={() => setFilter(f)}
            className={`px-4 py-2 rounded ${filter === f ? "bg-blue-500 text-white" : "bg-gray-200"}`}
            whileHover={{ scale: 1.05 }}
            whileTap={{ scale: 0.95 }}
          >
            {f}
          </motion.button>
        ))}
      </div>

      <motion.div layout className="grid grid-cols-3 gap-4">
        <AnimatePresence>
          {filteredItems.map((item) => (
            <motion.div
              key={item.id}
              layout
              initial={{ opacity: 0, scale: 0.8 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.8 }}
              transition={{ duration: 0.3 }}
              className="p-4 bg-white rounded-lg"
            >
              {item.title}
            </motion.div>
          ))}
        </AnimatePresence>
      </motion.div>
    </div>
  );
}

Animaciones vinculadas al scroll

Implementamos animaciones vinculadas a la posicion de scroll con useScroll y useTransform.

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

function ParallaxHero() {
  const { scrollY } = useScroll();
  const y = useTransform(scrollY, [0, 500], [0, -150]);
  const opacity = useTransform(scrollY, [0, 300], [1, 0]);
  const scale = useTransform(scrollY, [0, 300], [1, 0.8]);

  return (
    <motion.div
      style={{ y, opacity, scale }}
      className="h-screen flex items-center justify-center"
    >
      <h1 className="text-6xl font-bold">Bienvenido</h1>
    </motion.div>
  );
}

function ScrollReveal({ children }: { children: React.ReactNode }) {
  const ref = useRef(null);
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ["start end", "end start"],
  });

  const opacity = useTransform(scrollYProgress, [0, 0.3], [0, 1]);
  const y = useTransform(scrollYProgress, [0, 0.3], [50, 0]);

  return (
    <motion.div ref={ref} style={{ opacity, y }}>
      {children}
    </motion.div>
  );
}

Animaciones de gestos

Animaciones que responden a gestos como arrastrar y deslizar.

function DraggableCard() {
  return (
    <motion.div
      drag
      dragConstraints={{ left: -100, right: 100, top: -50, bottom: 50 }}
      dragElastic={0.2}
      dragTransition={{ bounceStiffness: 300, bounceDamping: 20 }}
      whileDrag={{ scale: 1.1, cursor: "grabbing" }}
      className="w-48 h-48 bg-blue-500 rounded-xl cursor-grab"
    />
  );
}

function SwipeCard({ onSwipe }: { onSwipe: (dir: string) => void }) {
  return (
    <motion.div
      drag="x"
      dragConstraints={{ left: 0, right: 0 }}
      onDragEnd={(_, info) => {
        if (info.offset.x > 100) onSwipe("right");
        if (info.offset.x < -100) onSwipe("left");
      }}
      className="p-8 bg-white rounded-xl shadow-lg"
    >
      Por favor deslice
    </motion.div>
  );
}

Resumen

Con Framer Motion, puede agregar facilmente animaciones sofisticadas a aplicaciones React. Con solo decirle a Claude Code “quiero este tipo de animacion”, genera el diseno de variantes y la configuracion de easing apropiados.

Para la combinacion con componentes de UI, consulte Uso de componentes Radix UI. Para la construccion de sistemas de diseno, consulte la guia de uso de shadcn/ui. Tambien revise la documentacion oficial de Framer Motion.

#Claude Code #Framer Motion #React #animation #UI/UX