mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-23 10:28:06 +00:00
用户反馈三点:① 拉不到最下面 ② 文字与图片没有进出动画,单调 ③ 图片仍是「框框住文本」,且希望有「外界光球打到插件上」。 ## ① 滚不到底:真 bug,且是两个独立根因叠加 实测(滑到底后读 scrollY):停在 10283,上限 10669,**差 386px**, 页脚完全不可见。两个原因: - **末尾两节合计超过一屏**。faq 高 635 + footer 367 = 1002px > 一屏 828px。 `scroll-snap-type: y mandatory` 只允许停在吸附点,于是浏览器被迫二选一: 要么 faq 标题对齐(则页脚滚不到),要么页脚可见(则标题被导航压住)。 实测两种坏法都出现过:h2 顶 = -57 / -38(导航底 67)。 修法:FAQ 六条改双列(省下约 190px),收尾段取消整屏高度, 合计压到 762px,两个要求即可同时满足。 - **只在 footer 单独设吸附点会形成死锁**。试过给 architecture 设 `scroll-snap-align: none`(它高 1180px),结果前一个吸附点把它自己吸回来、 后面又无吸附点接住,实测卡死在 y=5791,怎么滑都不动。 教训写进注释:高节退出吸附不是解法,「装得进一屏」才是。 ## ② 交错行:方向与布局相反(结构性错误) 原文给每行写死 `slide-l`(文)与 `slide-r`(图)。但翻转行里图在**左边**, 却仍从右侧飞入 —— 图穿过文字进场,方向与布局相反。5 行里 3 行错。 修法不是逐行改正,而是**从布局推导方向**:`.alt:not(.flip)` 文左图右、 `.alt.flip` 图左文右,方向跟着 `.flip` 走。这样不可能再写错。 退出时不加 `.in`,transform 回到同侧 ——「从左进就从左出」是自动的。 ## ③ 示意图:从静态线框变成有语义的动画 现状实测很糟:5 张图共 116 个元素,**只有 4 个在动**(各 1 条虚线), 图 2 完全静止 —— 用户说「框框住文本」是准确的。 按每张图的语义给它自己的动作(13 种 keyframes,47 个动画元素): - **图 1 隔离**:外部光球从画面外飞入,四种颜色命中四个插件, 激起涟漪 + 插件闪一下;内核一列都没有。这正是「外面的一切都落在插件上」。 - **图 2 零依赖**:四项依赖被**逐条划掉**。用 `pathLength=1` + `stroke-dashoffset` 让线自己「划」过去,不是淡入。 - **图 3 共享内存**:写入/读回两个包沿链路跑,arena 上有光带自左向右扫过。 - **图 4 优先级**:金色包沿四条曲线**插队**到 L1–L4 之前; 四级强度条依次点亮;队列条逐条被取走(先到先处理)。 - **图 5 长任务转投**:积压消息被接走飞向分诊助手,收到时闪一下。 配套修掉三处我自己引入的缺陷: - `.dv-pkdot` 原用 `pkPulse` 动 `r`,与行进包叠加会闪烁 → 改只动透明度 - `.dv-ripple:nth-of-type(2n)` 按 `<circle>` 计数,误配到数据包圆点, 四个涟漪全被染成金色 → 改显式逐色 - 涟漪原画在插件框**内部**,像框里画了个圆 → 移到框下层,从背后漾开 ## ④ 顺带发现并修掉的真问题 - **CSS 的 `prefers-reduced-motion` 管不到 SMIL**:实测 reduce 下 6 个 数据包照跑。加 JS 调 `svg.pauseAnimations()`,实测 8/8 SVG 已暂停。 - **窄屏横向溢出 26px**:源于我这次加的入场位移(`translateX(42px)`) 在未入场时探出视口。修法是 `overflow-x: clip`(不用 hidden,避免新建滚动容器) 并窄屏收到 ±20px。实测 390/768/1440 三档溢出均为 0。 ## 验证 - 滚动:到底=true,页脚可见,faq 标题不被遮挡(h2 顶=210 > 导航底 67) - 方向:5 行全部「文在左侧就从左进」,翻转行正确反向 - 入场:逐节停留 13 节全部入场,0 未揭示; 滑到底后 23 个 opacity=0 的元素**全在视口上方**(退场生效),无一是「场内却不可见」 - 回归:深浅双主题、JS 禁用、reduce、390/768/1440 三档 全绿,无控制台错误 - 结构:HTML 解析无未闭合,CSS 括号平衡
官网(静态站)
单文件、零构建、零依赖的落地页。与仓库 WebUI 的做法一致(原生 HTML/CSS/JS,无打包步骤)。
文件
site/
├── index.html 单文件站点(内联 CSS/JS)
└── assets/
└── logo.svg logo(来自 assets/branding/logo-h-he.svg)
资源是复制而非引用上级目录,因此 site/ 可整体拷走独立部署。
本地预览
cd site && python3 -m http.server 8799
# 打开 http://127.0.0.1:8799/
部署
纯静态,任意 web 服务器指向 site/ 即可:
server {
listen 80;
server_name your.domain;
root /path/to/TrueAgent/site;
index index.html;
location / { try_files $uri $uri/ =404; }
}
设计说明
- 配色取自品牌指南:蓝
#3b82f6/ 青#06b6d4/ 金#f59e0b, 正好对应三层记忆 Context / Document / Graph,因此三层记忆那节直接用了这三色做色条。 - 不放置立绘。曾试过放看板娘,但原图是白底 + 蓝紫渐变外框的方形图, 与页面几乎无法自然衔接(详见下文「为什么最终没有图」)。
- 淡入动画是渐进增强:内容默认可见,仅当 JS 真的跑起来才加
.js-reveal接管。 早期版本把opacity:0写在默认样式里,结果 JS 未执行时整页永久空白 (实测 30 个元素里 26 个停在不可见)——现在禁用 JS 也完整可读。 - 尊重
prefers-reduced-motion;架构图的<pre>在窄屏横向滚动,避免整页撑宽。
深浅双主题
跟随系统偏好;导航栏右上角的按钮可手动切换,选择存入 localStorage(键 ha-theme)。
实现要点:
- 在
<head>里首绘前就定好data-theme,避免先渲染深色再跳浅色的闪白。 - 语义色全部走 CSS 变量(
--bg/--text/--border/--code-bg/--hover…),:root[data-theme="light"]只覆盖取值,不重复选择器。 - 品牌三色(蓝/青/金)两主题共用,因为它对应三层记忆,换主题不该换语义。
动效层
| 效果 | 位置 |
|---|---|
| 四团极光漂移 + 细网格 | 背景(position: fixed, z-index: -2) |
| 粒子网络(近邻连线) | #fx canvas,密度按视口面积自适应,上限 72 |
| 三色滚动进度条 | 顶部 |
| 标题渐变流动 | h1 .grad |
| 分块上浮入场(错落延迟) | 各 section |
| 卡片聚光 + 3D 微倾 | .card / .stat(仅精确指针) |
| 色条自上而下「灌注」 | 三层记忆 |
| 数据流光带下行 + 节点脉冲 | 架构图 |
| 数字滚动到位 | 统计卡 |
| 文字下划线展开 | 分节标题 |
三条硬约束(都吃过亏):
- 内容默认可读:初始隐藏只在
.js-fx下生效,而.js-fx只有 JS 真跑起来才加。 JS 被禁用或报错时,页面是完整可读的 —— 早期版本把opacity:0写在默认样式里, 实测 30 个元素里 26 个永久不可见。 - 尊重
prefers-reduced-motion:此时不加.js-fx、不启粒子、不画进度条, 所有元素直接可见。 - 装饰不得产生滚动条:canvas 按
documentElement.clientWidth定尺寸 (用window.innerWidth会含滚动条宽度,实测多出 15px 撑出横向滚动);body再加overflow-x: clip兜底。
所有 listener 走 requestAnimationFrame 节流;标签页隐藏时暂停粒子。
为什么最终没有图
试过放看板娘立绘,失败,最后决定不放。过程留在这里,免得下次重复踩:
原图 mascot-xiaozhai.webp 是不透明 WebP(无 alpha),白底 + 蓝紫渐变外框。
直接用 = 深色页面上一个刺眼的白色方块;抠图又不可行:
python3 -c "
from PIL import Image
im = Image.open('assets/branding/mascot-xiaozhai.webp')
print(im.mode) # RGB —— 没有 alpha 通道
"
背景连通域分析显示白底与角色的白裙子、白围裙同色,flood-fill 会顺着轮廓 渗进去,让约 42% 的身体变成透明(发丝高光先死)。曾退而求其次做成 「圆角卡面 + 发光边框 + 底部渐隐」,视觉上能接受,但本质上是在方形图上盖装饰, 而非让图融入页面。
结论:这类素材要么重新出一张带透明通道的图,要么就不放。 现在 Hero 是单栏文字,版面反而更稳。
插件卡片
「开箱可用的插件」一节里,每个徽章都是按钮:
- 点一下展开该插件卡(名称 / 版本 / 用途),再点收起
- 可同时展开多个
- 末尾「展开全部 N 个」一次全开
数据来自各插件的 plugin.json,不是手写的:
cd /home/newqqagent/plugins
for d in */; do [ -f "$d/plugin.json" ] && python3 -c "
import json;d=json.load(open('$d/plugin.json'))
print(d.get('name'), d.get('version'), d.get('description','')[:60])"; done
改内容前请核对事实
页面上的数字都是实测值。注意「在跑插件 36」是加载总数 (16 内置 + 20 外部),不是"外部插件数" —— 早期版本写成「36 外部插件」是错的, 已更正。改动前建议重新取一遍:
# 在跑插件(以日志里实际 loaded 的为准,比数目录可靠)
grep -h '\[plugin\] loaded:' $(ls -t /home/newqqagent/log/homed_*.log | head -1) \
| sed 's/.*loaded: //' | sort -u | wc -l
# 工具数(同上,日志里注册后的真实值)
grep -ohE '[0-9]+ tools' $(ls -t /home/newqqagent/log/homed_*.log | head -1) | tail -1
# Go 代码行(排除第三方与鸿蒙工程)
find . -name '*.go' -not -path './.git/*' -not -path './.go/*' \
-not -path './third_party/*' -not -path './cmd/ohos/*' | xargs cat | wc -l
# LLM 适配器(注意 server.lua 是网关脚本,不是厂商适配器,故为 9)
ls internal/lua/adapters/*.lua | xargs -n1 basename