把 Windows 桌面变成一池会游动的小鱼:青池交互动态壁纸
普通壁纸只能看,视频壁纸虽然会动,播放内容却是固定的。我想做一个能回应鼠标的小池塘:平时小鱼在水中自由游动,偶尔聚成鱼群;轻点水面,就能看见波纹扩散,鱼儿逐渐游向投喂点。
这个项目叫「青池」,目前的版本是 v5。它使用 HTML、JavaScript 和 Canvas 绘制,再通过 Lively Wallpaper 放到 Windows 桌面背景层。
没有后台服务,不需要 API,也不需要登录账号,导入后可以离线运行。
lively wallpaper 下载地址:
鱼塘项目地址:https://download.csdn.net/download/u014541881/93646716
一、先看实际效果

场景由青绿色池水、石质池底、荷叶、荷花和小鱼组成。鱼的体积刻意做得较小,给水面留下足够空间,也方便查看桌面图标。
自由游动与偶尔结群
gif图,所以有丢帧和加速,实际很自然柔和。

鱼儿不是沿着固定轨道播放动画。每条鱼都有自己的位置、方向、速度和摆尾节奏,部分鱼独游,部分鱼结群,过一段时间会自然切换。
点击水面投喂

点击后,水面出现饲料点和扩散波纹。鱼儿逐渐转向目标,加减速和转弯都有过渡,不会直接跳到鼠标位置。
以上gif,并非实际效果图。GIF 为方便文章展示,降低了分辨率和帧率;壁纸默认目标帧率为 30 FPS。
二、功能介绍
| 功能 | 当前实现 |
|---|---|
| 多彩小鱼 | 默认 64 条,共六款鱼形与配色 |
| 自由游动 | 每条鱼拥有独立方向、速度和漫游目标 |
| 偶尔结群 | 独游与结群自然切换,可关闭结群 |
| 点击投喂 | 轻点水面,鱼儿逐渐靠近投喂点 |
| 水面波纹 | 包含亮边、暗边和局部折射 |
| 水下质感 | 鱼身随深度染上水色,降低对比度并轻微柔化 |
| 身体动作 | 身体到尾部连续弯曲,胸鳍轻微张合 |
| 场景层次 | 鱼在荷叶下方游动,不同深度有大小和阴影差异 |
| 可调设置 | 鱼数、体型、游速、帧率、结群、水波和标题 |
| 离线使用 | 所有素材随壁纸包提供 |
最终版本没有声音,也没有额外叠加的动态光影线条。池底图片本身的自然光照保留,让画面更干净。
三、安装与使用
1. 安装 Lively Wallpaper
Lively Wallpaper 是免费的开源动态壁纸软件,可以从官方网站进入 Microsoft Store 安装,也可以选择官网提供的 Windows 安装程序。
Lively 负责将网页作为桌面壁纸运行,青池项目负责池塘画面与交互。
2. 导入壁纸
配套文件名:
text
青池-自由小鱼群-v5.zip
安装步骤:
- 打开 Lively Wallpaper。
- 将 ZIP 文件直接拖入壁纸库,无需提前解压。
- 找到「青池 · 自由小鱼群 v5」,应用到需要的显示器。
- 显示桌面,左键轻点水面,检查是否出现波纹和投喂点。
如果拖入没有识别,可以通过"添加壁纸"入口选择文件。
如果使用源码目录,则选择 index.html,并完整保留旁边的脚本、配置文件和 assets 文件夹。
3. 调整参数
在 Lively 壁纸库中右键壁纸,打开"自定义"。
| 参数 | 调整范围 | 默认值 |
|---|---|---|
| 小鱼数量 | 4~120 条 | 64 条 |
| 小鱼体型 | 50%~150% | 100% |
| 游动速度 | 30%~180% | 100% |
| 目标帧率 | 20~60 FPS | 30 FPS |
| 允许偶尔结群 | 独游与结群交替,关闭后全部自由游动 | 开启 |
| 点击水波 | 显示或隐藏波纹,投喂仍可进行 | 开启 |
| 标题与提示 | 显示或隐藏右下角文字 | 开启 |
配置面板由 LivelyProperties.json 定义,网页通过 livelyPropertyListener 接收设置变化。这是 Lively 官方支持的网页配置方式,具体可参考官方交互文档。
默认 64 条鱼、1080p 的本机浏览器检查约为 29~30 FPS。实际桌面表现还与显示分辨率、电脑负载和 Lively 设置有关。
4. 操作说明
**左键轻点水面:**产生投喂点,持续约 10 秒。再次点击可以改变鱼儿关注的位置。
**拖动或右键:**不会投喂。按下与松开位置相距不到 8 像素,才会被判断为轻点。
**关闭结群:**鱼儿会逐渐恢复自由游动,不会突然改变方向或瞬间散开。
5. 常见问题
点击没有反应怎么办?
先确认正在显示桌面,再检查 Lively 的壁纸鼠标交互设置。本项目不需要键盘输入。
会不会挡住桌面图标?
桌面背景层级和输入转发由 Lively 管理。项目不安装系统鼠标钩子,也不创建覆盖软件窗口的交互层。
图标点击是否同时转发给壁纸,取决于 Lively 的版本与设置;网页无法读取外部桌面图标的位置。
画面卡顿怎么办?
先减少鱼数,再降低目标帧率。高分辨率、多显示器和大量鱼同时显示,都会增加绘制负担。
声音在哪里开启?
v5 已移除声音,没有音量设置。
四、图片素材如何获取与处理?
池底、鱼、荷花和荷叶使用 AI 生成素材,再将动画交给程序实时驱动。
图片本身没有动画,也不是把一段视频放到桌面上。
素材分三类制作:
- **池底:**俯视的青绿池水、石块与自然光照,不包含鱼和荷花。
- **鱼:**透明背景鱼形图集,包括红白、三色、黄金锦鲤,以及银色、橙色和蓝银色小鱼造型。
- **荷花与荷叶:**独立透明素材,与鱼分层绘制,形成遮挡关系。
鱼和植物图集按透明通道的连通区域切成独立 PNG,保留透明度;部分素材再等比缩小,避免屏幕上只有几十像素的小鱼加载过大的源图。
制作鱼素材时,提示词需要明确:
严格俯视、完整身体、头朝右、尾朝左、各对象互不重叠、真正透明背景、不要水面和投影。
这些约束能减少侧面鱼、带背景图片或对象重叠等问题。
银色、蓝银色等鱼形属于艺术化生成造型,不作为准确的物种识别图片。素材说明和提示词记录保存在 assets/ASSETS.md。
五、技术原理
1. Canvas 分层绘制
项目主要文件如下:
text
index.html 网页入口与标题提示
pond.js 绘制、鱼群行为、鼠标交互和暂停处理
LivelyInfo.json 壁纸包信息与入口
LivelyProperties.json 自定义参数
thumbnail.png 壁纸库缩略图
assets/ 池底、鱼、荷花与荷叶素材
项目采用 Canvas 2D 分层绘制,通过景深和材质变形表现立体感,没有使用完整三维鱼模型或物理水体。
绘制顺序大致为:
text
池底
↓
鱼的阴影
↓
按深度排列的鱼
↓
水色覆盖
↓
点击波纹与饲料
↓
荷叶、荷花
荷叶最后绘制,因此鱼儿游到荷叶下面时,会自然被遮挡。
2. 一张鱼图如何摆尾?
如果只移动图片的位置,再旋转整张图片,鱼看起来会像一块僵硬的纸片。
青池将鱼图沿身体方向分成 20 个窄条,为不同位置计算中心线偏移。偏移随时间变化,并向尾部逐渐增强,再让每个窄条沿中心线切线方向旋转,组合成连续弯曲的鱼身。
中心线的核心代码如下:
javascript
function spine(f, t) {
const amp = (0.9 + f.v / 38) * f.size * 0.115;
return Math.sin(f.tail - t * 4.4)
* amp * (0.08 + 0.92 * t * t)
- f.turn * f.size * 0.16 * t * t;
}
其中:
t表示从头部附近到尾部的位置。f.tail表示摆尾相位。f.v控制速度对摆幅的影响。f.turn增加转向时持续的身体弯曲。
每条鱼的初始相位不同,因此不会同步摆尾。身体变形、平滑转向和速度变化组合起来,游动就比整张图片平移自然得多。
3. 自由游动与群游如何切换?
每条鱼都有独立的行为计时器:
- 独游阶段约 14~30 秒。
- 结群阶段约 7~15 秒。
- 首次切换随机发生在 8~24 秒。
独游时,鱼受到缓慢变化的漫游目标影响;结群时,再加入同群鱼的位置与方向影响。
近距离分离力帮助它们保持间距,边界引导让鱼转回水面内。切换时平滑调整行为权重,避免突然转向。
投喂点出现后,靠近食物成为主要目标,鱼儿根据距离调整速度。这是一种启发式群游行为,并非精确的生物运动模拟。
4. 如何让鱼看起来在水里?
直接把鲜亮鱼图画在池底上,很容易产生"鱼浮在水面"的感觉。
项目提前生成不同深度的水色素材:叠加青绿水色、压低对比度,并轻微柔化。绘制时再根据深度改变大小、透明度和阴影距离。
这样鱼的颜色会受到池水影响,又能保留不同鱼形的特征。提前处理素材也减少了逐帧滤镜的开销。
5. 波纹与性能处理
点击波纹由逐渐扩大的椭圆环构成,配合亮边、暗边和环形区域内的轻微画面偏移,表现波峰与折射。
动画由 requestAnimationFrame 调度,模拟按目标帧率步进。池底提前缓存,渲染像素比上限设为 1.5。
收到 Lively 暂停回调或页面不可见时,项目停止模拟,减少不必要的后台绘制,让这个小池塘更适合长期放在桌面上。