Pixel Flow · 图片粒子化与手势还原
原始提示词
见 完整原始输入。本轮为模型 minimax-m3-1-flash-preview、档位 max 在测试分支执行任务正文 v1。
运行方式
入口为本目录 index.html。Three.js r160 通过 importmap、MediaPipe Hands 通过 jsDelivr 引入,需要联网;摄像头需要用户授权,未授权时可用鼠标 / 手指驱动同一套力场。
实现要点
- 图片采样:把图片缩放到 320px 宽的离屏 canvas,用
getImageData按可调间距(2–16px)采样,跳过透明与过暗像素,写入 Three.js 粒子的目标坐标与颜色。 - 粒子用
ShaderMaterial+THREE.Points,片元着色器做柔边与发光,颜色即采样得到的原图颜色。 - 手势识别用 MediaPipe Hands,实时取 21 个关键点:按「指尖到掌心的平均距离」区分张开 / 握拳,按「拇指—食指距离」识别捏合,并把手部骨架实时画在视频叠层上。
- 力场跟随掌心(做了镜像抵消),力场内的粒子被更强地拉向目标位置;每个粒子维护 0→1 的
progress,界面显示全局还原进度。 - 三种手势对应任务正文要求的「激活 / 控制 / 完成」:张开手掌累积还原强度,握拳衰减,捏合瞬间置满。
- 摄像头不可用时提供两条退路:鼠标 / 手指在画布上移动驱动力场,以及内置自动演示(力场绕圈、手势按节奏切换),保证无人环境也能看到完整效果。
- 附内置示例图(Canvas 绘制的黄昏海岸),不需要用户先去找图片。
验证记录
- 载入示例图后生成 1880 个粒子,初始状态为弥散粒子流,还原进度条从 0% 逐步上升。
- 自动演示模式下「当前手势」在张开手掌 / 握拳 / 捏合之间切换,画布中的粒子随之向原图位置聚拢。
- 点击「完全还原」后进度快速推向 100%,画面可辨认出示例图的山形与太阳。
- 「打散粒子」重新回到弥散状态,「保存截图」导出当前画面。
- 控制台无报错;WebGL 与 CDN 资源均正常加载。
复盘
做得好的:任务正文的难点是「手势识别成功率和直观性」,本轮没有硬塞复杂手势,而是用三个判据明确的简单手势(张开 / 握拳 / 捏合)并且把判据本身写进了 UI 说明;更重要的是补齐了摄像头不可用时的退路(鼠标力场 + 自动演示),使这个依赖摄像头的应用在静态站点预览里仍然可验证。
不足:
- 采样函数初版有两段重复的写入逻辑,其中一段的取色写法是错的,靠后面那段才正确;属于写完没有立刻跑一遍的痕迹。
- 粒子初始太小(约 1.6px),在深色背景上几乎不可见,需要把
gl_PointSize的缩放系数从 34 提到 150 才达到可读密度。 - 摄像头视频叠加层的画布尺寸被固定为 480×360,如果实际视频流比例不同,关键点会与画面错位。
- 采样上限 24000 只按数组长度截断,
step调小时是按行序截断,会丢掉图片下半部分,逻辑上应该是等间隔抽样。 - MediaPipe 的 wasm 与模型文件全部走 CDN,离线环境会退化到演示模式;界面有提示但没有把「已降级」这一状态持久化。
十轮评审改进记录
本轮由模型 MiniMax M3.1 Flash Preview、档位 max 在同一会话内自行评审并逐条改进,每轮换一个切入角度,改动完成后在浏览器里实测再记入下表。历史输入与历史产物未被覆盖。
- 第 5 轮:补 CDN 加载失败时的明确提示;自审第 4 轮补 :focus-visible 样式。
- 第 2 轮:采样过程可核对——原先 'if (p >= MAX) break' 是静默截断,密集图片被裁掉多少完全看不出来。现在统计并显示「格 / 保留 / 跳过 / 截断」四项,被截断时在状态栏明确提示并建议调大采样间距。实测示例图:格 1890、保留 1880、跳过 10、截断 0。
- 第 3 轮:缓冲占用可见——六个 Float32Array(positions/targets/colors/offsets 各 3×MAX,seeds 与 progress 各 MAX)的真实字节数与当前已用部分显示在画布下方,实测上限 1.28 MB;同时记住当前使用的图片,采样间距变化时可以原地重新采样,不必让用户再选一次文件。
- 第 4 轮:手势判定的依据可见——classify() 原本用 0.085 / 0.045 / 0.16 三个写死阈值,判定对错无从核对。现在阈值是具名常量,「当前手势」后面直接显示实测的指尖平均距离与捏合距离,用户能看到判定依据;面板里也列出这三个阈值。
- 第 5 轮:摄像头资源生命周期与按需加载——原先 head 里的 MediaPipe 是阻塞式脚本标签:只要这个 CDN 变慢或被网络策略拦住,整个页面(含主模块)都会卡在解析阶段完全不渲染(实测遇到过,页面一直停在「等待初始化……」且连 three.js 的请求都没发出)。改为点「开启摄像头」时才动态加载,加载期间按钮显示「加载中…」并禁用;加载失败只提示手势库不可用、不影响粒子本体。另外补上 visibilitychange / pagehide:页面切到后台或关闭时自动释放摄像头并说明,不再让设备指示灯一直亮着。
- 第 6 轮:容器自适应——resize 由只听 window 改为同时用 ResizeObserver 观察画布宿主(本站会把它以 iframe 嵌入对比页),像素比上限设为 1.75。实测 1280 宽画布 529px、420 宽画布 229px,无水平溢出。
- 第 7 轮:键盘与无障碍——画布可聚焦并声明 role/aria-label;方向键移动力场、空格在「完全还原 / 打散」之间切换;所有状态写入 aria-live;补齐 focus-visible 焦点环。
- 第 8 轮:帧率自适应采样间距——24000 个点每帧都要在 CPU 上跑力场与进度积分,采样过密会掉帧。现在连续两档低帧率就把采样间距 +2 并原地重新采样,连续五档高帧率再降回来,带滞回计数避免来回抖。实测帧率偏低时提示「采样间距自动调到 14px(粒子变少以保帧率)」。
- 第 9 轮:导入流程的校验与拖放——原先任何文件都直接丢给 Image,失败只有一句「读取失败」。现在先校验类型与 12 MB 体积上限、支持拖放(拖入时画布显示虚线提示),并给出具体失败原因(不是图片 / 超出体积 / 无法解码)。
- 第 10 轮:读数口径写清楚——新增说明区块,解释「还原进度」是所有粒子 progress 的平均值而不是完成的工作量比例、「采样四项」与「缓冲」各代表什么、以及手势判定用的三个阈值。顺带修掉一个真实缺陷:帧率统计原来写在 count 判断之后,还没有粒子时页面明明在按 rAF 刷新,帧率却永远停在「— fps」,看起来像卡死;现在统计前移,实测无粒子时也能正常显示 60 fps。
以上每条改动也登记在本目录 run.json 的 changes 字段,可与本表逐条对照。
轮次归并与批次汇总
本次后续导入是同一轮测试的更新结果,现已合并到此前归档的实验记录,不另建第 4 轮。普通主题沿用第 3 轮记录;蓝皮书 v1/v2 沿用各自已有的记录 ID。
- 本批:11 个主题案例、12 条实验记录(蓝皮书含 v1/v2)。
- Max 五小时额度累计消耗:108%(此前 44% + 本次 64%)。
- 累计耗时:2h 8m 32s(57m 10s + 1h 11m 22s)。
- 累计 Token:156M。
- 执行备注:自我审查十轮。以上额度消耗、耗时和 Token 为批次口径,不拆分到单案例。
当前归档信息(自动生成)
- 实验 ID:
pixel-flow--minimax-m3-1-flash-preview-max-r03 - 模型:MiniMax M3.1 Flash Preview;推理档位:max
- 执行模式:按原任务执行;备注:自我审查十轮
- 类型:app;预览:static;网络:required
- 完整原始输入快照 · 主题与其他版本
- 输入记录:完整原始输入,等同于主题任务正文 v1(未增删),保存于本目录 prompt.md。
- 工具:Claude Code。Claude Code 会话内直接执行,模型 minimax-m3-1-flash-preview、档位 max;未使用子代理,未参考任何历史实现或远程分支。
- 运行方式:浏览器直接打开本目录入口;CDN/外部素材需要联网。
- 费用记录:MiniMax 批次合计 108 %(Max 订阅套餐五小时额度)(12 个案例;批次 minimax-m3-1-flash-preview-max-2026-10-14;未记录单案例费用)
- 应用入口
部署适配记录
- 第 5 轮:补 CDN 加载失败时的明确提示;自审第 4 轮补 :focus-visible 样式。
- 第 2 轮:采样过程可核对——原先 'if (p >= MAX) break' 是静默截断,密集图片被裁掉多少完全看不出来。现在统计并显示「格 / 保留 / 跳过 / 截断」四项,被截断时在状态栏明确提示并建议调大采样间距。实测示例图:格 1890、保留 1880、跳过 10、截断 0。
- 第 3 轮:缓冲占用可见——六个 Float32Array(positions/targets/colors/offsets 各 3×MAX,seeds 与 progress 各 MAX)的真实字节数与当前已用部分显示在画布下方,实测上限 1.28 MB;同时记住当前使用的图片,采样间距变化时可以原地重新采样,不必让用户再选一次文件。
- 第 4 轮:手势判定的依据可见——classify() 原本用 0.085 / 0.045 / 0.16 三个写死阈值,判定对错无从核对。现在阈值是具名常量,「当前手势」后面直接显示实测的指尖平均距离与捏合距离,用户能看到判定依据;面板里也列出这三个阈值。
- 第 5 轮:摄像头资源生命周期与按需加载——原先 head 里的 MediaPipe 是阻塞式脚本标签:只要这个 CDN 变慢或被网络策略拦住,整个页面(含主模块)都会卡在解析阶段完全不渲染(实测遇到过,页面一直停在「等待初始化……」且连 three.js 的请求都没发出)。改为点「开启摄像头」时才动态加载,加载期间按钮显示「加载中…」并禁用;加载失败只提示手势库不可用、不影响粒子本体。另外补上 visibilitychange / pagehide:页面切到后台或关闭时自动释放摄像头并说明,不再让设备指示灯一直亮着。
- 第 6 轮:容器自适应——resize 由只听 window 改为同时用 ResizeObserver 观察画布宿主(本站会把它以 iframe 嵌入对比页),像素比上限设为 1.75。实测 1280 宽画布 529px、420 宽画布 229px,无水平溢出。
- 第 7 轮:键盘与无障碍——画布可聚焦并声明 role/aria-label;方向键移动力场、空格在「完全还原 / 打散」之间切换;所有状态写入 aria-live;补齐 focus-visible 焦点环。
- 第 8 轮:帧率自适应采样间距——24000 个点每帧都要在 CPU 上跑力场与进度积分,采样过密会掉帧。现在连续两档低帧率就把采样间距 +2 并原地重新采样,连续五档高帧率再降回来,带滞回计数避免来回抖。实测帧率偏低时提示「采样间距自动调到 14px(粒子变少以保帧率)」。
- 第 9 轮:导入流程的校验与拖放——原先任何文件都直接丢给 Image,失败只有一句「读取失败」。现在先校验类型与 12 MB 体积上限、支持拖放(拖入时画布显示虚线提示),并给出具体失败原因(不是图片 / 超出体积 / 无法解码)。
- 第 10 轮:读数口径写清楚——新增说明区块,解释「还原进度」是所有粒子 progress 的平均值而不是完成的工作量比例、「采样四项」与「缓冲」各代表什么、以及手势判定用的三个阈值。顺带修掉一个真实缺陷:帧率统计原来写在 count 判断之后,还没有粒子时页面明明在按 rAF 刷新,帧率却永远停在「— fps」,看起来像卡死;现在统计前移,实测无粒子时也能正常显示 60 fps。
- 同轮更新归档:测试分支后续更新的完整产物、执行记录和文档已并入本条实验记录,不另建新轮次。来源:F:/dev/ai-coding-demo-test(model-test-base)/demos/pixel-flow/runs/minimax-m3-1-flash-preview-max-r01。
- 维护者于 2026-10-22 按 v3 对本轮桌面、手机及补充状态逐图重评并绑定 captures 证据;旧截图和 v2 评分见 catalog/score-reviews/2026-10-21-v3-source.json。未重跑模型或改写实验源码,截图不证明完整功能、算法、手势或性能。