dsh-better-motion
v0.1.0
Published
把逆向自小米 MiMo 的动效令牌与卡片弹出/悬浮原语移植到 DSH 桌面端;停用即完全回到默认。
Maintainers
Readme
dsh-better-motion 更好的动效
把逆向自小米 MiMo 桌面端的动效规格移植到 DSH 桌面 UI。纯样式层插件:不注册插槽、 不替换宿主组件、不依赖任何宿主内部结构——只在宿主已有的 DOM 锚点上挂动画类。
提供的动效
| 区域 | 效果 | 参数来源 |
|---|---|---|
| 全局令牌 | --bmt-motion-* / --bmt-ease-* | MiMo :root 令牌(加 bmt- 命名空间) |
| 会话切换 | 消息行 40ms 错峰(对话列归 HUD 管) | msg-in 规格 |
| 通用浮层 | portaled 卡片 menu-pop 弹入 | menu-pop 规格 |
| 大对话框/设置面板 | 面板弹入 + 面板内页切换上浮 | panel 规格 |
完整参数表与逆向结论见 MOTION.md。
宿主缺陷守卫:工作区选择卡「关不掉」
欢迎页左侧的工作区 chip(default ▾)点第二下不会收起,而是重新弹出——这不是动效
问题,是宿主自身的缺陷:宿主 Menu 用 document 上的 pointerdown 判断「点到外面
就关」,判据是 target 既不在 anchor 也不在菜单内。右侧「标准模式」把触发器作为
anchor 传进 Menu,所以点触发器不算外面;而工作区 chip 由会话包自己渲染,Menu 只拿到
anchor: null + getAnchorRect(仅用于定位),于是:pointerdown 先关一次 → click 又
setOpen(!open) 开一次,表现为「怎么点都关不掉」。本插件只是把这次重开播成了弹入,
看起来像动画坏了。
installMenuTriggerGuard() 的修法(不碰宿主 DOM、不改宿主代码):chip 处于
aria-expanded="true" 时,在捕获阶段拦掉这一次 pointerdown 的传播,Menu 的关闭逻辑
不执行,交给 chip 自己的 onClick 完成切换。chip 收起时不拦,正常打开——与「标准模式」
卡的行为一致。该守卫只匹配 类名以 _workspace 结尾 + aria-haspopup=menu + 已展开 的
按钮,其余指针事件零影响;停用插件即完全恢复。
关于关闭/出场动画(结论:不做)
尝试过 exit-ghost 方案(移除/隐藏时克隆节点播 150ms 出场),实测在 DSH 宿主上不可靠:面板的移除/隐藏机制无法从样式层稳定观测,出场动画时有时无 (时序竞态),且小卡片的缩退在高频开关场景读起来像"播一半消失"。已整体 回退——所有卡片与面板关闭均为宿主默认行为(瞬关)。
回退
三种方式,任选其一,立即生效:
- 停用插件:设置 → 插件 → 更好的动效 → 关闭(或 Plugin Manager)。
- 所有清理在 Client
apply()的返回函数里完成:摘样式表、断开全部 MutationObserver / 监听器、移除所有bmt-*类。停用 = 完全恢复默认。 - 每个 DOF 都有防叠加检测:宿主元素自身已有 animation 时一律让位。
无障碍
prefers-reduced-motion: reduce 下全部动效退化为 100ms 纯淡入,零位移。
已知边界
- 会话切换动效锚定
[data-chat-flow]/[data-chat-anchor-key](宿主自带属性, 与 dsh-better-hud 的已验证实现同一套锚点;宿主版本变化时该模块静默失效,不影响其它功能)。 - 通用浮层弹入只处理「挂载即悬浮 + 带圆角或阴影」的卡片,带自身动画的浮层跳过。
- 与 dsh-better-hud 的悬停卡动效重复(同源锚点):建议二者只开一个,避免同卡片叠两层类 (本插件的防叠加检测会跳过已有动画的卡片,实际不会双播,但建议精简)。
许可
MIT
