瞬间
查看我的瞬间 →
48
2

Ethereal 主题魔改

2026-08-06
2026-08-06
Ethereal 主题魔改
文章摘要
|

Ethereal 主题魔改全记录:从瞬间条到标签云

本文记录本站 Halo 博客主题 Ethereal(Astro 主题,fork 自 AloneNanNan/halo-theme-ethereal,基于 Fuwari 设计)从 v1.0.7 到 v1.0.16 的全部自定义魔改:每个功能的魔改处(涉及文件)、功能说明与实现原理


魔改总览

功能引入版本魔改处(核心)
瞬间滚动条(全站固定)1.0.8 → 1.0.15 多轮迭代新增 MomentMarquee 三件套,改 MainGridLayout / app.ts / global.css
标签彩色化 + 球形标签云1.0.8 → 1.0.16新增 tag-colors / tag-sphere 四件套,改 settings.yaml / Tags.astro / 7 处标签元素
切页 is-home 同步修复1.0.11 → 1.0.13app.ts(Swup 钩子)、global.css
天气组件错误透传1.0.9 前后Weather.astro
手机端标签回退原版1.0.16tag-colors.ts / tag-sphere.ts / Tags.astro / tag-sphere.css

一、瞬间滚动条(全站固定、跨页不闪)

魔改处

  • 新增:src/components/widget/MomentMarquee.astro(组件)、src/styles/moment-marquee.css(样式)、src/utils/moment-marquee.ts(数据拉取)
  • 修改:src/layouts/MainGridLayout.astro(挂载位置)、src/scripts/app.ts(初始化)、src/styles/global.css(banner 位移同步)

功能
页面顶部一条「瞬间」动态滚动条:内容从左到右无缝循环滚动,横跨两侧栏与文章卡片之上;整条可点击进入 /moments 瞬间页;随页面切换常驻不闪、动画不中断。

详细介绍(含多轮迭代)

  1. v1.0.8 初版:仅首页文章列表上方显示。数据不在服务端注入,改为客户端 fetch('/moments/rss.xml')(同源无跨域),解析 <item><description> 去 HTML 截断后填充,双份复制 track 实现无缝循环,按内容宽度计算动画时长。
  2. v1.0.9 全站固定:把组件从 index.astro 移到 MainGridLayout,渲染在 #main-grid 之上、#swup-container 之外——Swup 切页只替换容器内内容,因此瞬间条跨页持久、动画不中断;加 data-mm-init 幂等守卫,切页不重建。
  3. v1.0.10 首页间距修复:首页带 banner 时 #main-grid.is-home.enable-banner 整体下推 376px 给 banner 让位,而瞬间条是网格的兄弟节点不受影响,导致中间凭空出现 ~360px 空白。修法:瞬间条包裹层加 moment-marquee-anchor 类,同条件下同步 translate-y
  4. v1.0.11 → 1.0.12 切页卡顿根因:切页时瞬间条与网格仍被错误下移几秒。线上实测(浏览器 CDP 时间线)发现 visit:start 钩子里 new URL(visit.to.url)Invalid URL——Swup 的 visit.to.url 是相对路径,抛错被 catch 吞掉导致 body.is-home 同步从未执行。修法:新增 pathnameOf() 兼容相对/绝对路径提取,在 visit:start 用目标 URL 提前同步 body.is-home,并加 content:replace 兜底钩子。
  5. v1.0.13 过渡同步:给 moment-marquee-anchor 补上与 #main-grid 一致的 transition duration-700,让瞬间条和文章卡片从同一时刻同步滑动,消除"瞬间栏先定位"的错位感。
  6. v1.0.14 → 1.0.15 右侧图标:瞬间条最右侧加相机图标("记录瞬间")。过程中踩了 Tailwind 任意值语法坑:icon-[material-symbols--auto_awesome] 里的下划线会被当作空格导致图标规则永远生成不了,且 material-symbols 图标集构建时加载不稳定——最终改用手写内联 SVG(线性描边、currentColor 随主题变色、呼吸闪烁动画),100% 稳定显示。

二、标签彩色化 + 球形标签云

魔改处

  • 新增:src/utils/tag-colors.ts / src/styles/tag-colors.csssrc/utils/tag-sphere.ts / src/styles/tag-sphere.css
  • 修改:settings.yamlstyleSwitches.tag_style 三选项下拉)、src/components/widget/Tags.astro(球形分支 + 移动端列表副本)、src/scripts/app.ts(初始化)、7 处标签元素(PostMeta.astroarchives.astromoment.astromoments.astrophoto.astrotags.astro 的条件类)

功能
后台「样式 → 标签样式」新增三选项:

  • 原版:主题默认标签
  • 彩色标签:标签字体按名称哈希得到稳定色相,同一标签全站同色、刷新不闪,亮/暗模式自适应
  • 球形标签云:3D 旋转球体,标签均匀分布在球面,支持鼠标拖拽甩动、悬停互动、近大远小、彩色辉光

详细介绍

  • 彩色标签:用标签标识(优先 href,其次文本)做哈希 → 0~359 色相 → hsl(),只改字体颜色(不动背景/描边,避免破坏主题卡片视觉);由 initTagColors() 读取 theme.config 门控,非 colorful 直接跳过;监听 Swup page:view 与暗色切换重新着色。
  • 球形标签云:Fibonacci 球面分布保证均匀;每帧按深度(z 轴)计算缩放(0.61.3)与透明度(0.351);自动旋转 + 鼠标位置影响转速 + 拖拽惯性;prefers-reduced-motion 时停转。球形模式下侧栏标签组件不折叠(避免裁球)。
  • 手机端回退(v1.0.16):<768px 时 JS 跳过着色/不初始化球体,Tags.astro 双渲染一份原版列表(md:hidden,手机显示、桌面隐藏),CSS 隐藏球体——手机端永远只显示原版标签。

三、切页 is-home 同步修复(技术彩蛋)

魔改处

  • src/scripts/app.ts:新增 pathnameOf()pendingTargetPath,改造 visit:start 钩子,新增 content:replace 兜底钩子
  • src/styles/global.css.is-home.enable-banner .moment-marquee-anchor 同步位移规则

功能
修复 Swup 页面切换时 body.is-home 类滞后导致的 "顶部大段空白、几秒后跳回" 卡顿。

详细介绍
Ethereal 的首页 banner 位移规则 .is-home.enable-banner #main-grid 依赖 body 上的 is-home 类,而 body 不在 Swup 替换的容器内。原主题只在 page:view(动画结束后)更新该类,且 Swup 更新浏览器 history 也晚于 page:view,于是切页瞬间 body 仍是旧页的 is-home,banner 位移错误作用到新页。修复链:

  1. visit:start(动画开始前)用目标 URL 提前同步 is-home
  2. pathnameOf() 兼容 Swup 返回的相对路径(new URL(相对路径) 会抛错);
  3. content:replace 兜底(用缓存的目标路径,不依赖 history 更新时机)。

四、天气组件错误透传

魔改处

  • src/components/widget/Weather.astro(+22 行)

功能
天气卡片在接口异常时透传腾讯位置服务返回的真实 status/message,而非笼统的 "服务繁忙"。

详细介绍
原实现把所有失败统一 catch 成 "天气服务繁忙",遇到 110/112/113/120 等状态码无法区分是 Key 配置问题、域名白名单问题还是 QPS 限流。改为把 [status] message 直接显示在错误卡片上,一眼定位问题(本站曾实测到 status: 120 = QPS 达上限)。


五、版本历程

版本内容
1.0.7上游基线
1.0.8首页瞬间条初版 + 标签彩色化
1.0.9瞬间条全站固定(移到 #swup-container 外)+ 标签球形云
1.0.10首页瞬间条间距修复(banner 位移同步)
1.0.11 → 1.0.12切页卡顿根因修复(visit.to.url 相对路径兼容)
1.0.13瞬间条过渡同步(transition 对齐)
1.0.14 → 1.0.15瞬间条右侧相机图标(内联 SVG,避开 iconify 加载坑)
1.0.16手机端标签回退原版

结语:与上游共存

所有魔改集中在一个自定义分支(fork: lqbby/Halo-Theme-Ethereal),与上游 main 分支互不干扰。为了上游更新时能顺利合并,仓库内维护了 CUSTOM-PATCHES.md(改动清单 + 合并指南)和 ethereal-custom.patch(完整补丁),冲突高发点集中在 settings.yamlapp.tsMainGridLayout.astroglobal.cssTags.astrotheme.yaml,合并后需重新 astro build 验证。

魔改虽好,紧跟上游更重要——功能与可维护性的平衡,才是长期持有主题的正确姿势。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

Ethereal 主题魔改
/archives/ethereal-theme-mods
作者
LQBBY
发布于
2026-08-06
许可协议
CC BY-NC-SA 4.0

评论