返回文章列表
设计

用 Framer Motion 打造令人惊艳的 Web 动画

用 Framer Motion 打造令人惊艳的 Web 动画

动画是现代 Web 体验的重要组成部分。Framer Motion 让 React 开发者能够轻松创建复杂而流畅的动画效果。

基础动画

最简单的动画只需要 motion 组件和 animate 属性:

import { motion } from 'framer-motion';

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

手势交互

Framer Motion 内置了丰富的手势支持:

function InteractiveCard() {
  return (
    <motion.div
      whileHover={{ scale: 1.05, rotateY: 5 }}
      whileTap={{ scale: 0.95 }}
      drag
      dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
      className="card"
    >
      拖拽我试试!
    </motion.div>
  );
}

滚动驱动动画

使用 useScrolluseTransform 创建视差效果:

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

function ParallaxSection() {
  const { scrollYProgress } = useScroll();
  const y = useTransform(scrollYProgress, [0, 1], [0, -200]);
  const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [1, 0.8, 0]);

  return (
    <motion.div style={{ y, opacity }}>
      <h1>视差滚动效果</h1>
    </motion.div>
  );
}

布局动画

layoutId 实现跨组件的平滑过渡:

function TabContent({ activeTab }) {
  return (
    <div className="tabs">
      {tabs.map(tab => (
        <button key={tab.id}>
          {tab.label}
          {activeTab === tab.id && (
            <motion.div
              layoutId="activeTab"
              className="indicator"
            />
          )}
        </button>
      ))}
    </div>
  );
}

3D 倾斜卡片效果

结合 useMotionValueuseTransform 实现 3D 效果:

function TiltCard() {
  const x = useMotionValue(0);
  const y = useMotionValue(0);
  const rotateX = useTransform(y, [-100, 100], [10, -10]);
  const rotateY = useTransform(x, [-100, 100], [-10, 10]);

  return (
    <motion.div
      style={{ rotateX, rotateY, transformStyle: 'preserve-3d' }}
      onMouseMove={(e) => {
        const rect = e.currentTarget.getBoundingClientRect();
        x.set(e.clientX - rect.left - rect.width / 2);
        y.set(e.clientY - rect.top - rect.height / 2);
      }}
      onMouseLeave={() => { x.set(0); y.set(0); }}
    >
      3D 倾斜卡片
    </motion.div>
  );
}

性能优化建议

  1. 使用 transform 属性 - GPU 加速,避免触发重排
  2. 合理使用 will-change - 提示浏览器优化
  3. 避免同时动画过多元素 - 使用 staggerChildren 错开
  4. 使用 useReducedMotion - 尊重用户的无障碍设置
import { useReducedMotion } from 'framer-motion';

function AccessibleAnimation() {
  const shouldReduceMotion = useReducedMotion();
  
  return (
    <motion.div
      animate={{ x: shouldReduceMotion ? 0 : 100 }}
    />
  );
}

总结

Framer Motion 是 React 生态中最强大的动画库之一。通过合理运用这些技巧,你可以为用户创造出既美观又流畅的交互体验。

记住:好的动画应该是有目的的自然的不干扰用户的。