渲染目标可换:同一引擎也能驱动 canvas
引擎产出的是值,「把值写到哪」是另一回事。前面各页的值都落到 DOM (applyStyles 拼 transform);
但「时间 → 值」是纯函数,这个sink 可以随意替换:同一个主 Animation 当时钟,
onUpdate(p) 里把每个粒子的位置采样出来,改成往 <canvas> 的 2D context 上画——
渲染器换了,引擎一行没动。这也是动画即数据里 render 是纯函数那条主线的延伸。
一个主 Animation 驱动一片粒子,画到 canvas
几十个粒子从散布位置聚拢成一个环再散开 (repeatType: 'mirror' 往返)。一个 Animation 给出全局进度 p,
每个粒子的位置是它自己 起点 → 环上目标 的插值——和 DOM 版的关键帧采样完全一样,只是最后一步从写样式变成
ctx.arc。canvas 还能轻松做 DOM 难做的事:开「拖尾」不全清画布,留下运动残影。
sink = canvas 2D context;引擎与 DOM 版完全相同,只换了 onUpdate 里的最后一步。
onUpdate 里的最后一步。canvas 适合大量、
逐像素或带残影的视觉 (粒子 / 拖尾 / 程序化纹理),代价是失去 DOM 的命中测试与无障碍。声音等外部信号驱动的
canvas 可视化见声音驱动,无尽微动见噪声。
@vega/anim — 同一引擎,sink 换成 canvas