DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Lby-2007 /

Lby-2007/dsh-splash-fish

Verified

Depth-driven 2.5D startup animation plugin for DeepSeek Harness

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@3aa19692

dsh-splash-fish

A startup film for DeepSeek Harness — your own illustration develops out of the dark, the frame drifts with real depth parallax, then dissolves into the workspace.

纯客户端 UI 插件,挂在 dsh 的 shell.overlay 槽位上。每次页面加载只播一次,播完自行卸载,不残留 DOM。

startup film

预览 内容
preview/splash-25d-preview.mp4 完整启动动画,5.07 秒,含 2.5D 视差
preview/hair_wave_preview.mp4 上一代的头发位移层(3.6 秒,对照用)
preview.html 浏览器直接打开即可预览,?t=2600 冻结到某一帧

安装

方式一:让 Agent 装(推荐)

在 DeepSeek Harness 里新建一个会话,把下面这段整个发给 Agent:

帮我安装这个 DeepSeek Harness 插件:https://github.com/Lby-2007/dsh-splash-fish

步骤:
1. 把这个仓库克隆到 %USERPROFILE%\.dsh\bundles\dsh-splash-fish
   (目录要长期存在,插件是以 link 方式引用的,移走会失效)
2. 读写 profile 配置,把它注册进 desktop profile:
   - 文件:%USERPROFILE%\.dsh\profiles\desktop\package.json
   - dependencies 里加一行 "dsh-splash-fish": "link:<上一步的绝对路径>"
   - dsh.profile.bundles 数组里追加 "dsh-splash-fish"
3. 在 %USERPROFILE%\.dsh\profiles\desktop\node_modules\ 下为它建一个目录链接
4. 告诉我需要重启应用才生效

Agent 会自己读 AGENTS.md 里的细节。装完彻底退出应用再打开。

方式二:应用内安装(不用命令行)

  1. 把仓库下载或 clone 到一个长期目录,例如 D:\dsh-plugins\dsh-splash-fish
  2. 打开 DeepSeek Harness → 设置 → 插件 → 添加插件
  3. 填入那个目录的绝对路径(必须是含 package.json 的那一层)
  4. 安装 → 立即启用 → 重启应用

方式三:命令行(Web 版 / 有 dsh CLI 时)

dsh plugin --profile web add /你的绝对路径/dsh-splash-fish

桌面版的 desktop profile 由 Electron 应用独占管理,命令行会被拒绝(profile "desktop" is managed exclusively by the Electron application)。桌面版请用方式一或方式二。


它是怎么工作的

一个视频,而不是一堆 CSS 动画

单张插画里,头发和脸在同一条像素上,没有分层。CSS 只能做整块平移——那看起来像有人在拽纸片。

所以画面上每一帧的位移都是离线渲染好的:深度图驱动视差、发根发梢权重控制幅度、空间相位让波横扫、高频湍流让区域内部也发生形变。渲染结果编码成 WebM,运行时作为视频层播放。

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φ)

其中 A_BASE 保证最远处也在动(没有死区),A_DEPTH 给视差,A_TURB 给区域内部的形变。所有波走整数个周期并减掉 t=0 的相位偏置,首帧与末帧位移严格为 0——视频播完摘掉时画面不会跳。

三个必须解决的接入问题

问题 做法
视频要和底图共用同一个缩放/模糊变换 把 <video> 放进 .sf-bg 内部,子元素继承父节点的 transform 与 filter
插件没有打包器,引用不到外部文件 base64 内联 → 运行时 atob → Blob → createObjectURL
视频 3.6 秒、时间轴 4.4 秒,播完会跳 位移公式保证首尾归零,播完直接 display:none

不闪宿主启动壳

宿主自带的启动画面([data-dsh-boot])在任何客户端插件被实例化之前就画好了。所以 lib/index.js 通过 dsh 的结构化注入行,在 index.html 解析阶段就塞进一行同色封面:

const inject = ["webServer"];
function apply(ctx) {
  ctx.on("webserver/index-inject", (table) => {
    table.push({ kind: "style", text: COVER_CSS });
    table.push({ kind: "script", placement: "head", text: COVER_JS });
  });
}

几条纪律(都是踩坑换来的):只推 style / script 两种行(未知 kind 会让 boot gate 直接 reject)、style 必须在 script 之前、订阅必须同步注册、不能用 tapIndex(桌面端走 dsh-app:// 直读,那条路是死代码)。封面在 client 挂载时被摘除,另有 3.5 秒硬超时兜底。

绝不能挡住界面

shell.overlay 的槽位层级只有 z-index: 20,祖先的层叠上下文会把后代的大 z-index 锁死在里面,所以动画层挂到 document.body 下、z-index 取 2147483600。

但仅仅是"挂到 body"还不够——全屏层一旦残留就会吃掉所有点击。所以三层防御:

  • .sf-root 与 React 空壳都设 pointer-events: none(即使残留,鼠标也穿透)
  • 挂载前清掉上一次可能残留的 .sf-stage-host
  • 播完再设一道 1.2 秒后的强制清理,不依赖卸载回调

播放期间的"点击跳过"改到 window 的捕获相位监听,并 stopPropagation 吞掉这次点击,不误触下面界面。


换成你自己的图

pip install opencv-python numpy scipy          # 渲染必需
pip install transformers                       # 深度图(可选,装不上会退伪深度)

# 1) 深度图
python3 hair/tools/05_depth.py --image assets/splash.webp --out hair/masks/depth.png

# 2) 头发 mask(SAM2,需要 torch + 权重 sam2.1_hiera_large.pt)
python3 hair/tools/01_sam2_hair_mask.py \
  --image assets/splash.webp --out hair/masks/hair_mask.png

# 3) 发根→发梢权重图
python3 hair/tools/02_make_weight.py \
  --mask hair/masks/hair_mask.png --out hair/masks/hair_weight.png

# 4) 渲染 108 帧 + 编码 + 内联
python3 hair/tools/06_render_25d.py
bash hair/tools/04_encode_webm.sh hair/frames25d assets/wall_25d.webm
python3 build.py

所有可调常量在 06_render_25d.py 顶部:A_BASE / A_DEPTH / A_HAIR / A_TURB / A_BREATH / PHASE_U / PHASE_V / CYCLES。当前值峰值位移约 9 px。

仓库里的 mask 是几何近似(生成时没有 GPU 环境跑 SAM2,用的是"椭圆约束 + 蓝度阈值 + 挖掉脸/肩")。发丝之间的镂空是糊的。跑一遍 01_sam2_hair_mask.py 换成真 mask 再重渲染,边缘会干净得多。


版本历史

版本 变化
v0.1.0 第一版:纯 CSS 启动动画(黑场显影、光晕、斜光、粒子、字标、淡出)
v0.2.0 换成深度驱动的 2.5D 位移,并消除宿主启动壳的闪烁
v0.2.1 动画层改挂 <body> 下,压住第三方浮层(余额鲸鱼挂件那类)
v0.2.2 加顶部压暗带,让 Windows 原生窗口按钮融入画面
v0.2.3 修掉启动层拦截点击的问题(pointer-events: none + 兜底清理),撤掉压暗带

完整改动见 CHANGELOG.md。


已知限制

  • 无纹理区域看不出在动。 皮肤、纯色背景这类平滑区域,位移 9 px 在像素值上只差不到 2 个灰度级。这是整图位移方案的物理极限,不是参数问题。
  • 盖不住原生窗口按钮。 Windows 的最小化/最大化/关闭由操作系统绘制在网页之上,CSS 无解。要么切 dsh 的 advanced 窗口模式(标题栏变透明),要么接受它。
  • 只播一次,刷新页面重播。
  • VP9 + alpha 只在 Chromium 系生效(dsh 桌面版是 Electron,没问题)。Safari 不支持。
  • dsh 仍是 developer preview,shell.overlay / slots.register 契约可能随小版本变动。

项目结构

dsh-splash-fish/
├── package.json              dsh.bundle.patch + dsh.client.platform=web
├── cordis.patch.yml          roster 里插一行
├── lib/index.js              host 半边:注入启动封面
├── client.js                 构建产物(图 + 视频已内联,勿手改)
├── client.template.js        源码:样式、时间线、video 挂载、清理逻辑
├── build.py                  内联静图 + webm → client.js
├── assets/                   splash.webp / wall_25d.webm / hair_wave.webm
├── hair/tools/               01 SAM2 分割 / 02 权重 / 05 深度 / 06 2.5D 渲染
│                             04 编码 / 03 旧渲染 / 07 拆层 / 08 分层渲染
├── hair/masks/               hair_mask.png / hair_weight.png / depth.png
├── preview/                  预览 mp4
├── preview.html              免安装预览页
├── dev/harness.html          伪宿主自测页(?t= 冻结帧 / ?nohair=1 差分)
└── AGENTS.md                 给 AI Agent 的安装与改动指引

License

MIT. 插图版权归原作者,仓库内仅供演示,请自行替换 assets/splash.*。

—/ 5

No ratings yet

Verified DSH bundle

Commit 3aa196922334

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout