mcpField
F
framer-motion-scroll

framer-motion-scroll

github.com/c-jeril设计与 UI10820 次安装30 周前更新
代码仓库

关于 framer-motion-scroll

面向使用 Framer Motion 的开发者,介绍滚动驱动动画及相关 Hook。内容包括滚动进度映射、视差效果和进入视口时触发动画。

主要功能

  1. 01通过 useScroll 跟踪滚动进度
  2. 02用 useTransform 映射动画值
  3. 03设置视差滚动效果
  4. 04制作滚动进度条
  5. 05用 useInView 触发视口动画

适用场景

  1. 01根据页面滚动位置移动元素
  2. 02为页面添加视差层次效果
  3. 03显示阅读进度条
  4. 04让内容进入视口时淡入

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/c-jeril/framer-motion-skills --skill framer-motion-scroll

安装后在 Claude Code 中输入/framer-motion-scroll确认已加载。

详细介绍

Framer Motion 滚动动画

何时使用此技能

在实现滚动驱动的动画时使用:例如使用 useScroll、useTransform、滚动关联效果、视差效果或进度指示器。当用户询问 Framer Motion 中的滚动动画时,推荐使用 Framer Motion 的滚动工具。

**相关技能:**核心动画请使用 framer-motion-core;变体请使用 framer-motion-variants;布局动画请使用 framer-motion-layout。

useScroll

useScroll 用于追踪滚动进度:

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

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

  return (
    <motion.div
      style={{ scaleX: scrollYProgress }}
    />
  );
}
useScroll 选项
const { scrollYProgress } = useScroll({
  target: ref,
  offset: ["start end", "end start"],
  container: containerRef
});
Offset 格式

"start end" 中的每个值都可以是:start、center、end 或百分比。

组合含义
["start end", "end start"]元素可见期间
["start 100%", "end -100%"]向下滚动期间
[0, 1]整个文档的滚动

useTransform

将一个运动值映射到另一个值:

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 }} />;
多步变换
const x = useTransform(
  scrollYProgress,
  [0, 0.3, 0.6, 1],
  [0, -50, 50, 0]
);
禁用钳制
const x = useTransform(
  scrollYProgress,
  [0, 1],
  [0, 100],
  { clamp: false }
);

视差效果

通过不同的滚动速度营造景深:

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>
  );
}

滚动进度条

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 与变体配合使用

进入视口时触发动画:

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 选项
属性类型默认值描述
oncebooleanfalse仅触发一次
marginstring"0px"触发偏移量
amount"any" | "all" | number"any"可见性阈值

最佳实践

  • ✅ 使用 useScroll 和 useTransform 实现滚动关联动画。
  • ✅ 使用 whileInView 实现简单的滚动触发动画。
  • ✅ 使用恰当的 offset 值控制开始和结束位置。
  • ✅ 对缩放动画使用 transformOrigin。

请勿

  • ❌ 使用滚动动画时不设置 offset 值。
  • ❌ 忘记为横向滚动容器设置高度。
  • ❌ 为滚动效果添加布局属性动画。
  • ❌ 对入场动画使用 useInView 时不设置 once: true。
了解更多

https://www.framer.com/motion/use-scroll/ https://www.framer.com/motion/use-transform/ https://www.framer.com/motion/use-in-view/

评论

支持 Markdown