跳转到主要内容
返回文章
1 分钟阅读

逐字揭示与滚动叙事:动效的节奏感

#动效#Framer Motion#叙事
逐字揭示与滚动叙事:动效的节奏感

滚动叙事(scroll-driven storytelling)的魅力,在于把「阅读」变成「体验」:你滚动的每一寸,都驱动着画面或文字做出回应。其中「逐字揭示」是我最喜欢的技巧之一——一段话,随着你的滚动,一个字一个字地亮起来。

原理

核心是监听某个容器的滚动进度,再把进度映射到每个字符的透明度上。每个字符占据进度轴上的一个小区间,滚动到那里时,它恰好被点亮:

const { scrollYProgress } = useScroll({
  target: ref,
  offset: ['start 0.85', 'end 0.4'],
});
 
const opacity = useTransform(scrollYProgress, range, [0.16, 1]);

一个经典的 React 陷阱

最初我直接在 map 循环里调用 useTransform,结果立刻报错——这违反了 Hooks 规则:Hook 只能在组件顶层调用,不能在循环里。

正确的做法,是把「单个字符」抽成一个独立组件,让它自己管理自己的 Hook:

function Char({ char, progress, range }) {
  const opacity = useTransform(progress, range, [0.16, 1]);
  return <motion.span style={{ opacity }}>{char}</motion.span>;
}

这样每个字符都是独立的组件实例,Hook 数量稳定,逻辑清晰。

节奏感从哪里来

逐字揭示的成败,九成在节奏。我的经验:

  1. 区间要重叠——相邻字符的亮度区间互相咬合,才有「流动」而非「跳跃」。
  2. 起始亮度别设为零——0.16 的底色让文字始终可辨,不至于漆黑一片。
  3. 给滚动多一点余量——offset 别卡太死,让动画有进入和完成的缓冲。

结语

动效是叙事的一部分。逐字揭示之所以动人,不是因为它「炫」,而是因为它让读者意识到:是我在推动这段文字,是我在让它亮起来。这种参与感,是静态排版给不了的。

节奏,是动效的呼吸。

假作真时真亦假,无为有处有还无。

凯 · KAI000%
泪蛋蛋掉在酒杯杯里
DJ版 · 镐天
0:000:00