Skip to content

Releases: fomalhaut1998/hexo-theme-fomalhaut

v1.0.5 — 日夜自动模式与一批动效修复

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 18 Oct 10:41

这一版补上「访客没手动选过深浅色时,按当天真实日出日落自动定深浅」——这条规则原来只挂在首页的日历卡里,文章页根本没有,于是「夜间模式下点『随便逛逛』跳过去就变回白天」。顺手把日夜判断收成一份共享实现,侧栏日历与美化面板改成委托它;首页卡片入场从缩放改纯淡入,pjax 换页后入场动画不再哑火;归档页年份胶囊居中不再把整页顶下去,评论区楼中楼的表情面板被压住点不动一并修掉。

全站日夜首屏预置(新增 source/js/inject/daynight-boot.js)

  • 病根:自动定深浅的唯一执行者是 /js/aside-calendar.js,它随首页的日历卡渲染,文章页 HTML 里连这个 <script> 都没有;「随便逛逛」用 location.href 整页跳转,head 重新执行却读不到可用信息 → 退回 display_mode: light。站内普通链接走 pjax 不重新加载,所以平时看不出来
  • 把这一半搬进 head 同步执行(早于首帧,不会先亮后暗闪一下):有未过期的手动选择(theme 键)就什么都不做;没有就用与 aside-calendar.js 逐字同源的 sunTimes() / geo() 判日夜,立刻写 <html data-theme>,DOM 就绪后再补 body.DarkMode 与 #modeicon
  • 坐标四级兜底:window.fomalNightConfig.latLng(站点写死)→ global.ipLoacation(IP 定位,head 里通常还没到)→ localStorage asideCalGeo(上次日历定位)→ { lat: 22.5319, lng: 时区推经度 };极昼极夜算不出日出日落就返回 null,什么都不做、交给主题默认
  • 算法挂到 window.fomalDayNight(apply / isDayNow / hasChoice / geo / sunTimes / setMode / setConfig / config / themeKey),同一套算法只留一份实现,免得两边改歪

手动选择优先与总开关(source/js/aside-calendar.js、source/js/modules/settings.js)

  • 日历卡新增 sharedApi() / syncSharedConfig():isDayNow / setMode / applyDayNight / sunTimes / geo / hasThemeChoice 优先委托 window.fomalDayNight,取不到才用自带实现兜底;启动时把文件里的旧 CONFIG 旋钮汇报给共享实现(那边没写的才补),旧配置不失效
  • 站点旋钮收口到 _config.fomalhaut.yml 注入的一行内联脚本:window.fomalNightConfig = { enabled: true, latLng: null, themeKey: 'theme' }。enabled: false 就是关掉「没手动选过就按日出日落自动定深浅」,只认手动选择与系统设置;运行期 setConfig() 会立刻重算
  • 「8 小时自动切换」在 enabled: false 时不再动手;顺带修掉切回白天误写 classList.add('DarkMode') 的老 bug(原来切回白天后仍被判成夜里 —— shell.js 的日转过场与月亮按钮样式都读这个类)

首页卡片入场改纯淡入(_config.fomalhaut.yml 的 wowjs.animateitem)

  • 文章卡片与侧栏卡片从 animate__zoomIn / 2s / 延迟 200ms / offset 30 改成 animate__fadeIn / 700ms / 无延迟 / offset 0,首屏不再空一片等缩放
  • 删掉两组被注释掉的重复配置(置顶轮播、分类磁贴),换成说明:wowjs.animateitem 的 class 写多个会命中容器内层元素,catalog_magnet 是 id 不是 class

pjax 换页后入场动画不再哑火(新增 scripts/wow-pjax-rehook.js)

  • 原因链(实测确认):卡片的 .wow / data-wow-* 由 hexo-butterfly-wowjs 在 body_end 注入,整块包在 .js-pjax 里且不带 data-pjax;pjax 换页时这段 innerHTML 被整块换成新页面的同款脚本,而新插入 DOM 的 <script> 浏览器不执行 → 卡片身上没有 .wow,wow.js 的 live MutationObserver 也就没有对象可接管,不隐藏、不揭示、无动画
  • 修法:pjax:complete 之后把 .js-pjax 里这批哑火的加类脚本换成新节点重放(刻意复用插件自己的脚本,动画参数永远跟着 wowjs.animateitem 走,换页后与首屏一致),再 wow.doSync(document.body) 让新卡片重新进待揭示队列,并清掉 wow.boxes 里已被 pjax 换掉的旧节点;暴露 window.__wowPjaxRehookNow 便于手动触发,删掉本文件即卸载

归档页与评论区两处小修

  • 归档页年份胶囊居中改用 track.scrollBy:原来 scrollIntoView 与全局 html{scroll-padding-top:70px} 打架,每跨一个年份就把窗口往上顶 61px,顶栏方向检测跟着反复翻转(滚起来一顿一顿 + 导航栏抖动)。现在只横向滚动胶囊条,不带动整页;新增 --ar-bar-h(默认 55px),年份标题 sticky 位置改成 calc(var(--ar-nav-h, 0px) + var(--ar-bar-h, 55px)),不再钻到吸顶胶囊条底下;对 #page-header 监听 nav-fixed,pjax 往返复用同一套监听(source/js/inject/archive-page.js、source/css/archive-page.css)
  • 评论区楼中楼:每条 .tk-comment 自带 z-index: 1 自成层叠上下文,回复框里的 OwO 面板被关在这条评论内部,排在后面的评论卡同为 1 层、DOM 更靠后,于是压到「颜文字 / Emoji / QQ…」那一行,表情类型点不动。.twikoo .tk-comment:has(.OwO-open) 只在展开期间临时提到 z-index: 3,关掉即回落(source/css/twikoo.css)

回归脚本与文档

  • tools/tests 从 13 个脚本加到 14 个:新增 daynight-boot.test.cjs,用 node:test + vm 钉住「现在」,覆盖站点旋钮(enabled / latLng / themeKey 与运行期 setConfig)、手动选择优先与过期清理、「8 小时自动切换」是否听总开关
  • README 更新日志补 v1.0.5 一节,文件地图补 daynight-boot.js / wow-pjax-rehook.js / daynight-boot.test.cjs 三行,7.5 回归脚本表与跑法更新;示例站(Hello World、关于页、时间线)同步

升级提示

覆盖 themes/fomalhaut/ 与 source/ 下对应文件即可,配置项没有破坏性变更。两层新行为都在 _config.fomalhaut.yml 的 inject.head 里各一行:window.fomalNightConfig 内联脚本 + daynight-boot.js?v=20261014-nightboot2,不想要就删掉这两行 —— 首页的侧栏日历自带完整实现不受影响,非首页退回主题默认 light(即本版修复之前的样子)。scripts/wow-pjax-rehook.js 是站点级脚本,删除即卸载。老配置里的坐标旋钮(aside-calendar.js 的 CONFIG)仍然有效,启动时会汇报给共享实现。

v1.0.4 — 美化面板预览化与导航改版

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 11 Oct 10:02

美化设置面板从一条长滑条拆成能实时预览的分区,顶栏导航抽出一份独立样式表并按设备能力降级,夜间切换换成三段小动画,另修一批小毛病(数字框裁切、目录连点互抢、搜索提示残留、帧率条对比度)。

美化设置面板(source/js/modules/settings.js 重写)

  • 面板按 氛围特效 / 互动挂件 / 布局与部件 三块排(两列网格、面板变窄自动单列),再加主题色 / 字体 / 背景分区;卡片不透明度与背景滤镜挪到最上面
  • 关掉就是真的停:setNekoEnabled() 清掉猫咪的定时器与 requestAnimationFrame,cursor.setEnabled(false) 走 pause() + observer.disconnect(),指针路径提前返回;source/js/inject/beauty-boot.js 首帧先恢复隐藏态,避免加载瞬间闪一下
  • 每个开关与滑条都有实时预览,不再需要「只样式开过才算开」

主题色

  • 面板加原生取色圆(视觉直径 24px、热区 44px、环宽 3px),值以严格校验的六位 HEX 存 themeCustomColor,首帧校验不合法就回滚默认青绿
  • 预设删掉「紫 / 灰 / 黑」三个旧选项、补上 抹茶绿,一共十一色(红 / 橙 / 黄 / 抹茶 / 青绿 / 玉石绿 / 晴空蓝 / 柔靛蓝 / 雾灰蓝 / 紫罗兰 / 樱花粉);旧键自动迁移(purple → purplepure、gray / black → darkblue)
  • 新增 themeOnColorInk():按 WCAG 相对亮度算 --on-theme / --on-theme-away,按钮、选中项、目录当前页、::selection 与 AI 助手面板都读它 —— 浅色主题色上不再白字发虚

字体与背景预览化(新增两个模块)

  • source/js/modules/appearance-fonts.js:字体 5 / 个性 3 / 代码 4 三组(含「系统默认」),正文与代码各一块实时预览;只对合法 key 请求 document.fonts.load,12 秒超时、最新请求胜、失败不写好偏好可重试;「恢复默认」只重置两个字体键
  • source/js/modules/appearance-backgrounds.js:32 张壁纸 + 8 个渐变 + 7 个纯色 + 8 张在线接口图一屏管完,一级分「壁纸 / 色彩 / 自定义」、壁纸再分四类;打开分类才给 <img> 赋 src,切换走 Image 预加载 + token 取消,失败保留旧图
  • 两个模块都是全局脚本,在 settings.js 之前加载;旧的 setFont / setCodeFont / setBg / resetBg_ 契约不变,原来的入口照常可用

两个新特效 + 一个老特效重写

  • 萤火虫(source/js/modules/fireflies.js,默认关闭):纯 CSS 呼吸与漂移,不起 canvas / rAF / 定时器轮询;桌面 14 只、≤600px 8 只,待机在底部 44vh、层级在正文卡片之后;pointer-events: none,暂停靠 data-paused
  • 雪花重写(source/js/modules/snow.js):删掉 effects.js 里的 canvas 圆点循环,改用两张预渲染雪片按大小 / 透明度 / 速度分层下落;dt 上限 50ms、epoch 防过期回归、厚度随视口 14–30px;深色 / 后台 / 手机 / 减少动态都暂停,并与萤火虫互斥(只留最后开启的一项)
  • 点击涟漪(source/js/modules/ripple.js,默认关闭):按下那刻才建 1 个爆发节点 + 两圈同心水纹,700ms 后连节点一起回收,同时最多 6 枚;只认主指针左键,关闭时连 pointerdown 监听都不挂

顶栏导航(新增 source/css/navigation.css)

  • 桌面工具区 44×44px 触控区、间距 8px、两侧留白 24px;≤800px 收到 4px / 12px,≤480px 站名 20px;769–800px 隐藏标题,免得挤工具区
  • 磨砂按能力降级:默认只留 alpha 0.96 底色,≥1200px + 精细指针 + 支持 hover + 未开减少动态时才开 6px
  • 站名容器允许 overflow: visible,霓虹光晕不再被 overflow: hidden 一刀切掉(顺带救回主题 15px 文字阴影与首页 hover 伪元素),只有 ≤360px 才保留省略号保护
  • 首页按钮:伪元素宽度改成跟随站名链接 100%(原来只盖住文字宽度),高度收到 40px,图标改 flex 居中

调度与生命周期修正

  • scroll-gap-fix 升到 v4,加世代号 seq:过期的滚动校正立刻退出(v3 每次点击各起一条最多 3 轮校正、互不知情、先后停稳后轮流把页面拉回自己那边),作废次数记在 window.__scrollGapFix.state
  • 搜索模块四修:卡住的「正在加载…」提示改成脚本自持节点 .search-lazy-tip(插在 #algolia-hits 之前);库就绪后 300ms 检查 .ais-SearchBox-input,缺失就回 IDLE 并提示失败可重试;新增本地搜索历史(最多 8 条、去重、最新在前、可删除 / 一键清空);结果链接改写成同域 —— Algolia 索引里的 url 是按 _config.yml 的 url 写的正式域,本地与镜像域名下点结果会跳出去
  • 目录连点互抢同样用 seq 解决(失效的滚动校正立刻退出)
  • shell.js 重写昼夜切换:日落 / 日出 450ms + 暮色与第一批星 450ms + 星夜铺满 600ms + 圆形揭幕 350ms,整屏遮挡 3000ms 压到约 900ms;面板给「关闭 / 轻 / 标准 / 华丽」四档;遮罩改由本次切换自己持有(旧写法连点两次会操作到别人的那一段,极端情况留下永久盖住整页的残留)
  • 夜间壁纸预热:空闲时按 --darkmode-bg 提前拉一次(requestIdleCallback,兜底 2.5 秒),切过去不再出现「背景还在加载」的空白
  • 数字框与帧率条:数字框原主题宽 50px,靠 :is(…) 特异性 + max-width: none + min-width: 0 扩到 76×44px;数字与逐字稿一并换同一套选择器;帧率条底色用 data-state 着色、小字对比度 3.21 → 4.91,并跟随赏心悦色回溯(琥珀与红的 Lab ΔE 从 43.2 拉到 63.5)

回归脚本与文档

  • tools/tests 从 5 个脚本加到 13 个(新增 beauty-switches / theme-color / appearance-fonts / appearance-backgrounds / fireflies / snow / ripple / navigation),旧的 cursor-effects、fps-lifecycle 同步更新
  • README 更新日志补 v1.0.4 一节,文件地图补 navigation.css 与 5 个模块,7.5 回归脚本表与跑法更新;docs/plans/ 补上 9 份设计记录

升级提示

覆盖 themes/fomalhaut/ 与 source/ 下对应文件即可,配置项没有破坏性变更。新增的 CSS 与模块都在 _config.fomalhaut.yml 的 inject.head / inject_bottom 里有两行引入(带 ?v= 缓存串),删掉即回到主题源码原样;老版美化面板的设置键全部兼容(含旧的紫 / 灰 / 黑三项自动迁移)。

v1.0.3 — 归档页卡片改版与时间轴统计

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 08 Oct 16:55

归档页换成卡片墙,时间线统计拆细,另修一个 pjax 老 bug。这一版没有改主题模板,全部是站点级新增文件 + 两行注入。

归档页卡片改版(新增 3 个文件)

  • scripts/archive-index.js:构建期注册 after_render:html 过滤器,只往归档页(含 /archives/page/N/)的 </head> 前插一段 <script type="application/json" id="ar-index">,内容是全站每篇文章的标题 / 路径 / 日期 / 首个分类 / 字数 / 阅读分钟 —— 卡片上的分类与阅读时长因此不产生任何额外请求
  • source/css/archive-page.css:归档页外观(年度分布柱、年份胶囊、年份章节、卡片栅格),选择器全部以 .ar-ready 开头;列宽一律 minmax(0, 1fr) + min-width: 0,配色由 --theme-color / --font-color / --card-bg 经 color-mix 派生,跟随主题色与暗色模式
  • source/js/inject/archive-page.js:行为层,只读主题渲染好的 .article-sort 就地重排
  • 版面自下而上:年度分布柱状图(每根柱带 title「2026 年 · 3 篇」;年份跨度 ≤ 7 年时逐格画满,超过就只画有文章的年份,避免一整排空柱)→ 汇总「共 N 篇 · 起始年–末年 · 某年最多(N 篇)」→ 年份吸顶跳转胶囊(滚动高亮当前年份,点击平滑滚动、改 hash 但不新增历史记录,并按固定导航的实际高度留出偏移)→ 年份章节(大号年份 + 条数 + 收起 / 展开,折叠状态记在 localStorage 的 ar-collapsed-years)→ 卡片栅格
  • 卡片:封面 + 分类胶囊 + 标题 + 日期 + 「约 N 分钟」;整卡可点,标题与封面仍是各自的链接(可新窗口打开、可被爬虫抓);封面缺失或加载失败退回「标题首字 + 主题色光晕」占位;懒加载占位图直接读 data-lazy-src 补真图,不等 LazyLoad 的扫描时机
  • 阅读时长复用 hexo-wordcount-fomal 的口径(中文 300 字/分、英文 160 词/分);匹配不到就退回当前页条数
  • 降级与守卫:容器必须是 #archive / #category / #tag 之一、.article-sort 恰好 1 个、且至少有一篇文章,全部满足才给容器加 .ar-ready——任一不成立就整块失效、页面原样;容器上打 data-ar-archive 保幂等,首屏 / pjax:complete / pageshow(persisted) 都能安全重入
  • 同一套样式与脚本对 /categories/*、/tags/* 生效;根 _config.yml 新增 archive_generator(per_page: 12、按年 / 按月生成、order_by: -date,卡片 3 列刚好 4 行整)

时间线档案页统计拆细

  • 头部原来只有一个「天数」,现在拆成 更新天数(日期卡数)与 记录条数(正文条目数),再补一个 历时:首尾日期差的天数 + 「约 X 年 Y 个月」(按 30.4375 天/月折算)
  • 新增 countEntries() 数 .timeline-item-content 里第一层 :scope > ol/ul > li,作为「记录条数」的口径
  • 年份分隔器文案改「N 条记录 · M 天」;年份胶囊只写条数,底部多一条占比细条(宽度 = 该年条数 ÷ 全站条数)
  • 版面:左栏日期轨 --tl-rail 104px → 62px、列间距 --tl-gap 28px → 18px(1440px 屏卡片宽约 +52px);窄屏 ≤768px 改单列,日期挪到卡片上方一行小字

日历热力图 pjax 修复

  • gitcalendar.js 里文件级的 var git_init_seq = 0 挪到 window.__gitInitSeq:pjax 换页时先执行内联脚本、再加载外链脚本,后者把计数器重置回 0,于是 fetch 回来的数据被判成过期直接丢弃 —— 表现就是日历一直停在加载态,刷新一次又好了

内容

  • source/life/music/index.md 歌单换成网易云「[轻音乐纯享]何人都有孤独之时」(105 首),热评区块同步换新

文档

  • README 新增「更新日志 → v1.0.3」,文件地图补上新增的三个文件,并新增 8.13 归档页卡片(/archives/):一张「想改什么 → 去哪儿改」表 + 回滚说明
  • 顺手修掉 v1.0.2 删除 CI 工作流后残留的三处过时引用(「新增功能」表、目录结构树、部署方案 A),并修正文件地图里 7.5 / 7.6 的小节编号断档

升级提示

覆盖 themes/fomalhaut/ 与 source/ 下对应文件即可,配置项没有破坏性变更。想用归档页卡片:确认 _config.yml 里有 archive_generator 段、且 _config.fomalhaut.yml 的 inject.head 里有两行 archive-page.css / archive-page.js 引入;不想用就删掉那两行,页面立刻回到主题原样。

回归脚本 5 个、共 119 个用例,跑法 node --test "tools/tests/*.test.cjs"。

版本号解耦(补记,10-09 01:12)

  • 新增 themes/fomalhaut/scripts/butterfly-version.js:把「fork 自哪个上游 Butterfly」(4.3.1)与「主题自身版本」(package.json 的 version,仍是 1.0.3)拆成两个来源
  • scripts/events/welcome.js 的启动横幅、scripts/events/cdn.js 的 jsdelivr / unpkg 地址改读该常量:此前两处都取主题自己的 package.json,主题一升版本,CDN 地址就被拼成 hexo-theme-butterfly@1.0.3(上游没有这个版本),开 internal_provider: jsdelivr 的站点会整片 404
  • 根 README 的「更新日志 → v1.0.3」与文件地图同步补记
  • 升级:覆盖 themes/fomalhaut/scripts/ 下的 welcome.js、cdn.js,并补上新增的 butterfly-version.js

Full Changelog: v1.0.2...v1.0.3

v1.0.2 — 流式渲染与缓存策略

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 06 Oct 07:07

流式渲染与缓存策略。集中修三类「用久了才显出来」的问题:AI 助手吐字时掉帧、Service Worker 该失效时不失效、窄屏被撑出横向滚动。回归脚本从 4 个加到 5 个。

AI 助手流式渲染

  • 分片只累积文本,DOM 提交合并到一帧:requestAnimationFrame 提交,配 100ms setTimeout 兜底,同一帧里只保留最后一次待提交内容
  • 每帧只重建「尾巴」:新增 tailCut(),逐行扫出可定稿的切点(不在代码围栏内、不在有序列表项中间、行内 ** 与 [ ] 成对),已定稿部分一次性追加,尾块单独放进 .ai-tail 容器
  • 滚动改成只写不读:passive scroll 事件异步维护 stick 标记,写位置用 b.scrollTop = 1e9,省掉读 scrollHeight 触发的强制布局;手动往上滚不再跟随,滚回底部自动恢复
  • 面板空闲或悬停时预热(requestIdleCallback + pointerenter),提前建好 DOM 并强制一次样式布局
  • 实测:三条 20 秒突发流 63.7 / 67.6 fps → 89.7 / 89.9 / 90.0 fps,超过 50ms 的卡顿帧从 94 / 73 降到 0,强制布局累计 5925 / 7015ms 降到 82 / 106 / 107ms

Service Worker 缓存策略

  • CACHE_NAME 提到 ICDNCache-v3,老访客激活时整体丢掉 v2 残片
  • TTL 拆成两档:文本资源(html / js / mjs / css / json / xml / txt / map / webmanifest / manifest / svg)10 分钟,图片、字体、音视频仍按 24 小时 —— 原来全按 24 小时,发版只改 JS/CSS 又忘了同步改 ?v= 缓存戳时,回访者会继续跑旧代码最长一天
  • getFileType() 补齐 17 种扩展(cur / avif / bmp / apng / otf / eot / xml / txt / map / webmanifest / manifest / mp3 / m4a / mp4 / webm / pdf / wasm),原先一律回退 text/plain
  • 线路探测请求(?__pr=)不再写入 CacheStorage,只做「改写 + 回源」—— 探测每次都是新的随机串,写进去的条目以后永远读不到,而首屏、每次 pjax、每 5 分钟各来一轮

主题色联动

  • 日历热力图新增 git_theme_palette():直接读 --theme-color 实时生成 10 档调色板,换主题色自动重画(只在颜色真变了时清空重绘);_config.yml 里的 gitcalendar.color 退化为兜底值

指针与滚动

  • 小猫咪光标加两个 WeakMap 缓存(控件身份 + 祖先 cursor:pointer 链),MutationObserver 加过滤:光标自身、.neko 的 data-msg、#fps 的 title 等纯输出改动不再触发整轮重算
  • 回形针在窄屏会撑出约 10px 横向溢出,改 --clip-right: calc(-21px + max(0px, 23px - (100vw - 100%) / 2))
  • 时间线归档页与年表把固定轨道改成 minmax(0, 1fr) 并补 min-width: 0,长不可断词不再把页面顶宽

细节修正

  • 设置面板复选框去掉 translateY(5px);.colorRow 补 user-select: none 与 caret-color: transparent,点空隙不再落编辑光标
  • 关于页第 5 层「结构化存储」去掉站长的私人数据源,只留评论数据
  • 页脚主题版本号与 npmmirror 徽章同步(换成已去掉阴影的那一版)
  • 删掉开源仓库里的 .github/workflows/autodeploy.yml:它缺少对应 secrets,每次 push 都必然失败

回归脚本

  • 新增 tools/tests/sw-cache.test.cjs:纯 VM 跑 Service Worker 源码(caches / fetch / Response 全打桩,不联网、不起服务),9 项断言覆盖域名白名单、回源写缓存、二次请求吃缓存、文本与媒体的 TTL 分流、?__pr= 不写缓存
  • tools/tests/cursor-effects.test.cjs 随指针缓存重构扩充
  • 跑法:node --test "tools/tests/*.test.cjs"(共 119 个用例)

升级提示

覆盖 themes/fomalhaut/ 与 source/ 下对应文件即可,配置项没有破坏性变更。注意 Service Worker 换了缓存名(v3),上线后老访客的 v2 缓存会被自动清掉,第一次访问会重新拉一遍资源。

Full Changelog: v1.0.1...v1.0.2

v1.0.1 — 首屏关键链、动画生命周期与滚动性能打磨

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 05 Oct 11:05

首屏更快、动画不白跑、滚动不掉帧。这一版没有新增页面,是对 v1.0.0 的一次集中打磨。

首屏关键链

  • 默认正文字体补上 preload(带 crossorigin,字体按 CORS 模式取),浏览器不用再等 index.css 解析完才发现字体
  • 夜间默认壁纸与 source/js/modules/settings.js 的 resetBg_() 对齐到逐字一致的地址,避免同一张图下两份

动画与帧率生命周期

  • 雪花 / 星空:从「不可见就跳过绘制」升级为「不可见即退出 rAF」,恢复交给 MutationObserver / resize / pjax:complete 的失效回调
  • 帧率监测改成「面板开着才起循环」,采样封装成带 generation 的闭包,切后台自动挂起

滚动与指针

  • 修掉主题里 window.scrollCollect = () => btf.throttle(fn, 200)() 这种「工厂 + 当场调用」的假节流 —— 原来每次滚动都会新建一个 throttle 再执行,节流形同虚设
  • btf.throttle 补 cancel();pjax.pug 里手写的两处解绑统一收进清理函数
  • 小猫咪光标改成读写分离:高频指针输入只记最新值,下一帧先读几何再增量写,写入值用 WeakMap 缓存
  • 手机端自绘滚动条:滚动 / 布局值在读阶段一次采完,节点创建与样式写入放写阶段

样式

  • 评论区重做(source/css/twikoo.css):三张独立白卡浮在压灰一档的面板上,配整块焦点环
  • 侧栏作者卡新增回形针装饰(新增 source/css/paperclip.css):内联 SVG、18° 倾角、针身探出卡片边缘;夜间自动切成冰蓝夜光

工程与清理

  • 新增 4 个回归脚本(tools/tests/,Node 自带 node:test,共 50 个用例):光标效果、帧率生命周期、手机滚动条、滚动监听
    • 跑法:node --test "tools/tests/*.test.cjs"
  • 新增 docs/plans/2026-10-05-paperclip.md,记录回形针的设计参数与回滚方式
  • 删除 15 个死文件:leaves.js、bibi.js、love.js、tag-map 的 proj4 两条、local-search.js、tw_cn.js 与 8 个不再引用的图片
  • 修好控制台字符画的版式与版权行(版权年份改为运行时计算)
  • error_img 的兜底图改用主题自带的 /img/friend_404.gif 与 /img/404.jpg
  • README 新增「更新日志」小节,顶部补 Stars / Forks 与 Star History 图

升级提示

从 v1.0.0 升级:直接覆盖 themes/fomalhaut/ 与 source/ 下对应文件即可,配置项没有破坏性变更。

Full Changelog: v1.0.0...v1.0.1

v1.0.0 — 主题独立为 fomalhaut

Choose a tag to compare

@fomalhaut1998 fomalhaut1998 released this 05 Oct 11:07

首个正式版本。主题从 themes/butterfly 独立为 themes/fomalhaut,站点配置与主题代码彻底分离 —— 改配置就能搭起自己的站,升级主题不会冲掉你自己的改动。

相比仓库历史里的 3.22 版

项 旧版 (3.22) 本版 (v1.0.0)
主题目录 themes/butterfly/ themes/fomalhaut/
主题包名 hexo-theme-fomalhaut v4.3.1(沿用 Butterfly 的 package.json) hexo-theme-fomalhaut v1.0.0(独立版本号)
主题配置 _config.butterfly.yml _config.fomalhaut.yml
配置注入 少量 inject 完整 inject.head / inject.bottom + 独立 css/js 文件

工程化

  • fomal.js 从 2973 行拆成 105 行主引导 + 10 个模块(source/js/modules/)与 10 个注入脚本(source/js/inject/)
  • 配置里的 26 段内联样式与脚本抽成 source/css/site-inject.css 与独立 js,配置文件从 2037 行瘦到 1482 行
  • themes/fomalhaut/source/css/_custom/custom.css 删掉 341 行死代码,并补上完整的文件头索引地图

功能

  • AI 助手:前端 + Vercel / Cloudflare Pages 双平台同源代理,Key 走环境变量,不随页面下发
  • 美化设置面板:访客可自选字体、主题色、背景、显示偏好,设置存 localStorage
  • 侧栏日历与倒计时:带农历、二十四节气与节日提醒
  • 手机端抽屉、网站统计页、时间线归档、网址导航、天文星图
  • PWA + Service Worker 离线预缓存与请求分流
  • 多平台部署:GitHub Actions / Vercel / Cloudflare Pages

资源

  • 图片与字体统一走公共 CDN(jsDelivr 的 @fontsource/*、picsum.photos),不依赖任何私人服务
  • 字体精简为 6 款开源可商用字体(SIL OFL)
  • 示例数据全部替换为占位(站点名 Demo、域名 example.com、统计 ID 占位)

文档

  • 根 README 重写为完整文档(约 1000 行):项目架构、相比上一版的变化、环境要求、10 分钟快速开始、目录结构与文件地图、12 类功能的逐项配置、怎么写文章、最常改的地方、外挂标签速查、部署与常见问题
  • 新增 repoPic/screenshot/ 4 张界面截图

完整文档见 README