SuperAPI AI 工具集

skia-canvas-rendering

设计与创作

查看项目

更新于 10-18 18:02

技能介绍

用途

该技能用于在 React Native 应用中构建手绘 Skia 画布,例如进度网格、图表、编辑器、游戏棋盘等。每个手绘表面都是一个 Skia <Canvas>,其中唯一的 <Picture> 在 UI 线程上由该表面的纯 draw() 录制,由自停止的场景时钟播放时间线来驱动动画,并通过单元测试、绘制调用预算和像素黄金测试来验证。

主要能力

技能提供画布工具包(src/canvas/)、一个模板表面和两个检查脚本。它要求:draw(canvas, frame) 是 'worklet' 文件中的纯 worklet,只读取 frame,只导入 Skia 类型,不分配 Skia 对象,不读时钟或随机源。不透明画布先绘制每个像素(canvas.drawColor)。每次提交变更推送一个场景共享值(makeScene(seq, view, tracks), startAt: NOT_STARTED),帧运行器在第一帧盖上 startAt = info.timestamp,不使用 timeSinceFirstFrame。帧回调只在有运动时运行,且函数体只调用 runSceneFrame,不使用 Skia 的 useClock() 或 withRepeat(…, -1)。先持久化再动画,新变更快进,只有挂载期间提交的变更才动画。buildTimeline(events, motion) 是纯函数,尊重 'reduced'(一半时长、无粒子/抖动/过冲)。非补间效果层仅在其轨道播放时绘制。选择与提示作为 UI 状态由屏幕传入 highlight,拖拽预览精确落在悬停单元格。布局是实际画布尺寸的纯 worklet,由绘制和命中测试共享。不做像素翻转,RTL 通过布局镜像位置。数字在 toView() 中本地化并用 drawText 绘制(小形状中用 drawFittedText),单词和复杂脚本使用缓存的 Skia Paragraph,宽度来自字形宽度,字体通过一个 useFonts 提供者从捆绑 TTF 获取。路径用 Skia.PathBuilder 以单位大小构建一次,再用 canvas.translate/scale 放置。调色板是语义令牌集合(light、dark 等),附带 canvas-contrast.json 声明颜色配对,每对满足 WCAG 2.2 AA。表面不能运行时停止一切,时钟只通过 scene-clock-state 切换。iOS 保持 CADisableMinimumFrameDurationOnPhone 为 true。每个画布是一个可访问图像,带 accessibilityRole="image" 和翻译后的 accessibilityLabel,纯装饰画布显式退出。每个表面通过三种方式证明:纯单元测试、绘制调用预算测试(最忙帧不超过 1,000 次调用)和 3 种尺寸 × 时刻 0、0.5、1 的像素黄金测试(0.1% 容差)。服务器数据通过 useCommittedChange(data, diffEvents) 转为变更。

使用方式

工作流程包括:决定并分类(读 references/architecture.md);从模板复制工具包并在 contracts/ 填写第一个表面,运行 node ${CLAUDE_SKILL_DIR}/scripts/check-canvas-files.mjs . 列出要复制的文件;写表面前阅读 references/timeline-and-clock.md、references/drawing.md、references/api-traps.md;从模板复制表面到 src/features/<feature>/canvas/,替换占位符;按测试优先顺序构建:调色板与 canvas-contrast.json → canvas-model.ts → to-view.ts → build-timeline.ts 及其测试 → layout-<id>.ts 及其测试 → draw-<id>.ts 及其测试 → <id>-surface.ts;每步后运行 npx jest src/features/<feature>/canvas --ci --selectProjects unit;接线屏幕;运行 eslint、prettier、typecheck;创建像素黄金测试并打开检查全部 PNG;运行两个检查脚本直到打印 RESULT: PASS;在 Release 构建中于命名 iOS 模拟器和 Android 模拟器查看截图,覆盖每种语言(至少一个 RTL),再由开发者在真机上确认 120 Hz 和卡顿率。

适用场景

该技能适用于绘制图表、网格或棋盘等需要手绘 Skia 表面的 React Native 场景。表面如果接受触摸,还需在同一会话中使用 canvas-gestures-and-hit-testing。游戏棋盘还需阅读 references/game-boards.md。

限制

资料未说明该技能的收费、价格、支持平台或具体性能效果,这些信息暂未提供。完成定义要求工具包位于 src/canvas/ 并含测试,每个表面文件夹有调色板、to-view.ts、build-timeline.ts、layout-<id>.ts、draw-<id>.ts、<id>-surface.ts 且测试通过,时刻 0 不绘制稍后开始的效果,绘制测试断言首次调用是 drawColor(或声明不透明为 false 且每个渲染元素传递 isOpaque={false}),服务器数据表面有 diff-events.ts 及其测试,最忙帧在预算内,九个黄金 PNG 存在并已查看,typecheck 和 eslint 通过,无 PLACEHOLDER 残留,减少动态效果移除粒子/抖动/过冲,每个画布可访问,表面仅在应用活跃、屏幕聚焦且无遮挡时运行,两个检查脚本打印 RESULT: PASS 且不打印 SKIP 行。反模式包括使用 timeSinceFirstFrame 或 JS 上存储的 t0 动画、在 draw() 或模块导入时创建 Skia 对象、将每帧数据放入 React state 或每帧重新渲染标签、视图中只存变更并在 draw() 中读旧状态、帧回调在空闲表面/未聚焦屏幕/遮挡下继续运行、在 JS 线程用 scene.get().seq 守卫 onDone 等。