把项目从「手写 dist/」改成「wallpapers/ 是唯一真相来源,dist/ 由 pnpm build 生成」,
并补上配套的类型、门禁与抓取器。一次提交落地整条管线,因为拆开会留下不能构建的中间态。
- src/:运行时与模拟器源码(TS,strict),编译到 build/ 再拷进各分发
- tools/:build / dev / check-{syntax,paths,dist},以及抓取器与回归门禁 tools/checks/
(.scratch/ 下那批一次性脚本移入 tools/checks/ 并入库为长期门禁)
- wallpapers/:七档壁纸的源数据 + README.md(id/音频/预设的完整规范)
- docs/adr/0005-0008:构建管线与分发拓扑、模拟器契约、自包含 sim、每骨架资源布局
- .gitignore:排除 .scratch/ 的参考资料副本(上游 spine 整仓克隆 ~1.2 GB、
抓取侦查数据 ~680 MB)与调试转储;这些是本地调查材料,补偿会让仓库无法克隆
- 归一化 .gitignore/CONTEXT.md 行尾(工作区 CRLF、索引 LF 造成的整文件假 diff)
同时修掉三档卡住构建的未完工壁纸:
- kv45 的 meta.json 里 id 还是抓取期场景名 scene_main,经 downloader promote 正名为 kv45
- shajin / zhigengniao_juheye 的 meta.json 误用了骨架描述文件(name/spine/animations/pages)、
且都缺 preset.template.json;现按规范重建:骨架沉到 spines/<名>/(spine-ts 按 atlas 所在
目录解析贴图页)、补上元数据与单骨架预设,并清掉 zhigengniao 骨架里指向作者机的绝对路径
- 顺带 promote 已在 sources.yml 里的 kv46(月升之前,与兽共舞)
pnpm check 五道门全绿:10 个分发 / 7 档壁纸 / 141 处引用自包含。
4.0 KiB
4.0 KiB
14 — 面板动效
Status: resolved Type: task
需求
给这个壁纸设置添加一些细腻的动画吧
一条原则
只做解释状态变化的动画——东西从哪来、去哪了、刚才是哪个变了。
面板是常驻 UI。装饰性的循环动画(呼吸、闪烁、渐变流动)只会让人分心,而且这个面板
每改一个属性就会重画一次,任何"一直在跑"的东西都会变成噪音。所以整套动效里
没有一条 @keyframes 是持续运行的。
加了什么
| 位置 | 动效 | 它在解释什么 |
|---|---|---|
| 抽屉 | 曲线改成 cubic-bezier(.22,.61,.36,1) |
纯 ease 结尾会急停 |
| 面板刚滑出 | 逐行错开上移淡入(--i × 16ms) |
这些东西是"刚出来"的 |
| 条件新出现的行 | 同样的入场,不错开 | 它是被勾出来的 |
| 行悬停 | 底色高亮 + 图标放大 1.16 | 指针现在在哪一行 |
| 复选框 | 自绘,勾靠 background-size 从 0 长出来 |
刚才是哪个开关变了 |
| 下拉箭头 | 展开时翻 180° | 列表开着 |
| 下拉/取色器弹层 | 缩放 + 上移出现 | 它从按钮那儿长出来 |
| 色块 | 悬停放大;确认后弹一下 | 颜色变了但位置没变,不弹容易看不出 |
| 重置 | 悬停时图标转半圈 | 这是"复位" |
| 确认/取消 | 悬停提亮、按下下沉 1px | 按到了 |
| 右边缘把手 | 悬停淡入并左移 2px | 这里能滑出东西 |
两个容易做错的地方
入场不能每次重画都重播
paintProps() 是 host.textContent = "" 然后整块重建。如果入场动画挂在
#wesim[data-open="1"] .row 这种选择器上,那么每改一个属性——拖一下音量、勾一个开关——
整个面板都会重播一遍动画,看起来像闪屏。
所以:
- 刚滑出那一下:给根节点打
data-enter="1",520ms 后摘掉。带令牌,连着开关几次 只有最后一次的定时器能摘。 - 条件新出现的行:
paintProps记着上一次可见的属性键,只有新冒出来的才加.row-enter。
那 4 个颜色滑杆是个例外:它们不是属性表里的键(是 WE 内置的),走不到按 key 认新的那套,
所以单独用 colorOptionsShown 判一次"上一次它们不在"。
复选框不能用 ::after 画勾
<input> 是替换元素,伪元素在它上面不生效。所以勾是一张内联 SVG 背景图,
靠 background-size: 0 0 → 11px 11px 长出来(background-size 是可过渡属性)。
prefers-reduced-motion
整套动效在 @media (prefers-reduced-motion: reduce) 里被关掉。这不是可选项:
前庭功能敏感的人会因为界面动而难受,而这套动效对可用性没有任何贡献。
验证
tools/checks/verify-panel.mts 第 ⑩ 组,全部通过:
- 滑出后
data-enter="1"、行上跑的是wesim-row-in、--i是 0,1,2,3,4 - 播完
data-enter被摘掉(不会每次重画都重播) - 勾「显示颜色选项」后,只有亮度/对比度/饱和度/色调偏移四行带
.row-enter - 复选框
appearance: none(确认是自绘的) - 展开下拉 →
aria-expanded="true"且箭头matrix(-1,0,0,-1,0,0)(翻过来了);Esc 后复位 Emulation.setEmulatedMedia模拟 reduce → 动画与过渡时长都降到 ~0
测出来的三个真问题
- 颜色滑杆走不到
isNew(key)那套,永远不带入场标记(上面已说)。 - 点开下拉时先把
aria-expanded设成 true,紧接着openComboFor内部的closeCombo又把它清掉 —— 顺序反了,箭头永远不翻。改成openComboFor之后再设。 - 测试自身:动效那一段先移到远处再移到边缘。前面点过「取消」会把
armed置 false, 而它只有"指针离开边缘"才复位——不先走开一次,合成指针根本打不开面板。
回归
全绿:pnpm check、调试服与浏览器冒烟、热更新、四档自包含包 file://、静态托管预览、
发布产物里动效代码 0 处(wesim-row-in 计数为 0)、6 组渲染与重构前逐像素相同。