dsh-splash-fish
DeepSeek Harness 的开屏动画插件。把自己的插画放进去,启动时从黑场里显影,带一点深度视差,然后淡出进工作区。

preview/splash-25d-preview.mp4完整启动动画,5.07 秒preview/hair_wave_preview.mp4上一版的头发位移层,3.6 秒,留着对照preview.html用浏览器直接打开就能看,加?t=2600可以冻在某一帧
这是一个纯客户端插件,挂在 shell.overlay 槽位上。每次页面加载只播一次,播完自己卸载。
安装
让别人装:把下面这段发给 Agent。
帮我安装这个 DeepSeek Harness 插件:https://github.com/Streamfish-lab/dsh-splash-fish
1. 克隆到 %USERPROFILE%\.dsh\bundles\dsh-splash-fish
(目录要长期留着,插件是 link 引用的,移走就失效)
2. 改 %USERPROFILE%\.dsh\profiles\desktop\package.json:
dependencies 里加 "dsh-splash-fish": "link:<上一步的路径>"
dsh.profile.bundles 数组里加 "dsh-splash-fish"
3. 在 profiles\desktop\node_modules\ 下建一个指向它的目录链接
4. 告诉我需要重启应用
细节写在 AGENTS.md 里,Agent 会自己看。
自己装:设置 → 插件 → 添加插件,填仓库目录的绝对路径(要指到有 package.json 那一层),装完重启。
命令行(Web 版或者装了 dsh CLI):
dsh plugin --profile web add /你的绝对路径/dsh-splash-fish
桌面版不要用命令行,desktop 这个 profile 是 Electron 独占的,dsh plugin 会直接拒绝。
为什么做成视频
一开始我用纯 CSS 做,让头发那块区域平移几个像素。效果很差,因为单张图里头发和脸是同一批像素,平移就等于连着脸一起拽,看着像有人在扯纸片。
后来改成离线渲染:用深度图算每个像素该移动多少,近的动得多、远的动得少;再用发根到发梢的权重控制幅度递增;加上空间相位让波形扫过去,加一层高频湍流让区域内部也发生形变。渲染 108 帧,编码成 WebM,运行时当视频层播放。
位移公式,参数都在 06_render_25d.py 顶部:
amp = A_BASE + A_DEPTH·depth + A_HAIR·hairWeight
φ = 2π(PHASE_U·u + PHASE_V·v)
dx = amp·(0.62·sin(2πf₁t+φ) + 0.38·sin(2πf₂t−0.7φ)) + A_TURB·turb·sin(2πf₃t+2.1φ)
所有波走整数个周期,再减掉 t=0 时的相位偏置,这样首帧和末帧的位移都正好是 0。视频播完直接摘掉,画面不会跳。
接入时踩到的三个坑
视频得跟底图一起缩放。 .sf-bg 上有 sfFocus(1.14 缩到 1.02)和 sfDrift(1.02 到 1.06)两条动画,还有模糊。视频如果作为兄弟节点放进去,4.3 秒时底图已经是 1.06 倍而视频还是 1 倍,头发会飘到脸外面。解决办法是把 <video> 塞进 .sf-bg 内部,子元素会继承父节点的 transform 和 filter。
插件没有打包器。 client.js 是被 __ModuleLoader__.load() 直接执行的,没有 webpack,也没有 import.meta.url,包目录里的 webm 根本引用不到。只能把视频转成 base64 内联,运行时 atob 再 Blob 再 createObjectURL。不要直接用 data: 当 video.src,那个有长度限制,而且有些 Chromium 版本对 data URI 的视频不带 alpha。
视频 3.6 秒,时间轴 4.4 秒。 播完以后停在最后一帧,如果那帧头发还飘着,后面 0.8 秒就定格在一个歪掉的位置。所以渲染时必须保证首尾位移是 0,播完摘掉才看不出来。
不闪宿主启动画面
宿主自带的启动画面([data-dsh-boot],HARNESS 加转圈加 Loading plugins)在任何客户端插件被实例化之前就画好了,光靠 client 半边怎么都追不上。
能用的是 webserver/index-inject,它收集的注入行会在 index.html 解析阶段就渲染。lib/index.js 推了两行:一条样式铺同色封面,一条脚本负责在 client 挂载时把封面摘掉,另外设了 3.5 秒的兜底。
几个要注意的地方,都是试出来的:只推 style 和 script 两种(行类型是闭集,写个不认识的导致 boot gate reject,桌面端会进崩溃恢复页);style 必须排在 script 前面;订阅要同步注册,因为注入表只在启动时收集一次;tapIndex 在桌面端没用,那边走 dsh-app:// 直接读 index.html,不经过 web 服务器。
层级
shell.overlay 槽位的包装层 z-index 只有 20,祖先带 transform 之类就会创建层叠上下文,后代写多大的数都被锁在里面。所以动画层是自己建节点挂到 body 下面的,z-index 用 2147483600。
挂到 body 之后要小心一件事:不能挡住界面。现在 .sf-root 和 React 那个空壳都设了 pointer-events: none,挂载前会清理残留节点,播完还有一道 1.2 秒的强制清理定时器。
换成自己的图
pip install opencv-python numpy scipy
pip install transformers # 深度图,可选
python3 hair/tools/05_depth.py --image assets/splash.webp --out hair/masks/depth.png
python3 hair/tools/01_sam2_hair_mask.py --image assets/splash.webp --out hair/masks/hair_mask.png
python3 hair/tools/02_make_weight.py --mask hair/masks/hair_mask.png --out hair/masks/hair_weight.png
python3 hair/tools/06_render_25d.py
bash hair/tools/04_encode_webm.sh hair/frames25d assets/wall_25d.webm
python3 build.py
第一步的深度图需要 transformers,装不上会自动退回用亮度凑一张。第二步的 SAM2 需要 torch 和权重 sam2.1_hiera_large.pt。
说清楚一点:仓库里现在这张 mask 是凑出来的,不是 SAM2 的输出。生成的时候手上没有 GPU 环境,用的是椭圆约束加颜色阈值再挖掉脸和肩膀。发丝之间的空隙是糊的。你要是自己跑一遍 01_sam2_hair_mask.py 换掉它,边缘会好很多。
版本历史
| 版本 | 改了什么 |
|---|---|
| v0.1.0 | 第一版,纯 CSS 动画 |
| v0.2.0 | 换成深度图驱动的 2.5D 位移,顺便解决启动闪烁 |
| v0.2.1 | 动画层改挂到 body 下面,压住第三方浮层 |
| v0.2.2 | 顶部加压暗带,想盖住 Windows 的窗口按钮 |
| v0.2.3 | 修掉动画层拦截点击的问题,删掉压暗带 |
细节见 CHANGELOG.md。
还没解决的问题
- 皮肤和纯色背景这种没有纹理的地方,位移 9 像素在数值上只差一两个灰度级,肉眼看不出在动。这是整图位移本身的上限,调参数解决不了。
- Windows 右上角那三个窗口按钮是系统画的,网页盖不住。想彻底解决只能把 dsh 切到 advanced 窗口模式,那样标题栏是透明的。
- 只播一次,想重播要刷新页面。
- dsh 还是 developer preview,
shell.overlay和slots.register的接口说不定哪天就变了。
目录
dsh-splash-fish/
├── package.json 插件声明
├── cordis.patch.yml roster 里插一行
├── lib/index.js host 半边,负责注入启动封面
├── client.js 构建产物,图和视频都内联在里面,别手改
├── client.template.js 源码,样式、时间线、视频挂载、清理逻辑
├── build.py 把图和视频内联进 client.js
├── assets/ splash.webp / wall_25d.webm / hair_wave.webm
├── hair/tools/ 01 分割 02 权重 04 编码 05 深度 06 渲染 07 拆层 08 分层
├── hair/masks/ 三张图:mask、权重、深度
├── preview/ 预览 mp4
├── preview.html 免安装预览
├── dev/harness.html 自测页,?t= 冻结帧,?nohair=1 去掉视频层做对比
└── AGENTS.md 给 Agent 看的安装说明
License
MIT。插图版权是原作者的,这里只做演示用,请换成自己的图。
No comments yet. Be the first to write one.