水波纹:点一下水面就漾开,压力感瞬间被揉散
2026/9/24 23:51:13 网站建设 项目流程

水波纹最解压的点在于“动一下立刻有回应”。这个网页把整块画布当成一片可触摸的水面:点一下会漾出一圈圈涟漪,按住滑动会连成一条水痕,开启雨滴模式后还有雨点随机落下、各自打出小水花。波纹强度、扩散速度和涟漪颜色都能调,右上角实时显示帧率。下面先看成品,再讲这个单文件应用是怎么用码道 WebUI 生成并部署出来的。

为什么值得看

它没有用大量 DOM 元素去做圆圈动画,而是把水面看成一块高度场:每个网格单元存一个数值,水波就是数值在相邻单元间来回扩散。这样点击、滑动、雨滴都只是在对应位置“压”一下,画面自然跟着物理规则漾开:

  • 双缓冲高度场bufAbufB来回交换,保证每一步同时更新,不串帧。
  • 点击与滑动:点按产生空心涟漪,滑动按步长插值,连成一条连续水痕。
  • 雨滴模式:开关一开,雨滴随机下落,落到水面上的位置调splash()打水花。
  • 三个可调参数:波纹强度、扩散速度、涟漪颜色都实时生效。
  • 60 fps 显示:右上角按秒统计刷新率,方便看设备跑得顺不顺。

任务描述

在码道 WebUI 输入框粘贴以下需求,回车发送:

我仍然只说清楚最终效果。它这轮的动作是: - 新建项目目录并写入单文件 `index.html`,后续调整数组大小和调色板,把性能与观感补齐。 - 提取内嵌 JavaScript 跑 `node --check` 语法检查,确认没有语法错误。 - 探测空闲端口(这轮是 3000),用 `python3 -m http.server` 起服务,`curl` 自检 HTTP 200 后给出内部预览地址。 - 最后把功能清单、文件位置和访问地址一起写回对话,预览地址就在对话末尾。

码道实际做了什么

开发一个“水波纹模拟器”网页应用:深色平静水面铺满窗口,点击或滑动水面会实时荡起涟漪,支持触摸操作;提供波纹强度、扩散速度和涟漪颜色三个调节项;内置雨滴模式,开启后雨点随机落下并溅起水花;右上角显示实时帧率,画面流畅、色彩治愈,单个 index.html 即开即玩。完成后自动部署成可访问的网页应用,并把访问地址写出来。

1. 点击和雨滴共用同一个扰动函数

点按用的是空心涟漪(能量集中在圆环上),滑动和雨滴用的是实心扰动,两种波形都从同一个splash()出来,只是幅度函数不同:

functionsplash(cx,cy,radius,strength,hollow){varx0=Math.round(cx),y0=Math.round(cy);varr2=radius*radius;for(vardy=-radius;dy<=radius;dy++){vary=y0+dy;varrow=y*W;for(vardx=-radius;dx<=radius;dx++){vard2=dx*dx+dy*dy;if(d2>r2)continue;varx=x0+dx;vardist=d2===0?0:Math.sqrt(d2);varamp;if(hollow){amp=Math.max(0,1-Math.abs(dist-radius*0.55)*2.6);}else{amp=Math.cos(dist/radius*Math.PI*0.8+0.3);if(amp<0)amp=0;}cur[row+x]=clampAdd(cur[row+x],-strength*amp,-600,600);}}}

2. 高度场用有限差分推进,一次只算一步

水波的核心是让每个点向四周扩散。step()取上下左右四个邻居的平均值乘一个扩散系数,再减去当前值;双缓冲在这里决定“新值与旧值互不干扰”:

v=(sp[i-iw]+sp[i+iw]+sp[i-1]+sp[i+1])*0.25*d-si[i];v*=damp;if(v>600)v=600;elseif(v<-600)v=-600;si[i]=v;

每一步之后交换prevcur,所以下一次迭代读到的就是刚更新完的高度场。

3. 滑动不是一条线,而是拆成很多小水花

如果拖动距离长了只打一个点,水痕会断断续续。代码按鼠标移动距离计算步数,沿路径均匀插值,把一次滑动拆成连续多个splash()

vardx=x-lastPt.x,dy=y-lastPt.y;vardist=Math.sqrt(dx*dx+dy*dy);varsteps=Math.max(1,Math.ceil(dist/3));for(vars=1;s<=steps;s++){varpx=lastPt.x+dx*s/steps;varpy=lastPt.y+dy*s/steps;splash(px,py,2+params.strength*3.5,42*params.strength,false);}

验证与踩坑

生成结束后打开对话里的内部预览地址,页面标题是「水波纹模拟器」,点击画面确实会漾开涟漪。

  • 分别截下初始平静水面和点击后的画面,两个文件内容不同:扰动强度不同,涟漪半径也不同。
  • 踩坑:物理网格的分辨率会影响画质与流畅度。生成时会根据窗口面积在 24000 到 130000 个单元之间自适应选择 CELL,屏幕越小 CELL 越小、细节越密。
  • 扩散速度调高后,fDenom = 4 / (1.35 + params.speed * 1.25)会变小,单步更新更“硬”;拉满后水波会比较躁,喜欢柔和感的话默认 60% 最舒服。

本地复现

项目是单文件index.html,没有第三方依赖。把文件保存到本地后用浏览器直接打开就能玩;如果希望通过本地 HTTP 服务访问:

cdcodearts-water-ripple python3-mhttp.server8080# 然后打开 http://127.0.0.1:8080

直接下载试玩

源码同步到公开 Demo Park 仓库:

  • Demo Park 仓库:https://atomgit.com/deli007/demo_park
  • 本案例目录:https://atomgit.com/deli007/demo_park/tree/main/codearts-water-ripple

准备环境:进入 AI 开发者空间

本文用码道 WebUI 版演示。先进入 AI 开发者空间并选择体验版,不需要本地安装:

  1. 浏览器打开 https://devstation.developer.huaweicloud.com/aidevspace?utm_source=opcsfsq&utm_medium=wbwz
  2. 弹窗「请选择要进入的版本」→ 点击体验版
  3. 首次使用跳到华为云登录页,登录一次后浏览器会话可复用
  4. 弹窗「临时凭证自动配置」→ 点击同意,沙箱自动创建

进入主界面后,等左侧菜单加载出来,找到CodeArts,点它右侧的浏览器图标,就打开了码道 WebUI 对话窗口。

开通后有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

进入 CodeArts:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz

使用码道体会

最直观的收获是「高度场」这个抽象:它把二维水面压缩成一个个数值,波纹、雨滴和渲染三层逻辑拆得很开。尤其是双缓冲,一开始没太理解为什么需要两份数组,看到step()里邻居同时读取旧值才明白:如果边算边覆盖同一个数组,波会向已经更新过的一侧倾斜。需求里没提双缓冲,但它自己按稳定做法写出来了,这种不显眼但正确的细节比把按钮调漂亮更有价值。

总结

水波纹把一个很容易想象的物理现象落到高度场迭代:点击产生扰动,有限差分负责扩散,调色板负责观感。后面可以继续加「石头落下的大水花」「背景渐变」「点击音效」或「波纹定格导出」,也可以把高度场接到其它网格类效果上,玩法空间不小。

水波纹 运行效果对照

连续截取的两个运行画面,左右分别是平静水面与点击、滑动后的涟漪状态:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询