Canvas动态水波纹特效通过getImageData/putImageData实时扰动像素,结合二维缓冲区迭代计算振幅传播,用鼠标交互触发扰动,并以requestAnimationFrame优化渲染性能。

网页端用 Canvas 实现图片的动态水波纹像素特效,核心是利用 getImageData 和 putImageData 对图像像素做实时扰动,再结合波动物理模型(如水波扩散算法)逐帧更新。它不是简单画个正弦波,而是模拟真实水面受激后能量传播的过程。
准备带背景图的 Canvas 画布
先在 HTML 中声明一个 canvas,并确保尺寸设在标签属性里,而不是靠 CSS 拉伸:
-
必须设置
width和height属性值,比如<canvas id="waterCanvas" width="1024" height="600"></canvas>,否则像素会模糊 - 用 JavaScript 加载背景图,等图片
onload后再开始绘制,避免空白或报错 - 建议预加载一张高清图作为底图(如水面、城市倒影等),提升视觉质感
实现像素级水波扩散逻辑
水波效果本质是二维网格上的振幅传播。常用方法是维护两个缓冲区(buffer1 和 buffer2),按规则迭代计算每个点的新振幅:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 点击位置设为初始扰动(比如 buffer1[x][y] = 512),其他点归零
- 每一帧遍历所有像素,用公式
next = (top + bottom + left + right) / 2 - current - current >> 5更新振幅 - 振幅决定像素偏移量:水平偏移 ≈ 振幅 × sin(时间),垂直偏移 ≈ 振幅 × cos(时间)
- 用偏移后的坐标从原图取色,写入新图像数据
实时渲染与性能优化
动画必须用 requestAnimationFrame 驱动,不能用 setTimeout 或 setInterval:
- 每次渲染前调用
ctx.getImageData(0, 0, width, height)获取原始像素 - 根据 buffer 数据生成偏移映射,构造新
Uint8ClampedArray填充像素 - 用
ctx.putImageData()写回画布,注意该操作较重,避免频繁调用 - 可对非关键区域降采样(如每 2×2 像素只算一次偏移),或限制最大扰动半径来提速
添加交互与视觉增强
让效果更自然,可叠加几层处理:
- 鼠标悬停时自动触发微扰动(不点击也泛起涟漪),用
mousemove节流(如 50ms 一次) - 在波纹边缘加轻微透明度衰减,模拟水波消散感
- 叠加一层半透明渐变遮罩,强化光影流动,避免纯像素偏移显得生硬
- 若需倒影效果,可先翻转图像再应用相同水波逻辑,最后合成

















