用canvas实现雨滴敲击水面效果,核心是构建高度缓冲区模拟波传播、位移采样法渲染扭曲、结合鼠标/触控事件触发与requestanimationframe驱动动画。

用 Canvas 实现“雨滴敲击水面”的动态交互,核心是模拟水波扩散的物理效果(如衰减正弦波或简化的径向扰动),配合鼠标/触控事件触发,并用 requestAnimationFrame 持续更新与渲染。不依赖 WebGL 或第三方库,纯 HTML5 + JavaScript 即可完成。
1. 建立 Canvas 画布与基础上下文
在 HTML 中声明 canvas 元素,并获取 2D 渲染上下文:
<canvas id="waterCanvas" width="800" height="600"></canvas>
JavaScript 中初始化:
const canvas = document.getElementById('waterCanvas');
const ctx = canvas.getContext('2d');
// 推荐设为设备像素比适配,避免模糊
const dpr = window.devicePixelRatio || 1;
canvas.width = canvas.clientWidth * dpr;
canvas.height = canvas.clientHeight * dpr;
ctx.scale(dpr, dpr);2. 构建水波缓冲区(高度图)
用一维数组模拟水面高度场(如 Uint16Array),每个像素对应一个“水高”值。常见尺寸取 canvas 宽×高,但为性能可降采样(如 1/2 或 1/4 分辨率):
- 定义两个缓冲区:
currentBuffer和previousBuffer,用于迭代计算波动传播 - 每次点击位置 (x,y),在缓冲区中设置初始扰动(如 +128 的脉冲)
- 用简单差分公式模拟波传播:
next[i] = (current[i-1] + current[i+1] + current[i-width] + current[i+width]) / 2 - previous[i] - 加入阻尼衰减:乘以 0.99~0.995,防止震荡无限持续
3. 将高度图映射为视觉波纹(位移+折射)
纯 Canvas 不支持实时 fragment shader,但可用以下轻量方式近似水面扭曲效果:
- 方案A(推荐):位移采样法 —— 绘制一张静态背景图(如浅蓝渐变),再对每个像素根据周围高度差计算偏移量(dx, dy),从原图对应偏移后位置取色
- 方案B(简化):灰度扰动+高光叠加 —— 把高度图转为灰度图绘制在 canvas 上,叠加白色高光圆环模拟水花飞溅,用 globalAlpha 控制透明度体现衰减
- 关键技巧:用
ctx.getImageData()读取背景,遍历像素计算位移;用ctx.putImageData()写回(注意性能,建议限制处理区域或降采样)
4. 绑定交互与动画循环
监听用户点击/触摸,注入扰动源,并驱动主循环:
- 监听
canvas.addEventListener('click', e => {...}),用getBoundingClientRect()转换为 canvas 坐标 - 在对应缓冲区坐标处赋初值(如
currentBuffer[y * width + x] = 128) - 主循环用
requestAnimationFrame(render),每帧执行:- 交换缓冲区并计算新高度场
- 将高度场转为视觉效果(位移/灰度/高光)
- 绘制到 canvas
- 可添加鼠标移动连续滴落:监听
mousemove并节流(如 50ms),每次只在新位置触发小扰动
不复杂但容易忽略细节:缓冲区边界需做镜像或钳位处理防止越界;高度值用有符号整数更易控制衰减方向;移动端记得同时监听 touchstart 并阻止默认行为。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











