Files
Genarrative/docs/technical/BABY_LOVE_DRAWING_RUNTIME_DEMO_IMPLEMENTATION_2026-05-13.md

7.2 KiB
Raw Blame History

宝贝爱画本地 Demo 运行态实现方案 2026-05-13

1. 范围

本方案落地寓教于乐独立关卡:

baby-love-drawing / 宝贝爱画

当前范围只做本地 Demo 闭环:

  1. 寓教于乐频道默认关卡卡片;
  2. 独立运行态;
  3. mocap 与开发者调试输入;
  4. Canvas 绘制和擦除;
  5. image-2 绘画魔法后端代理;
  6. localStorage 本地保存;
  7. 直达路由开关保护。

本阶段不接正式持久化表,不新增作品发布、作品号、公开详情或搜索入口。

2. 前端接入点

已新增页面阶段:

baby-love-drawing-runtime

已新增路由:

/runtime/baby-love-drawing

已新增文件:

packages/shared/src/contracts/edutainmentBabyDrawing.ts
src/services/edutainment-baby-drawing/babyDrawingClient.ts
src/components/edutainment-runtime/babyLoveDrawingModel.ts
src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.tsx
server-rs/crates/api-server/src/edutainment_baby_drawing.rs

已接入:

  1. src/components/rpg-entry/RpgEntryHomeView.tsx:寓教于乐频道默认展示宝贝爱画卡片;
  2. src/components/platform-entry/PlatformEntryFlowShellImpl.tsx:启动宝贝爱画运行态;
  3. src/components/platform-entry/platformEntryTypes.ts:扩展 SelectionStage
  4. src/routing/appPageRoutes.ts:扩展路由;
  5. src/routing/appRoutes.tsx:直达路由开关保护;
  6. src/index.css:补齐寓教于乐默认关卡卡片和宝贝爱画运行态样式;
  7. server-rs/crates/api-server/src/app.rs:挂载绘画魔法后端路由。

3. 契约

契约放在:

packages/shared/src/contracts/edutainmentBabyDrawing.ts

核心字段:

  1. templateId = "baby-love-drawing"
  2. templateName = "宝贝爱画"
  3. originalImageSrc 保存原始画布图;
  4. magicImageSrc 保存 image-2 魔法图,可为 null
  5. strokeTrace 保存画笔和橡皮轨迹;
  6. saveMode = "original-only" | "original-and-magic" 记录保存结果。

4. 运行态模型

运行态状态:

drawing
finished
magicPending
magicReady
saved

工具:

brush
eraser

颜色:

红、橙、黄、绿、青、蓝、紫

按钮悬停:

  1. 颜色选择只接受左手悬停,阈值 1500ms
  2. 按钮选择接受任一手悬停,阈值 2000ms
  3. 工具切换只接受右手在工具区域握拳。
  4. 画笔 / 橡皮光标位置只接受右手坐标;左手缺帧或左手移动不得重置、替换或驱动画笔位置。
  5. 左手需要显示独立位置指示器,帮助用户确认当前是否悬停在目标颜色上;该指示器只表达左手位置,不参与画笔 / 橡皮操作。
  6. 本地 mocap handedness 当前按摄像头视角输出,宝贝爱画运行态消费前需要换算为用户身体视角:rightHand 作为用户左手,leftHand 作为用户右手。键鼠调试输入不做该换算。
  7. 真实硬件短暂缺失某只手时,显示层保留上一帧位置约 320ms 并做轻微坐标平滑;绘制层仍只在当前帧确认用户右手存在时生效。
  8. 为避免左手抢画笔,本关不做动态 handedness 换手纠正;rightHand 永远只进入用户左手选色通道,leftHand 永远只进入用户右手画笔通道。若硬件侧 handedness 继续抖动,宁可右手画笔短暂停住,也不允许左手驱动画笔。
  9. 右手画笔通道增加单帧最大位移门禁;若 camera-left 候选点相对上一帧右手位置出现不合理大跳,判定为不可信帧,只保留上一帧光标并停止绘制。

5. Canvas 绘制

画板使用 DOM Canvas。

绘制规则:

  1. 右手在画板内且状态为 grab 时生效;
  2. 工具为 brush 时,以当前颜色绘制连续线段;
  3. 工具为 eraser 时,以 destination-out 擦除;
  4. 右手状态为 open_palm 或离开画板时结束当前笔画;
  5. 当前帧没有右手坐标时只结束当前笔画,不把左手坐标用于绘制、擦除或光标定位;
  6. 每条笔画记录工具、颜色、点位和时间。

6. 绘画魔法

前端 service

createBabyDrawingMagicImage(payload)

后端接口:

POST /api/creation/edutainment/baby-love-drawing/magic

请求体:

{
  "originalImageSrc": "data:image/png;base64,...",
  "strokeTrace": []
}

响应体:

{
  "magicImageSrc": "data:image/png;base64,...",
  "generationProvider": "vector-engine-gpt-image-2",
  "prompt": "..."
}

后端使用 VectorEngine gpt-image-2-all,把原始画布图作为参考图,生成绘本风格图片。

本地未配置 VectorEngine 或接口失败时,前端允许提示错误并保留原图保存能力;不得把失败伪装成正式魔法图。

后端接入约束:

  1. 接口需要 Bearer 鉴权;
  2. 请求体限制为 8MB
  3. originalImageSrc 只接受图片 Data URL
  4. 笔触数量上限为 600 条;
  5. 上游参考图字段使用 VectorEngine 统一契约 image
  6. 关闭入口时,creation_entry_config 路由熔断可识别 baby-love-drawing

7. 本地保存

本地保存使用:

localStorage key = genarrative.edutainmentBabyDrawing.localDrawings.v1

保存策略:

  1. 魔法生成前保存:saveMode = "original-only",只保存 originalImageSrc
  2. 未保存原图直接生成魔法后保存:saveMode = "original-and-magic",保存 originalImageSrcmagicImageSrc
  3. 保存后展示“再画一张”和“返回”。

8. 验收命令

npm run test -- src/components/edutainment-runtime/babyLoveDrawingModel.test.ts src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.test.tsx src/services/edutainment-baby-drawing/babyDrawingClient.test.ts src/routing/appRoutes.test.ts
cargo test -p api-server edutainment_baby_drawing --manifest-path server-rs/Cargo.toml
cargo test -p api-server resolves_runtime_paths_to_creation_type_ids --manifest-path server-rs/Cargo.toml
npx eslint src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.tsx src/components/edutainment-runtime/babyLoveDrawingModel.ts src/services/edutainment-baby-drawing/babyDrawingClient.ts src/routing/appRoutes.tsx --ext .ts,.tsx --max-warnings 0
npm run typecheck
npm run check:encoding

9. 已覆盖测试

  1. src/components/edutainment-runtime/babyLoveDrawingModel.test.ts:颜色 / 按钮悬停阈值、坐标归一化、笔触追加;
  2. src/components/edutainment-runtime/BabyLoveDrawingRuntimeShell.test.tsx:画板、七色、画笔 / 橡皮、完成保存、返回按钮、左手位置指示器、mocap 摄像头视角到用户身体视角换算、左手输入不替换画笔光标位置、左手短暂缺帧不闪烁、用户左手不能抢占右手画笔、camera-left 大跳不接入画笔;
  3. src/services/edutainment-baby-drawing/babyDrawingClient.test.ts:原图保存、原图加魔法图保存、后端魔法接口请求;
  4. src/routing/appRoutes.test.ts/runtime/baby-love-drawing 开启可达、关闭回落主应用;
  5. server-rs/crates/api-server/src/edutainment_baby_drawing.rs 内部单测prompt、Data URL 校验、PNG 输出和轨迹范围摘要;
  6. server-rs/crates/api-server/src/creation_entry_config.rs 路由映射单测:确认后端熔断可识别 baby-love-drawing