开源地址:**gitee.com/hhs_3/strok... 🎨)

一、晚上八点,女儿拿着画笔过来了
那天我在家加班,女儿跑过来问我:"爸爸,毛毛虫怎么画?"
我打开抖音给她找了个简笔画教程。视频画得挺好,但问题来了:她是跟着画的,一笔没看完,手就跟不上了。我得不停帮她暂停;一走神忘了按,就得拖回去重放。来回几次,她烦了,我也烦了。
放下手机的时候我忽然想:这不就是个产品需求吗------把"视频教学"变成"交互动画",每一笔慢慢画给孩子看,想快想慢自己调,没看清就重播。抖音解决的是"看什么",没解决"跟着画"。
我决定做个小程序,用一个 AI 编程助手结对开发。这篇文章就是这次开发的真实记录:我说了什么,它做了什么,中间翻过哪些车。
二、第一回合:我的 Lottie 方案,被 AI 否了
我平时主要做后端,前端是最近做小程序才捡起来的。但手头正好有个现成经验:我给自己的钓鱼小程序做绑钩教学动画,用的就是 Lottie------在 Lottie Creator 里把绕线动作一帧一帧做出来,导出 JSON,小程序里播放,效果很成熟。所以我的第一反应就是它:简笔画动画,Lottie 呗。
AI 的回答让我愣了一下:不用 Lottie,连 SVG 都不用。
它的理由(我决定让AI自己试试我看效果):
- 简笔画的本质是笔画路径数据 (
M/L/C贝塞尔),不是动画资源。要"一笔一笔画出来"的效果,只需要按弧长匀速插值逐段绘制路径; - 用 Lottie 意味着每幅画都要设计师在 AE 里做工程,48 幅画的成本是灾难;而路径数据代码即数据------加一幅画就是写一份坐标文件;
- 顺带的福利:首页缩略图零图片资源------用离屏 Canvas 从同一份笔画数据实时渲染出来,缓存到本地。整个小程序的图片资源接近于零。
后来的结果验证了这个判断:整包只有 472KB,48 幅画的缩略图全是"画"出来的。
它做的事 :写了一个走笔动画引擎(utils/engine.js)------每笔是贝塞尔路径,按弧长等速插值,笔画顺序就是孩子的落笔顺序;虚线提示线、三档速度、逐步重播都在这个引擎上长出来。
三、第二回合:48 幅画,全是 AI"手写"的
引擎好写,内容才是大头。我提的目标:48 幅、8 大分类、3-10 步由易到难。
AI 逐幅"手写"笔画坐标(300×300 坐标系,每幅一个 data/xxx.js)。这个过程翻了几次车,也沉淀出一套我现在很得意的造型规范:
- 相接的部件用相切,不用重叠------毛毛虫、雪人这种"一串球",圆心距=两圆半径之和。既好看,涂色时每个球又是独立色块(后来用真实像素填色测试验证过);
- 附件必须真正落在主体曲线上 ------M 变老鼠的尾巴曾经悬空,肉眼看着好好的,是像素填色测试发现填色"漏水"才暴露的;
- 数字画/字母画必须选有公开教程出处、几何自证的组合------8=两个圈=头和身体 ✓;AI 自创的画法被毙了两次,最后 M/O/S 三个字母画全部对照着 Art for Kids Hub 等公开教程重画。

它还做了两个自检工具:npm run ascii 在终端里逐笔画出字符画检查造型,npm run audit 给全部 48 幅做体检(笔画出界、圈圈互相覆盖)。48 幅画最后是逐幅人工目检过的------AI 时代反而更要有这种笨功夫。
四、第三回合:涂色页,一个 Android 大坑
涂色是孩子最喜欢的一环:点哪块、哪块变色。技术上是泛洪填充,AI 做得很快,还附赠了"示例配色"------自动识别画里最大的几个区域(连通域标记),从大到小一块一块演示配色给孩子找灵感。
真正的坑在别处:画完的庆祝动画,HTML 浮层在部分安卓机上被 canvas 盖住了 (同层渲染失效,canvas 是原生层级,fixed+z-index 都没用)。最后 AI 把庆祝画面整个画进 canvas 内部------彩纸、文字、按钮全是 canvas 绘制的,顺便解决了一切层级问题。
还有个更隐蔽的:填色页铺白底时,渲染函数开头的 clearRect 会把外部预铺的底擦成透明,而透明像素会被填色算法当成墨线------整张画布都点不动。这种 bug 真机上肉眼根本看不出原因,最后是靠像素级测试定位的。
五、第四回合:语音的三次反转
这是全程最折腾的一段,像坐过山车:
AI 先接入了微信官方「同声传译」插件的 TTS------免费、免后台,双语播报("我们来画小狗狗,英文是,Puppy")。我以为这下能收工了。
然后媳妇给我打了差评:语速太快,而且是男声。
我让 AI 去查证。结论很干脆:官方接口只有 lang 和 content 两个参数,没有音色、没有语速,换不了 。网上流传的 voiceType 参数是野参数,传了会被忽略(AI 留了个试验开关让我真机死心)。它给的补救是播放侧变速:InnerAudioContext.playbackRate = 0.8,慢是慢了,声音还是那个声音。
最后我拍板换方案------本地预生成。用微软晓晓(温柔女声、慢速 12%)把全部口播文本离线合成 319 条 mp3,传七牛云,小程序下载后缓存本地。这一段 AI 的工程设计我觉得是整个项目的亮点:
- 内容寻址 :音频文件名 = 口播文本的 SHA-1(纯 JS 实现两端共用)。文案改一个字,哈希就变,旧音频自动失效,下载 404 自动回落同声传译------任何音频缺失的最坏结果就是回到现状,永不出错;
- 中间还踩了个 argparse 的坑:
--rate -12%拆开传参数会被当成新选项,319 条全失败;改成--rate=-12%等号连写一次全过。这种坑不踩过真不知道。
现在孩子听到的就是:温柔女声、慢速、每步讲解、画完夸奖,双引擎互为兜底。
六、第五回合:让它能自己传播
我做这个小程序没预算投广告,传播只能靠家长晒娃。所以 AI 做了作品分享卡 :孩子涂完色点保存,生成的不是裸图,而是一张"作品卡"------孩子的画 + 品牌栏 + 小程序码,家长发朋友圈,别人长按就能进小程序。
这个小功能也翻过车:布局是纯函数、有无头测试盯着,结果一句 slogan 按 384px 宽度实测超出可用区域 22px,被测试当场拦下。要是没有这层测试,就是上线后某个机型上文字压二维码的脏活。
转发分享也都配了:三个页面点开直达对应画的教学页,分享卡还兼做转发封面。
七、一些我坚持的工程纪律(AI 时代的笨功夫)
回看这几天,AI 把"写代码"这个环节压缩得极快,但有几件事我坚持让它做,事后证明都是值的:
- 无头测试全绿才许动 :动画引擎、语音状态机、填色算法、分享卡布局、内容哈希------71 项断言,
npm test一把跑完。测试拦下过 slogan 超宽、拦下过 sha1 两端不一致的风险; - 真实渲染验收:分享卡是 canvas 画的,AI 起了个本地服务在浏览器里实景渲染验收,而不是只信布局测试;
- 造型逐幅人工目检:48 幅,一幅一幅看过来;
- 先查证再动嘴:同声传译能不能换声音、虚拟支付政策、流量主门槛......全部先查官方文档再下结论,省掉了大量"我以为"。
八、写在最后
现在的状态:小程序在备案中,软著申请已提交,开发时间基本上周天一天就把整体全部写出来了,周一下班后,调整了语音为本地生成,代码 MIT 开源:
这次开发里,AI 写了几乎全部代码,但关键的决策都是人做的:不要 Lottie 是我追问后被说服的;男声不满意是媳妇提出来的;48 幅要逐幅目检是我要求的;"先验证孩子画不画得完、再谈推广"也是我给自己泼的冷水。写代码的成本降到几乎为零之后,剩下的事全是判断。
技术栈:uni-app(Vue 3)+ Canvas 2D,微信小程序端。欢迎 Fork、提 Issue,加一幅新画尤其欢迎------src/data/ 里写一份坐标文件就行,缩略图、口播、涂色全都自动出来。