HTML5 Canvas 水波纹按钮效果需监听点击事件,在 event.offsetX/Y 位置绘制渐变半透明圆,用 requestAnimationFrame 更新半径与透明度直至消失;canvas 应绝对定位、尺寸同步按钮,水纹对象含位置、半径、透明度及衰减率,每帧清空画布并重绘活跃水纹,建议限制数量、优化样式与性能。

用 HTML5 Canvas 实现按钮点击水波纹扩散效果,核心是监听点击事件、在点击位置绘制渐变半透明圆,并用 requestAnimationFrame 持续更新半径与透明度,直到水纹消失。
获取准确点击坐标
必须使用 event.offsetX 和 event.offsetY,它们返回相对于目标元素(比如按钮内部 canvas)左上角的坐标。用 clientX/clientY 或 screenX/screenY 会因滚动、缩放或外边距导致中心偏移。
如果按钮本身是相对定位容器,建议把 canvas 设置为 position: absolute; top: 0; left: 0;,并确保 canvas 宽高与按钮完全一致(可通过 JS 动态同步)。
创建并管理水纹对象
每次点击生成一个水纹对象,包含起始位置、当前半径、当前透明度和衰减率:
立即学习“前端免费学习笔记(深入)”;
-
半径增长用固定增量(如
radius += 3),不用乘法,否则扩散会越来越快、失真 -
透明度线性衰减(如
alpha -= 0.03),配合ctx.globalAlpha = alpha控制淡出 -
超出范围即清理:当
alpha ≤ 0或radius > 最大扩散距离(如按钮宽高较大值)时,从数组中移除该水纹
动画循环与重绘逻辑
使用 requestAnimationFrame 驱动动画,每帧执行三步:
- 调用
ctx.clearRect(0, 0, canvas.width, canvas.height)清空画布(关键!不清理会残留旧水纹) - 遍历所有活跃水纹,更新其
radius和alpha,剔除已结束的 - 对每个水纹调用
ctx.beginPath() → ctx.arc(x, y, radius, 0, 2*Math.PI) → ctx.fill()绘制圆形
注意:canvas 的 globalAlpha 是全局状态,每次绘制前需单独设置,避免影响其他图形。
样式与性能优化建议
让效果更自然、不卡顿:
- 给 canvas 设置
opacity: 0.25(CSS 层级),再配合 JS 中的globalAlpha,可增强层次感 - 限制同时存在的水纹数量(如最多 6 个),防止密集点击拖慢帧率
- 水纹颜色推荐浅白或按钮主色的低饱和变体,避免遮挡文字;填充用
rgba(r,g,b,a)或直接设fillStyle+globalAlpha - 按钮需设
overflow: hidden,防止水纹圆超出边界显示锯齿



















