mcpField
P
procedural-canvas-animation

procedural-canvas-animation

github.com/calesthio创意与媒体219114 次安装15 周前更新
代码仓库

关于 procedural-canvas-animation

procedural-canvas-animation 是用于制作程序化 2D Canvas 动画的技能,面向生成式视觉与轻量模拟的创作者。内容聚焦可复现的逐帧渲染、合成、性能、无障碍与输出检查,不涉及 3D 场景或通用前端教程。

主要功能

  1. 01粒子、轨迹与天气效果
  2. 02基于帧索引渲染
  3. 03确定性随机与状态重放
  4. 04透明度与画布合成
  5. 05性能、无障碍与输出检查

适用场景

  1. 01制作粒子或天气动画
  2. 02渲染可复现的视频帧
  3. 03生成透明叠加动画
  4. 04适配不同画幅与减少动态效果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/calesthio/generative-media-skills --skill procedural-canvas-animation

安装后在 Claude Code 中输入/procedural-canvas-animation确认已加载。

附带文件EVAL.md

详细介绍

程序化 Canvas 动画

当 2D 位图 Canvas 是程序化运动的合适绘制表面时,请使用此技能。它涵盖自定义粒子、矢量场/噪声场、轨迹、天气、纹理、生成式几何和用于渲染媒体的轻量级模拟。

它不涵盖 Three.js 场景图、WebGL/WebGPU 着色器、D3 数据语义、游戏引擎架构或通用前端 Canvas 教程。

证据立场

  • 有文档依据的事实: 来自 WHATWG、ECMAScript、p5.js、W3C 或引用的 API 文档中的行为。
  • 生产启发式做法: 在目标运行环境中测试的实用设计或优化选择。
  • 实证观察: 从实际动画、浏览器、帧输出或编码交付中测得的结果。

事实已于 2026-07-12 核实。Canvas、浏览器、p5.js、OffscreenCanvas 和编码行为可能会变化;请固定版本并记录渲染环境。

锁定 Canvas 约定

定义:

  • 位图宽度/高度、CSS/显示尺寸、宽高比变体、fps、帧范围和 alpha 要求;
  • 坐标系以及从归一化模拟空间进行的投影;
  • 随机种子、算法、初始化、参数和状态更新顺序;
  • 无状态、重播或检查点策略;
  • 色彩空间、合成模式、背景和预乘假设;
  • 源图像/字体以及 CORS/离线策略;
  • 目标运行环境/浏览器、像素密度、输出格式和编码器;
  • 减少动态效果/静态变体及闪烁策略;
  • 性能预算和代表性压力帧;
  • 所有源素材的来源和权利信息。

了解位图

有文档依据的事实: Canvas 的固有分辨率与 CSS 尺寸分开。其默认位图尺寸为 300 × 150。设置 width 或 height 会清空位图并重置上下文状态。Canvas 2D 的初始合成模式为 source-over,globalAlpha = 1,并使用预乘 alpha。使用 {alpha:false} 请求的上下文是不透明的,不适合透明内容交付。

请明确设置位图尺寸。不要用 CSS 拉伸低分辨率位图,并称其为高分辨率。对于固定的视频输出,请选择精确的像素尺寸和明确的密度;为了获得可预测的输出,p5.js 的 pixelDensity(1) 通常是合适的。

尺寸变化意味着需要重建:请重建变换、状态、缓冲区和布局,而不要假定像素或上下文设置会保留。

使用绝对帧接口

围绕以下内容进行设计:

renderFrame(frameIndex, variant, accessibilityMode)

合成时间为:

$$ t = \frac{frameIndex}{fps} $$

让 requestAnimationFrame() 不参与生产状态。有文档依据的事实: rAF 是一次性的,遵循浏览器显示调度,在隐藏上下文中可能暂停,并且不保证 60 fps。p5.js 的 frameRate() 会请求目标帧率,但不会定义离线媒体时间。

不要将 Date.now()、performance.now()、millis()、deltaTime 或可变的 frameCount 用作最终渲染的真实依据。

选择确定性策略

无状态

直接根据 (seed, objectId, frameIndex, channel) 计算每个对象。最适合周期性场、解析粒子、程序化线条和任意帧访问。

固定步长重播

重置为确定性的初始状态,并按文档记录的顺序,以精确的 $\Delta t = 1/fps$ 推进,直至所需帧。适用于时长可控的有状态雪景、群集或细胞系统。

检查点

在固定帧保存确定性状态,并从最近的较早检查点开始重播。适用于长时间运行的有状态模拟。请对检查点架构进行版本管理,并在参数/运行环境变化时拒绝使用。

依赖历史的持久缓冲区轨迹不支持随机访问。请重播历史、保存检查点,或在每一帧中绘制前 $K$ 个解析位置。

显式设置随机种子

文档事实: ECMAScript Math.random() 的算法由实现决定,且无法控制种子。p5.js randomSeed() 和 noiseSeed() 可以重现各自的序列,但无法保证不同 p5/浏览器版本生成的像素完全一致。

记录种子和生成器实现。如果需要任意访问,优先使用带键的随机值,这样渲染第 200 帧时就不会受之前帧消耗的随机值数量影响。

除非算法明确按帧设置种子,否则不要每帧重新设定种子;这样通常会冻结运动或造成相关性。

粒子、场、天气和轨迹

为每个系统定义:

  • 生成范围和生命周期;
  • 初始位置、速度、形状和颜色的分布;
  • 力和场的方程及单位;
  • 边界行为:环绕、反射、销毁、重新生成或限制;
  • 更新顺序和碰撞策略;
  • 从归一化模拟映射到各画布的方式;
  • 轨迹/历史记录策略;
  • 异常值和 NaN 的处理方式。

让模拟状态独立于像素。不同宽高比的变体应共享同一事件,同时有意调整构图、数量、密度、线宽或场偏向。

对于天气,要区分视觉上的可信度和物理模拟。除非模型和输入支持,否则不要声称具有气象学准确性。

合成与透明度

明确设置 globalCompositeOperation,并恢复上下文状态。在黑色、白色和棋盘格背景上测试 source-over、加色/变亮效果、蒙版和擦除。

透明内容的交付要求:

  • 启用上下文 alpha;
  • 不要意外填充背景;
  • 输出格式/编解码器保留 alpha;
  • 检查角落和边缘像素;
  • 检查接收端合成器中的预乘/直通 alpha 转换和光晕。

JPEG 无法保留 alpha。WebCodecs 编码器对 alpha 的处理取决于配置和编解码器;应验证功能和输出,而不要假定其支持。

外部资源与源站安全性

文档事实: 绘制未通过有效 CORS 验证的跨源媒体,可能导致画布变为非源站安全状态,使像素读取和序列化操作抛出 SecurityError。

尽可能将生产资源冻结到本地。记录 URL、许可证、哈希、CORS 策略和失败时的行为。不要等到长时间渲染后才发现画布已被污染。

p5.js 生产模式

用于确定性的离线工作:

function setup() {
  pixelDensity(1);
  createCanvas(outputWidth, outputHeight, P2D);
  noLoop();
  initialize(seed);
}

function renderFrame(frame) {
  resetOrRestore(frame);
  advanceTo(frame, 1 / fps);
  drawCurrentState();
}

这是一个架构示例。advanceTo() 必须避免推进过多步;应定义第 0 帧表示尚未执行任何步进的初始状态,还是其他状态。

避免让窗口大小、输入事件或实时设备像素密度改变最终状态。resizeCanvas() 会清除输出,并通常会触发重绘,因此应显式重建声明的变体。

性能

在将工作移至 worker 之前先进行性能分析。首先减少:

  • 算法复杂度和成对交互;
  • 重复构建路径和更改上下文状态;
  • 大型阴影/滤镜和过度绘制;
  • 像素回读和逐像素循环;
  • 帧循环中的内存分配;
  • 过多的对象数量或轨迹历史;
  • 对静态图层的冗余重绘。

文档事实: OffscreenCanvas 可以转移,也可以在 worker 中运行,但使用 worker 并不保证总渲染时间更短。它可以提升主线程的响应能力,并实现流水线分离。请确认 worker 中可用的 API,并考虑转移/序列化开销。

测量预热和冷启动时的帧耗时、p50/p95、峰值内存、输出回读和资源清理。只能对固定环境承诺可重复性;字体、抗锯齿、滤镜、浮点运算和颜色转换可能存在差异。

无障碍与安全

有意义的非文本内容需要提供等效替代内容。不能仅靠颜色传达含义;有意义的图形和控件指示器需要具备适当的对比度。

WCAG 2.2 限制每秒闪烁超过 3 次的内容,除非闪烁低于规定阈值。循环播放时,应测试渲染后的循环内容。交互界面上的符合条件的自动运动内容必须提供暂停、停止或隐藏功能。

减少动态效果时,应改变运动表现方式:使用有代表性的静态画面、减缓漂移、缩小位移、减少粒子,或改为用户控制播放。单纯降低 FPS 可能会增加卡顿,却不会减小运动幅度。

对于装饰性画布,应向辅助技术隐藏实现细节,并在承载页面中说明其含义。画布文本或描述不能替代可通过键盘操作的语义化控件。

来源与质量保证

记录种子、生成器、算法/库版本、参数、尺寸、fps、帧范围、色彩空间、密度、源素材/许可证/哈希值、运行时/浏览器以及输出哈希值。

质量保证:

  1. 直接渲染所选帧并按顺序渲染;在声明的环境/容差范围内进行比较。
  2. 测试首帧、末帧、循环边界、重生、碰撞和不同比例的帧。
  3. 检测 NaN、Infinity、位置失控和无界内存分配。
  4. 在多种背景上检查透明输出。
  5. 在完整渲染前测试 CORS/读取像素。
  6. 预热后测量帧时间的 p50/p95。
  7. 检查最终尺寸的细节、闪烁、减少动态效果的输出和替代方案。
  8. 验证输出帧数、尺寸、alpha、颜色和编码。

示例 1:透明风带叠加层

这是一个完整示例,并非强制公式。

**意图:**制作一个时长 8 秒、30 fps、1920x1080 的透明叠加层,包含 600 条发光风迹。

**方法:**使用种子 42719、归一化坐标和 36 帧解析轨迹。不可变粒子参数由键控生成器提供。每个位置都是基于绝对时间的纯周期函数。每帧 $f$ 清空为透明,并绘制从 $f-36$ 到 $f$ 的线段,其 alpha/宽度受有界的年龄值控制。基础风带使用 source-over,另行测试叠加高光的加色混合。

**质量保证:**对帧 0、1、137 和 239 比较直接渲染与顺序渲染的哈希值;检查 alpha 直方图/角落;合成到黑色/白色/棋盘格背景上;测量 p50/p95;进行闪烁测试。

**可能的故障:**可变 PRNG 消耗、{alpha:false}、背景填充、加色混合导致的值裁切,或轨迹环绕时跳变。

**变体:**9:16 比例下减少数量并让流动偏向垂直方向;减少动态效果时输出经过批准的静态帧。

示例 2:可重放的 p5.js 降雪效果

这是一个完整示例,并非强制公式。

**意图:**制作 12 秒的降雪效果,支持 9:16 和 16:9 比例,并提供减少动态效果时使用的静态输出。

**方法:**设置 pixelDensity(1)、noLoop(),并使用种子 8301 初始化随机数/噪声;使用归一化状态和固定的 $1/30$ 步长。renderFrame(n) 会重置状态,执行步骤 0..n-1,然后绘制。尺寸会影响投影和构图边距,但不会影响模拟状态。重生时仅按确定性的重放顺序消耗数值。

**质量保证:**重放第 240 帧两次;在投影前比较归一化状态;拒绝 NaN/超出边界的增长;测试裁切、性能、暂停行为、替代方案和闪烁。

可能的故障:deltaTime、millis()、frameCount 或窗口尺寸泄漏到状态中;调整尺寸后未重建;假设种子生成的结果跨版本保持稳定。

来源

已于 2026-07-12 核实:

评论

支持 Markdown