2026-07-05 / 6 min

LiuliX Glaze 的水墨拖尾是怎么做出来的

记录全局水墨拖尾从简单跟随到桌面和触控设备都能稳定使用的实现过程。

前端动效Canvas

LiuliX Glaze 需要一个不会压住内容、但能让页面有记忆点的背景效果。我最后选了水墨拖尾,不过真正难的不是画出一个圆形遮罩,而是让它跟手、连续、不过度消耗性能。

最初的 DOM 拖尾容易变成一串规整的圆点,元素数量多以后也不适合全屏运行。最后改为 canvas:一层提前绘制背景图片,一层只绘制水墨 mask,再通过 destination-in 让图片从墨迹里显现出来。

拖尾不是一条固定长度的线,而是一组独立的 segment。每段记录起点、终点、时间、强度和随机 seed,并按自己的生命周期扩散和淡出。durationMs 控制存活时间,maxTrailSegments 限制上限,采样间隔控制移动过快时的绘制密度。

水墨边缘由中心渐变、外圈扰动和少量挖空共同构成。参数太少会像光斑,太多又会脏,所以调参时更在意它是否干扰正文,而不是是否足够复杂。

后来触控端暴露了一个问题:横向移动有拖尾,纵向滚动只剩一个点。原因是触摸事件没有持续更新同一个接触点。现在使用 touchstart、touchmove、touchend 和 touchcancel 跟踪活动触点,桌面和手机共用同一套渲染参数;只有用户选择减少动效时才关闭效果。

性能上通过限制设备像素比、降低 mask 分辨率、控制每帧采样数量和空闲时停止绘制来保持稳定。按钮和卡片交给 Framer Motion,水墨拖尾保留在 Canvas,这样两类动效不会互相影响。

站点整体结构见 LiuliX Glaze 项目页。