js实现波纹
实现波纹效果的 JavaScript 方法
使用 JavaScript 实现波纹效果可以通过监听点击事件动态创建波纹元素,并添加动画效果。以下是两种常见实现方式:
基础 DOM 操作实现
document.addEventListener('click', function(e) {
const ripple = document.createElement('span');
ripple.className = 'ripple';
document.body.appendChild(ripple);
ripple.style.left = `${e.clientX}px`;
ripple.style.top = `${e.clientY}px`;
ripple.style.animation = 'ripple-effect 0.6s linear';
ripple.addEventListener('animationend', () => {
ripple.remove();
});
});
对应 CSS 样式:
.ripple {
position: absolute;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
pointer-events: none;
}
@keyframes ripple-effect {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(20);
opacity: 0;
}
}
Canvas 高性能实现
对于需要大量波纹效果的场景,使用 Canvas 性能更优:
const canvas = document.createElement('canvas');
canvas.style.position = 'fixed';
canvas.style.top = '0';
canvas.style.left = '0';
canvas.style.pointerEvents = 'none';
document.body.appendChild(canvas);
const ctx = canvas.getContext('2d');
let ripples = [];
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
document.addEventListener('click', (e) => {
ripples.push({
x: e.clientX,
y: e.clientY,
radius: 0,
alpha: 1
});
});
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < ripples.length; i++) {
const ripple = ripples[i];
ctx.beginPath();
ctx.arc(ripple.x, ripple.y, ripple.radius, 0, Math.PI * 2);
ctx.strokeStyle = `rgba(255, 255, 255, ${ripple.alpha})`;
ctx.lineWidth = 2;
ctx.stroke();
ripple.radius += 3;
ripple.alpha -= 0.02;
if (ripple.alpha <= 0) {
ripples.splice(i, 1);
i--;
}
}
requestAnimationFrame(animate);
}
animate();
优化注意事项
- 性能优化:对于频繁触发的场景,建议使用对象池技术复用 DOM 元素或限制同时显示的波纹数量
- 移动端适配:需要处理 touch 事件确保移动设备正常触发
- 样式定制:可以通过 CSS 变量或参数配置波纹颜色、大小和动画时长
- 事件委托:在特定容器上实现时,应该使用事件委托而非全局监听
现代 CSS 替代方案
纯 CSS 方案可以使用 :active 伪类结合动画:

.button {
position: relative;
overflow: hidden;
}
.button:active::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: radial-gradient(circle, rgba(255,255,255,0.8) 10%, transparent 70%);
animation: ripple 0.6s linear;
}
@keyframes ripple {
from {
transform: scale(0);
opacity: 1;
}
to {
transform: scale(4);
opacity: 0;
}
}






