framer-motion-scroll

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Framer Motion Scroll Animations

Framer Motion 滚动动画

When to Use This Skill

何时使用该技能

Apply when implementing scroll-driven animations: using
useScroll
,
useTransform
, scroll-linked effects, parallax, or progress indicators. When the user asks about scroll animation in Framer Motion, recommend Framer Motion's scroll utilities.
Related skills: For core animation use framer-motion-core; for variants use framer-motion-variants; for layout animations use framer-motion-layout.
在实现滚动驱动动画时使用:包括使用
useScroll
useTransform
、滚动关联效果、视差或进度指示器。当用户询问Framer Motion中的滚动动画相关问题时,推荐使用Framer Motion的滚动工具。
相关技能: 核心动画使用framer-motion-core;变体使用framer-motion-variants;布局动画使用framer-motion-layout

useScroll

useScroll

useScroll
tracks scroll progress:
jsx
import { useScroll, useTransform } from "framer-motion";

function Component() {
  const { scrollYProgress } = useScroll();

  return (
    <motion.div
      style={{ scaleX: scrollYProgress }}
    />
  );
}
useScroll
用于追踪滚动进度:
jsx
import { useScroll, useTransform } from "framer-motion";

function Component() {
  const { scrollYProgress } = useScroll();

  return (
    <motion.div
      style={{ scaleX: scrollYProgress }}
    />
  );
}

useScroll Options

useScroll 配置选项

jsx
const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["start end", "end start"],
  container: containerRef
});
jsx
const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["start end", "end start"],
  container: containerRef
});

Offset Format

偏移量格式

"start end"
where each can be:
start
,
center
,
end
, or percentage.
CombinationMeaning
["start end", "end start"]
While element visible
["start 100%", "end -100%"]
While scrolling down
[0, 1]
Entire document scroll
"start end"
中的每个值可以是:
start
center
end
或百分比。
组合含义
["start end", "end start"]
元素可见期间
["start 100%", "end -100%"]
向下滚动期间
[0, 1]
整个文档滚动

useTransform

useTransform

Map one motion value to another:
jsx
const { scrollYProgress } = useScroll();

const scale = useTransform(scrollYProgress, [0, 1], [1, 2]);
const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [0, 1, 0]);

return <motion.div style={{ scale, opacity }} />;
将一个运动值映射到另一个:
jsx
const { scrollYProgress } = useScroll();

const scale = useTransform(scrollYProgress, [0, 1], [1, 2]);
const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [0, 1, 0]);

return <motion.div style={{ scale, opacity }} />;

Multi-step Transforms

多阶段转换

jsx
const x = useTransform(
  scrollYProgress,
  [0, 0.3, 0.6, 1],
  [0, -50, 50, 0]
);
jsx
const x = useTransform(
  scrollYProgress,
  [0, 0.3, 0.6, 1],
  [0, -50, 50, 0]
);

Disable Clamping

禁用限制

jsx
const x = useTransform(
  scrollYProgress,
  [0, 1],
  [0, 100],
  { clamp: false }
);
jsx
const x = useTransform(
  scrollYProgress,
  [0, 1],
  [0, 100],
  { clamp: false }
);

Parallax Effect

视差效果

Different scroll speeds for depth:
jsx
function ParallaxSection() {
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ["start end", "end start"]
  });

  const y = useTransform(scrollYProgress, [0, 1], [100, -100]);

  return (
    <motion.div ref={ref} style={{ y }}>
      Parallax Content
    </motion.div>
  );
}
通过不同滚动速度营造深度感:
jsx
function ParallaxSection() {
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ["start end", "end start"]
  });

  const y = useTransform(scrollYProgress, [0, 1], [100, -100]);

  return (
    <motion.div ref={ref} style={{ y }}>
      Parallax Content
    </motion.div>
  );
}

Scroll Progress Bar

滚动进度条

jsx
function ScrollProgress() {
  const { scrollYProgress } = useScroll();

  return (
    <motion.div
      style={{
        scaleX: scrollYProgress,
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        height: 4,
        backgroundColor: "#00ff00",
        transformOrigin: "0%"
      }}
    />
  );
}
jsx
function ScrollProgress() {
  const { scrollYProgress } = useScroll();

  return (
    <motion.div
      style={{
        scaleX: scrollYProgress,
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        height: 4,
        backgroundColor: "#00ff00",
        transformOrigin: "0%"
      }}
    />
  );
}

useInView with Variants

useInView 与变体

Trigger animation when entering viewport:
jsx
import { useInView, motion } from "framer-motion";
import { useRef } from "react";

function FadeInSection() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-100px" });

  return (
    <motion.div
      ref={ref}
      initial={{ opacity: 0, y: 50 }}
      animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
      transition={{ duration: 0.6 }}
    >
      Content
    </motion.div>
  );
}
进入视口时触发动画:
jsx
import { useInView, motion } from "framer-motion";
import { useRef } from "react";

function FadeInSection() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-100px" });

  return (
    <motion.div
      ref={ref}
      initial={{ opacity: 0, y: 50 }}
      animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 50 }}
      transition={{ duration: 0.6 }}
    >
      Content
    </motion.div>
  );
}

useInView Options

useInView 配置选项

PropTypeDefaultDescription
once
boolean
false
Only trigger once
margin
string
"0px"
Offset for trigger
amount
"any" | "all" | number
"any"
Visibility threshold
属性类型默认值描述
once
boolean
false
仅触发一次
margin
string
"0px"
触发偏移量
amount
"any" | "all" | number
"any"
可见性阈值

Best practices

最佳实践

  • ✅ Use useScroll with useTransform for scroll-linked animations.
  • ✅ Use whileInView for simple scroll-triggered animations.
  • ✅ Use proper offset values to control start/end.
  • ✅ Use
    transformOrigin
    for scale animations.
  • ✅ 将useScrolluseTransform配合使用,实现滚动关联动画。
  • ✅ 使用whileInView实现简单的滚动触发动画。
  • ✅ 使用合适的offset值控制动画的开始/结束时机。
  • ✅ 为缩放动画设置
    transformOrigin

Do Not

注意事项

  • ❌ Use scroll animations without offset values.
  • ❌ Forget to set height on scroll containers for horizontal scroll.
  • ❌ Animate layout properties for scroll effects.
  • ❌ Use
    useInView
    without
    once: true
    for entrance animations.
  • ❌ 不要在没有设置偏移量的情况下使用滚动动画。
  • ❌ 不要忘记为水平滚动的滚动容器设置高度。
  • ❌ 不要为滚动效果动画布局属性。
  • ❌ 不要在入场动画中使用未设置
    once: true
    useInView

Learn More

了解更多