面向 React DOM 的动效 · React Native Animated API

动效只写一次。运行顺滑,永不崩坏。

Animated 把 React Native 的 Animated 带到 Web。一个值驱动任意数量的元素且不会每帧触发 React 渲染,受支持的动效由浏览器自己播放,每次打断都从屏幕上的当前状态继续。

安装
npm install @kkwaenggwari/animated

一个时钟值驱动全部 64 个形状的涟漪。把指针移到舞台上试试。

本版本的实测数据

在桌面 PC 的无头 Chrome 中用 1.0.0 构建测量。数据因设备而异。 测量方法

  • 0.00ms400 个元素运动时每帧的 JavaScript

    Animated 元素上有限的 transform 和 opacity 动效由浏览器播放,页面自己的帧回调不做任何工作。

  • 0.13ms一个值驱动 10,000 个元素时每帧的 JavaScript

    这个值只写入一个 CSS 变量,每个元素都在 CSS 中由它推导出样式。

  • 0动效进行中的 React 渲染

    值从不经过 React state。组件在 props 变化时渲染,而不是在帧变化时。

01 · 简单

你熟悉的 API,用在普通的 React style 上

timing、spring、interpolate、loop 和 Animated.event 保留了 React Native 中的名称和配置。值可以直接放进普通的 style prop,在写出第一个动效之前,不需要学习任何特殊组件。

  • 把 Animated.View 改名为 Animated.div,就能移植 React Native 代码。
  • 一个值可以同时移动进度条、表盘和一排卡片,每个都有自己的范围。
  • useAnimated 负责管理动画配方:挂载时启动,依赖变化时重新开始,卸载时清理。

正在准备示例…

与 React Native 相同的调用

Spinner.jsx
// React Native
<Animated.View style={{ transform: [{ rotate }] }} />

// React DOM with @kkwaenggwari/animated — the rest is identical
<Animated.div style={{ transform: [{ rotate }] }} />

const spin = useAnimatedValue(0);
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] });

Animated.loop(
  Animated.timing(spin, { toValue: 1, duration: 900, easing: Easing.linear, useNativeDriver: true }),
).start();

02 · 快速

不会每帧触发 React 渲染

Hook 的值就是一个 CSS 变量。线性插值和算术运算会变成该变量的精确 calc() 表达式,所以每帧只写入一次,其余交给浏览器推导。Animated.<tag> 元素上有限的 transform 和 opacity 动效由浏览器播放,无需帧回调。

  • 改变圆点的数量:计数器显示 React 每次变化只渲染一次,而不是每帧一次。
  • scope 让值只在容器上写入一次,而不是写到每个元素上。
  • inspect(element) 告诉你每个属性走的是哪条路径,以及原因。

正在准备示例…

03 · 稳定

随时打断,都能接着动。

新的目标会从元素在屏幕上的位置开始,弹簧还会保留速度,所以中途反向时会平滑转向,而不是先停下来。在 Hook 中声明的控制器会在被替换和卸载时停止并释放,服务端渲染的标记在水合后也会继续动画。

  • 快速点击两次:使用 spring 时轨迹会弯折,使用 timing 时保持位置但开始一条新曲线。
  • 停止时值会停在原处,不会跳到结束状态。
  • 卸载、切换路由或标签页隐藏后,都不会留下多余的帧循环。

正在准备示例…

基于 Animated 构建

需要现成的组件?试试 Animated Chorus。

滚动的数字、移动的标签高亮、进度条、底部面板和动画列表,可以直接放进 React 和 React Native。这三个此刻就在本页运行。

访问 Animated Chorus

三分钟上手

安装包,让第一个值动起来,然后挑一篇与你当前任务对应的指南。

npm install @kkwaenggwari/animated

搜索

输入关键词搜索文档。