You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于滚动位置用React和Framer Motion实现文字逐字变色

实现滚动驱动的逐字变色动画方案

基于React + Framer Motion,参考Polestar的滚动字符变色效果,核心思路是拆分字符独立控制 + 滚动进度映射动画触发时机,具体实现步骤如下:

1. 核心思路拆解

要实现逐字变色,必须把文本拆分为单个独立元素,再根据滚动位置,给每个字符分配不同的动画触发阈值,通过Framer Motion将滚动进度映射为字符的颜色变化。

2. 具体实现步骤

步骤1:拆分文本为单个字符组件

将目标文本拆分为数组,每个字符渲染成单独的motion.span,这样能单独控制每个字符的样式和动画状态。

步骤2:监听滚动进度

使用Framer Motion的useScroll钩子,监听目标区块的滚动位置,计算区块在视口中的滚动进度(0到1的范围)。通过offset参数定义进度的起止点:

  • ["start end", "end start"]表示:当区块顶部刚进入视口底部时进度为0,当区块底部完全离开视口顶部时进度为1。

步骤3:映射滚动进度到字符颜色

对每个字符,根据其索引计算专属的触发进度(比如第n个字符的触发点为n / 总字符数),再用useTransform将滚动进度转化为字符的颜色值,实现滚动到对应位置时字符平滑变色。

3. 完整代码示例

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

export default function ScrollTextColor() {
  const targetText = "PRECISION";
  const sectionRef = useRef(null);
  
  // 监听目标区块的滚动进度
  const { scrollYProgress } = useScroll({
    target: sectionRef,
    offset: ["start end", "end start"]
  });

  return (
    <div className="App">
      {/* 顶部占位区,用于触发滚动 */}
      <div style={{ height: "100vh", display: "flex", alignItems: "center", justifyContent: "center" }}>
        向下滚动查看效果
      </div>
      
      {/* 目标动画区块 */}
      <div 
        ref={sectionRef} 
        style={{ 
          height: "100vh", 
          display: "flex", 
          alignItems: "center", 
          justifyContent: "center",
          backgroundColor: "#f5f5f5"
        }}
      >
        <div style={{ fontSize: "8rem", fontWeight: "800", letterSpacing: "0.5rem" }}>
          {targetText.split("").map((char, index) => {
            // 计算当前字符的动画触发进度
            const triggerPoint = index / targetText.length;
            // 映射滚动进度到颜色变化:从灰色过渡到黑色
            const charColor = useTransform(
              scrollYProgress,
              [triggerPoint - 0.1, triggerPoint],
              ["#888888", "#000000"]
            );

            return (
              <motion.span 
                key={index} 
                style={{ color: charColor, transition: "color 0.3s ease" }}
              >
                {char}
              </motion.span>
            );
          })}
        </div>
      </div>
      
      {/* 底部占位区 */}
      <div style={{ height: "100vh" }}></div>
    </div>
  );
}

4. 优化与扩展

  • 动画过渡优化:调整useTransform的输入范围(比如[triggerPoint - 0.1, triggerPoint])可以控制颜色过渡的快慢,数值区间越大过渡越平缓。
  • 性能优化:如果文本过长,可将单个字符组件封装为React.memo组件,避免不必要的重渲染。
  • 扩展动画效果:除了颜色,还可以映射滚动进度到字符的缩放、字体粗细、透明度等属性,增强视觉层次。

内容的提问来源于stack exchange,提问作者Ayhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:03:12