展厅墙上挂着一幅不断变化的作品:几团圆形的「势力场」在画面里缓慢游走,靠近时不是简单重叠,而是边缘互相牵引、拉出一段柔和的颈部,最终融成一整块;分开时又慢慢断开。整幅画用的是分层配色,从深蓝到浅绿一圈圈过渡,看起来像一张会呼吸的等高线地形图。每次刷新构成都不同。技术上是原生 Canvas 逐像素演算,没有用任何图形库。
融球是怎么算出来的
每个像素都要问一遍。画面上的每个点,把它到所有球心的「影响值」加起来,总和超过阈值就算在图形内部——融合是加法的自然结果,不是特意画出来的。
影响值随距离衰减。用的是球半径除以距离这一类反比关系,所以靠近球心影响强、远处迅速趋近于零。
配色按总和分层。不是只分内外两色,而是把总和映射到一条色带上,于是自动产生等高线一样的层次。
为什么这种画法天然很吃性能
融球的开销是「像素数乘以球数」。全屏八十万像素、六个球,就是每帧近五百万次计算,而且必须逐像素写入缓冲区。常见的优化有三条:降低采样分辨率后再放大、只在球的包围盒内计算、或者改用等值线追踪只求边界。这份源码走的是第一条——画布尺寸被限制在画框大小,不铺满全屏,所以能稳定运行。如果要把它改成整页背景,这一点必须提前考虑。
能改的地方
球的数量、半径范围、移动速度都在脚本的初始化段落,球多了融合会更复杂但也更慢。阈值决定图形的「胖瘦」,调高会让球显得更小、更难融合。配色是一条色带映射,换掉它就能从地形图风格变成霓虹、灰度或单色。展厅的墙面与画框是纯 CSS 背景,可以整段去掉只留画布。
常见问题
画面更新很慢?
先把画布尺寸调小——它对性能的影响是平方级的,比减少球数有效得多。也可以按二分之一分辨率计算再用 CSS 放大,观感损失很小。
能做成跟随鼠标的吗?
可以。把其中一个球的坐标绑到鼠标位置上即可,其余球保持自动游走,互动感会强很多。
手机上能用吗?
能,但建议为移动端进一步缩小画布并减少球数。触摸交互需要自行补一段事件绑定。
适合用在哪
设计与艺术类站点的首屏、品牌页的动态背景、加载页的等待动画,也是一份很好的「隐函数曲面」入门实现。影响函数、阈值判定与色带映射的完整代码都在脚本里,下载后可查看。