ByteNoteByteNote
界面动画总是僵?react-spring 用物理参数取代时长
字

字节笔记本

2026年10月28日 · 约 4 分钟读完

界面动画总是僵?react-spring 用物理参数取代时长

API中转
¥120

这是 agent 出片工具链系列的第 4 篇。动画库其实分两个流派:时间驱动派给你 duration 加缓动曲线,物理驱动派只给你弹簧参数,让画面自己「落」到终点。react-spring 是后一派的代表,README 自称 spring-physics first。仓库 2.9 万星、MIT 协议,@react-spring/web 单包月下载就有 2008 万,稳定版 v10.1.2,10 月初刚发了 v11 的第二个 beta。顺带提醒:老的 react-spring.io 域名已被无关站点占据,官方文档现在在 react-spring.dev。

react-spring:A spring-physics first animation library

一、不设时长,只设手感

时间驱动动画有个老大难:动画跑到一半被用户打断怎么办?反向播放要重新起一段动画,速度从零开始,肉眼看就是「卡一下」。弹簧物理没有这个问题,动画的每一帧由当前速度、位置和目标点算出来,中途改目标,速度是连续的,肉眼看到的就是自然地拐弯。

用起来只有 from 和 to,加上可选的物理配置,张力、摩擦这些参数决定的是「手感」而不是时长:

jsx
import { useSpring, animated } from '@react-spring/web'

const springs = useSpring({
  from: { x: 0 },
  to: { x: 100 },
})

<animated.div style={{ ...springs }} />

把返回的 springs 展开进 style,元素挂载后自己动。当然它也没把时间驱动派一棍子打死,README 写明默认用弹簧,需要精确卡点时同样支持 duration 加 easing。

二、五个 hooks 覆盖常见动效

API 表面很小:useSpring 是单个弹簧;useSprings 给列表批量发弹簧;useTrail 让一串元素依次跟随,做拖尾;useTransition 管挂载和卸载的进出场;useChain 把几段动画串成一条时间线。配一个 animated 高阶组件,把 SpringValue 直接当样式用,命令式控制走 api 对象的 start、stop、set。

react-spring 仓库:2.9 万星,v11 beta 进行中

平台包按渲染目标拆分:网页用 @react-spring/web,配 Three.js 场景用 @react-spring/three,还有 konva、zdog 等绑定,也就是 README 列的 react-dom、react-three-fiber、react-konva、react-zdog 那一排。版本上有条分界线:React 19 直接装最新包,老版本 React 要退回 @react-spring/web@9。

@react-spring/three 与 react-three-fiber 配合做 3D 动效

三、放在 agent 出片流水线里的位置

对 agent 来说,react-spring 是个好服务对象:API 面小、全声明式、物理参数不依赖设计师调曲线,生成的代码命中率高。网页端的界面动效、卡片悬浮、列表进出场,交给它正合适。

但有一条边界要说清:真实时间的物理模拟是「不可复现」的,同样的参数渲染两次,帧和帧之间对不齐。视频渲染恰恰要求确定性,每一帧必须一样。所以在这个系列里它的分工很明确,网页动效归 react-spring,视频里要弹簧手感就用 Remotion 自带的 spring(),那是帧号驱动的同款物理,专为逐帧渲染设计。

即将到来的 v11 也值得盯一下:beta 阶段的变更说明里写了转向 ESM-only 构建,并移除废弃目标、native 支持和伞形包,维护明显在向 web 和 three 收拢。生产环境现在可以稳定用 v10 系列,新项目建议直接定 React 19,省得将来迁移。

下一篇是 GPU 2D 图形库 PixiJS,粒子、滤镜和高帧率画布都靠它。

相关文章

分享: