本文目录导读:

纯CSS实现(适合简单波纹)
利用CSS的径向渐变和动画模拟扩散效果。
<div class="ripple"></div>
.ripple {
width: 200px;
height: 200px;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%,
transparent 0%,
rgba(100,180,255,0.3) 20%,
transparent 40%);
animation: rippleAnim 2s ease-out infinite;
}
@keyframes rippleAnim {
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(3);
opacity: 0;
}
}
特点:简单轻量,但只能模拟单圈扩散,无物理交互。
Canvas + 物理模型(逼真交互)
用Canvas绘制粒子或网格,通过波动方程模拟水面。
核心原理:
- 创建二维数组存储每个点的垂直位移
- 每帧计算相邻点之间的力(类似弹簧系统)
- 受到点击时,在点击位置施加初始位移
// 简化的波动方程算法
const canvas = document.getElementById('water');
const ctx = canvas.getContext('2d');
const width = 400, height = 400;
const spacing = 8; // 网格间距
const damping = 0.98; // 能量衰减
const cols = Math.floor(width / spacing);
const rows = Math.floor(height / spacing);
let current = new Array(cols).fill(0).map(() => new Array(rows).fill(0));
let previous = new Array(cols).fill(0).map(() => new Array(rows).fill(0));
function simulate() {
for (let i = 1; i < cols - 1; i++) {
for (let j = 1; j < rows - 1; j++) {
// 波动方程:新位移 = 2*当前 - 前一刻 + 扩散力
const force = (current[i-1][j] + current[i+1][j] +
current[i][j-1] + current[i][j+1]) * 0.4 - current[i][j];
const newVal = 2 * current[i][j] - previous[i][j] + force;
previous[i][j] = current[i][j];
current[i][j] = newVal * damping;
}
}
}
// 点击产生涟漪
canvas.addEventListener('click', (e) => {
const x = Math.floor(e.offsetX / spacing);
const y = Math.floor(e.offsetY / spacing);
current[x][y] = 20; // 初始冲击
});
特点:真实物理感,可多点交互,需优化性能。
Three.js / WebGL(3D水面)
使用三维渲染库创建带高光和法线贴图的3D水面。
步骤:
- 创建平面网格(PlaneGeometry),细分顶点
- 使用正弦波叠加算法更新顶点Y轴位置
- 添加镜面反射材质和环境贴图
// 使用Three.js模拟
const geometry = new THREE.PlaneGeometry(20, 20, 100, 100);
const material = new THREE.MeshStandardMaterial({
color: 0x0066ff,
roughness: 0.3,
metalness: 0.1,
transparent: true,
opacity: 0.8
});
const water = new THREE.Mesh(geometry, material);
// 动画循环中更新顶点
function animate() {
const vertices = water.geometry.attributes.position.array;
for (let i = 0; i < vertices.length; i += 3) {
const x = vertices[i];
const z = vertices[i + 2];
// 叠加多个正弦波
vertices[i + 1] = Math.sin(x * 0.3 + time) * 0.5
+ Math.cos(z * 0.2 + time * 2) * 0.3;
}
water.geometry.attributes.position.needsUpdate = true;
}
特点:效果华丽,适合游戏/可视化,需要GPU支持。
设计工具(非代码方案)
- After Effects:使用「波纹」效果 + 表达式控制
- Blender:添加「Ocean Modifier」+ 动画时间轴
- Shadertoy:纯着色器代码,GPU并行计算波纹
选择建议
| 需求场景 | 推荐方法 |
|---|---|
| 网页按钮点击反馈 | CSS 涟漪 |
| 自然水面仿真 | Canvas波动方程 |
| 3D游戏水面 | Three.js / Unity |
| 视频后期特效 | After Effects |
| 艺术化交互装置 | Shadertoy |
需要我帮你实现某个具体场景的代码吗?可以告诉我你的技术栈(如Vue/React/微信小程序)或效果要求。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。