`acc` 节点:React Native Reanimated v1 声明式动画中的累积求和原语
发布时间:2026/9/15 13:20:06 作者:尧图编辑部 阅读量:1,286

acc节点React Native Reanimated v1 声明式动画中的累积求和原语【免费下载链接】react-native-reanimatedReact Natives Animated library reimplemented项目地址: https://gitcode.com/GitHub_Trending/re/react-native-reanimatedacc(node)是 React Native Reanimated v1 节点体系中的一个基础原语它记录并返回给定节点的历史求值总和用于把离散的动画信号累积成持续变化的数值。本文以版本化文档 nodes/acc.md 为核心结合 v1 声明式 API 的节点模型clock.md、declarative.md 等与单帧至多求值一次的架构算法讲清acc的语义、适用场景、组合用法与注意事项帮助你写出可在 UI 线程运行的积分器式动画逻辑。一、acc的语义把每次求值累加起来acc节点的定义非常简洁接口签名如下完整原文见 acc.mdacc(node);其行为可以概括为返回给定节点的累积值accumulated value。该节点内部维护一个和sum记录给定节点所有历史求值的总和每次它被求值时都会把当前时刻node的值累加到该总和上并返回累加后的结果。用伪代码可以更直观地表达这一语义// acc 节点内部概念示意 accState.sum 0; function evaluateAcc(node) { accState.sum accState.sum evaluate(node); // 当前求值 历史总和 return accState.sum; }换句话说acc是一个离散时间下的累加器它不关心节点当前的瞬时值而关心节点自挂载以来所有求值结果的累积量。这与同样记录历史差值的diff节点返回上一次求值与当前求值之差互为镜像——diff做差分acc做积分。acc的输入node可以是任意动画节点如Value、add、multiply、cond的返回值等这也体现了 v1 节点体系节点可任意组合的设计见 declarative.md 中不再操作动画对象而是操作执行单步动画的节点这一核心思想。二、为什么acc是确定性的v1 的单帧至多求值一次算法要真正理解acc的累积语义必须了解 v1 架构的一条关键规则。在 about.md 的 At most once evaluation (the algorithm) 一节中明确指出与原始Animated库中每个节点在一帧内可能被求值多次不同Reanimated v1 限制每个节点在一帧内至多被求值一次。当节点被求值后其值会被缓存若同一帧内其他节点需要该节点的输出则直接返回缓存值而不重新求值。这条规则对acc至关重要累积口径唯一由于一帧内acc至多累加一次累积结果不会因同一帧内多次引用acc而重复叠加。结果可预测acc的返回值只取决于从挂载到现在一共被求值了多少帧以及每帧输入节点的值与求值顺序、引用次数无关便于在声明式表达式中反复使用。该算法的完整求值流程来自 about.md为先分析本帧事件流 → 更新运行中的 clock 节点 → 从被更新的节点出发遍历节点树 → 找到连接到视图属性的最终节点并递归求值 → 若仍有运行中的时钟则排队下一帧。acc正是这一遍历过程中被按帧累积的普通节点之一。三、与diff的组合从差值到累积的完整信号处理acc常与diff配合使用。diff的语义是diff(node);返回节点上一次求值的值与当前求值的差首次求值时直接返回节点当前值。可见diff与acc是时间维度上的一对逆操作diff提取增量一阶差分适合检测变化、求变化率acc累积增量求和/积分适合把增量还原为总量。一个典型的物理模拟思路是用diff求出位置节点的位移增量再通过acc累加出总路程或者反过来把acc(速度增量)当作位移。二者都依赖 about.md 中描述的缓存值 至多一次求值机制来保证上一次求值与本次求值之间有确定的一帧间隔。四、实战用法在声明式节点图中做积分acc的典型价值在于用纯声明式的节点组合实现本需要用命令式代码维护的累加状态。在 v1 中节点可挂在Animated.View的样式属性上也可放在Animated.Code/useCode中随输入节点变化而执行。4.1 挂在样式上累积手势或传感器信号import Animated from react-native-reanimated; const { Value, acc, multiply, cond, eq, set } Animated; // 每一帧把 gestureDelta例如手势位移的增量信号累加进 total const gestureDelta new Value(0); const total acc(gestureDelta); // 直接映射到视图变换 // Animated.View style{{ transform: [{ translateX: total }] }} /这里total每帧返回gestureDelta的历史累积值等价于一个运行在 UI 线程的积分器无需在 JS 侧手动setValue维护和。4.2 与setcond配合可控清零的累加器acc的累积是持续性的。若需要重置累积可用set与cond在节点图中实现条件清零——set会把源节点的值赋给Animated.Valuecond提供条件分支求值两者详细语义见 set.md 与 cond.md。const { Value, acc, cond, eq, set, block } Animated; const input new Value(1); // 每帧输入信号 const resetFlag new Value(0); // 置 1 时清零 const total acc(input); // 在 useCode 或 Animated.Code 中清零时把 total 对应的 Value 复位 // set(totalSource, cond(eq(resetFlag, 1), 0, total))结合 block按顺序求值数组中的节点并返回最后一个节点的值可以构造先判断是否需要清零、再输出累积结果的复合节点块。4.3 在Animated.Code/useCode中驱动副作用acc不一定非要绑定到视图属性。v1 提供的Animated.Code组件与useCode钩子允许当输入节点更新时执行一段节点逻辑import Animated from react-native-reanimated; Animated.useCode( () set(someValue, acc(perFrameDelta)), [perFrameDelta] );useCode的第一个参数是返回节点或节点数组数组会被放进block的工厂函数第二个参数是依赖数组依赖变化时节点会重新创建这正好适合需要随输入信号重建/重置累加器的场景。注意useCode仅在支持 Hooks 的 React Native≥0.59上生效。五、使用acc的注意事项累积是无界的acc从节点挂载起一直累加数值会单调增长或按输入符号波动不会自动归零。若用于translateX等样式属性需自行设计清零逻辑避免数值溢出或视图飞出屏幕。一帧至多一次求值的隐含约束acc的确定性依赖 v1 的节点缓存 至多一次求值算法见 about.md。同一帧内多次引用acc返回的是同一次累加结果而不是重复叠加使用时不必担心被引用多次会累加多次。首次求值语义与diff类似acc在首次求值时会以当前输入节点的值作为起点即总和从首个输入值开始因此挂载时刻的输入值也会计入累积设计初始条件时需留意。它属于 v1 声明式节点 APIacc是 v1 节点体系nodes/目录下 50 余个节点之一的组成部分其定位是与add、diff、set、cond、block等基础节点组合出复杂的动画逻辑当前仓库的源码与 v3/v4 现代 API 已采用 Hook 化的useSharedValue等新模型见 packages/react-native-reanimated/src 目录acc作为历史版本 API 记录在 versioned_docs/version-1.x 中。六、延伸阅读节点体系总览nodes/add.md、nodes/diff.md、nodes/block.md、nodes/set.md、nodes/cond.md值容器与时钟value.md、clock.md声明式动画与副作用节点declarative.md、code.md架构背景单帧至多求值一次算法与设计动机见 about.md【免费下载链接】react-native-reanimatedReact Natives Animated library reimplemented项目地址: https://gitcode.com/GitHub_Trending/re/react-native-reanimated创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考