抖动背后的技术:线条为什么会自动"活"起来
用户视角:画一笔,它就动了
你画一条线,松手——这条线开始抖动。没有你做任何额外操作,它自己就在动。这是怎么做到的?
核心思路
WigglyPaint 的抖动引擎可以粗略理解为:
- 你画的时候,App 记录下这条笔画的轨迹(一串坐标点)
- 这条线从落笔的瞬间就被赋予一个抖动函数——告诉引擎每个坐标点该怎么随时间偏移
- 渲染引擎(Metal 在 iOS 上,Canvas 在网页上)每帧重新绘制,把每个点按抖动函数算出来的新位置画出来
- 这就形成了"线条在动"的视觉效果
每支画笔的抖动函数不同
这就是为什么 Pencil 画出来是高频小抖、Marker 是低频大摆、Brush 是整体呼吸——每支画笔有不同的抖动参数:
- 频率:每秒抖动多少次
- 幅度:每个点偏移多少像素
- 相位:不同点的抖动起始时间差(让线条显得"有波浪"而不是整体平移)
- 模式:随机抖动 / 正弦波 / 噪声曲线
不需要时间轴
这是 WigglyPaint 和传统动画工具最大的架构差异。传统工具(Piskel、Photoshop)的做法是:
- 你画第 1 帧
- 复制 → 画第 2 帧(每个点手动挪一下)
- 再复制 → 画第 3 帧
- 导出时把所有帧按顺序拼接成 GIF
WigglyPaint 的做法完全跳过了手动逐帧——由引擎实时生成每一帧。你只画一次,抖动函数负责无穷帧。
性能怎么保证
这也是为什么 iOS 版用 Metal 渲染——Metal 能在 GPU 上高效地每帧重绘所有抖动线条。在 120Hz ProMotion 的 iPad Pro 上,每秒要算 120 帧,每帧可能有上百条抖动线条。如果用 CPU 做早卡爆了。
SwiftUI + Metal 的原生组合在这里起了关键作用。