崮生(子虚)
|
cc792d27b0
|
fix: 更新字体输出格式为 ttf,优化加载性能
|
2026-08-27 06:06:42 +08:00 |
|
崮生(子虚)
|
8e2c68e6f9
|
docs: uni-webfont 补 README/LICENSE;依赖改 npm 语义版本(webfont-sdk ^0.2.1)
|
2026-08-16 15:10:08 +08:00 |
|
崮生(子虚)
|
67b29487be
|
chore: dist-bundle 加入 gitignore 并移除误提交的构建中间产物(真实载体是 uni_modules/gs-webfont)
|
2026-08-16 15:03:40 +08:00 |
|
崮生(子虚)
|
140f84d3c7
|
feat: uni-app 插件 gs-webfont —— 字体按需加载(子集化)上线准备
- webfont-sdk 引擎修复两处并发池 bug(原版排队分支丢任务;闭包复用会让
队列真身丢失导致 pending 卡死),新增 per-state provider 与 submitText 分批
- 新增 packages/uni-webfont:字符累积 + uni.loadFontFace 同 family 重载策略,
串行保序(maxConcurrent=1),二次 loadFont 从引擎播种累积集
- 产物同步 uni_modules/gs-webfont/js_sdk(自包含 ESM+iife+d.ts)
- 端到端验证:mock 全绿;线上真实服务 4 字 → 10.1KB 合法 TTF
|
2026-08-16 10:34:40 +08:00 |
|
崮生(子虚)
|
f9160950ea
|
chore: 1.13.0 —— demo 页引用 leafer-x-webfont@latest(importmap 统一)
|
2026-08-15 23:31:22 +08:00 |
|
崮生(子虚)
|
5c85a2ebe7
|
chore(leafer-x-webfont): 0.2.0 发布 + demo CDN 引用统一 importmap @latest
- npm 0.2.0:脏节点增量扫描 + 贡献者回记 + 百万节点零风暴(见 0ab51e4)
- demo 页三个裸导入统一进 importmap,版本引用 0.1.0/0.2.0 混用 → 全部 @latest
|
2026-08-15 23:27:42 +08:00 |
|
崮生(子虚)
|
0ab51e496c
|
perf(leafer-x-webfont): 注册回调贡献者回记+静默链应用,百万节点打字场景零风暴
问题(1M Text 节点实测):
- v0 字体注册回调里全树改写 fontFamily:百万次 property.change 污染
dirty 集,打字场景退化 20s;单点改动 978ms
- 公共 setter 路径(v2):百万次完整属性变更管线 = 2.2s 风暴
方案(v4):
- 贡献者回记:commit 时合并累加每个 family 的贡献节点(不覆盖,
迟到 chunk 仍能找到贡献者),chunk 回调只把贡献者标脏——链应用
范围从全树缩小到实际用字节点,打字场景 O(1)
- 静默/公共写分流:溢出(初始全量等贡献者>512)走静默写 __ 数据层
(~50ns/次,不触发事件不污染 dirty);少量贡献者走公共 setter
(leafer 自动局部重绘该节点)
- ready() 语义闭环:字体全部落地后同步消化残留 dirtyAll/renderPending,
否则会被下一个不相关的用户操作捡走——表现为「改一个字卡 800ms」
- forceRender 收敛:仅静默写/浏览器模式标记 renderPending,flush 尾部
无 in-flight chunk 时合并成一次执行
实测(1M Text,真实 leafer + 本地后端):
- 单点改动 flush: 856ms → 0.15ms
- 随机100节点 flush: 0.9ms
- 新增 Text: 0.08ms
- 打字同步按键成本: 0.2ms/次(与无插件基线 0.012ms 同数量级)
- 拖拽等无文字变化操作: 0 请求 0 提交
|
2026-08-15 21:13:07 +08:00 |
|
崮生(子虚)
|
ca1d2fc1e7
|
feat(webfont-sdk): 0.2.0 新增服务端 API 客户端子路径 webfont-sdk/api
- createWebFontApi 工厂封装全部 6 个 REST 接口(fonts/fontMeta/
config/stats/upload/reportEvent)+ 全套类型,独立子路径导出不进主入口
- leafer demo 删除硬编码 FONTS 数组,改 api.fonts() 实时拉取
(24 个字体 vs 原硬编码 6 个),初始字体带回退、失败显式报错
- 主站 src/api.ts 重写为 SDK 客户端薄适配层(dogfooding):
旧类型名保留为别名组件零改动,顺带消灭 FontInfo 重复声明
- /docs 文档页新增 npm 安装、双模式用法、API 客户端示例(中英)
- 主站 package.json 添加 workspace 依赖 webfont-sdk
已发布 npm webfont-sdk@0.2.0,CDN 与 demo 端到端验证通过。
|
2026-08-15 20:35:17 +08:00 |
|
崮生(子虚)
|
b385bc89bc
|
perf(leafer-x-webfont): 脏节点集增量扫描,百万节点画布可正常运行
全量 walk O(全树) 改为事件驱动增量:
- property.change 携带 target(PropertyEvent 五参构造)→ 精确记脏节点
- child.add/remove 携带 child → 整棵子树入脏集(构造期赋值不走 setAttr)
- 订阅集与 Leafer 自家 Watcher 相同(property.change + child.*),
渲染可靠 = 事件可靠;不再订阅 layout.end(每帧触发,百万级下
周期性全量 walk 是持续卡顿源)
- 脏节点 >512 退化全量(模板整体替换场景全量更省)
- 全量/增量共用 collect/walkInto/commit,指纹短路保证无变化时
update 调用归零
- 新增 provider 透传(测试/私有部署)、flushNow(跳过防抖立即提交)、
updateCalls 计数(量化指纹短路效果)
压力测试(_prof_million.entry.ts,1M Text 节点):
- 初始全量 scan: ~580ms(一次性)
- 打字稳态(emit+flush): 0.024ms/键
- 无文字变化 flush ×100: 0.16ms,update=0
- 内存: 指纹表 O(family 数),与节点数无关
真实 leafer 验证(scripts/test-leafer-incremental.mts):
初始添加/改文字/新增子树全自动捕获,拖拽 50 次 0 请求 0 提交。
附带修复 dev 后端启动:llrt_lr.ts 改动态 import + fsReady
(createRequire 与 tsx ESM loader 模块图隔离导致 implInterface
注册到孤儿实例,mkdir undefined)。
|
2026-08-15 20:19:27 +08:00 |
|
崮生(子虚)
|
bf98a49a79
|
perf(leafer-x-webfont): 按 family 内容指纹短路无变化的 loader.update
拖拽/缩放等操作每帧触发布局事件,防抖后仍会全量重扫并逐 family
调用 loader.update。新增 committed 指纹表:本轮收集的字符集与上次
提交一致时跳过 update,无文字变化的交互中 update 调用归零。
存字符串本身而非 hash,比较为 memcmp 级且零碰撞。
|
2026-08-15 19:13:36 +08:00 |
|
崮生(子虚)
|
64b9ca9a57
|
chore(deps): 全量升级依赖——vite 8.2.1 / jsdom 30 / puppeteer 25.7 / pinyin-pro 3.29 等;unhead 对齐 2.1.17(vite-ssg 内部依赖 2.x,升 3 会双 head 实例)
|
2026-08-15 16:53:44 +08:00 |
|
崮生(子虚)
|
bbfc69e8a6
|
feat: 首页与 README 增加 LeaferJS 插件入口(链接在线 demo)
|
2026-08-15 16:48:04 +08:00 |
|
崮生(子虚)
|
e0cdbccde0
|
Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/undici-8.9.0' into new
|
2026-08-15 16:25:40 +08:00 |
|
崮生(子虚)
|
6c79eeb4ab
|
fix(build): fs 适配层改静态 import 分发——修复 top-level await 与 CJS 构建不兼容(上个提交遗留)
|
2026-08-15 16:24:47 +08:00 |
|
崮生(子虚)
|
c82da2f6ed
|
feat: demo 加源码/npm 链接,构建时复制进主站 dist/leafer-demo/(vite 插件 + sitemap 路由)
|
2026-08-15 16:22:17 +08:00 |
|
崮生(子虚)
|
64b8bcdbe8
|
chore: 恢复 doc 下技术截图跟踪,gitignore 收窄为仅 doc/*.md
|
2026-08-15 16:21:45 +08:00 |
|
崮生(子虚)
|
bbc5d6f8b1
|
feat(demo): 全 CDN 化——leafer-ui/export/插件/SDK 全走 jsDelivr,服务地址本地/线上自适应
|
2026-08-15 16:18:49 +08:00 |
|
崮生(子虚)
|
ec5740c266
|
chore(packages): 补齐两包 npm 发布元数据(LICENSE/README/types 路径修正/author/repository)
|
2026-08-15 16:09:30 +08:00 |
|
dependabot[bot]
|
66f16e7040
|
chore(deps-dev): bump undici from 8.8.0 to 8.9.0
Bumps [undici](https://github.com/nodejs/undici) from 8.8.0 to 8.9.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v8.8.0...v8.9.0)
---
updated-dependencies:
- dependency-name: undici
dependency-version: 8.9.0
dependency-type: direct:development
...
Signed-off-by: dependabot[bot] <support@github.com>
|
2026-08-15 08:09:14 +00:00 |
|
崮生(子虚)
|
8d53425483
|
chore: 移除 doc/ 目录跟踪(商业化文档不入库)
|
2026-08-15 16:06:33 +08:00 |
|
崮生(子虚)
|
a0c2b4aafc
|
feat: webfont-sdk Node 模式 + leafer 版基准测试(双方案并存)
- webfont-sdk: 新增 Node 模式(node-registry),GlobalFonts 注册 + 每 chunk 唯一 family + 逗号链回退
- leafer-x-webfont: fontFamily 链写回(Node 端),scan 链归一化防套娃、rewriteFamily 跳过链形态防抹回
- 修复 pnpm 双实例 bug: @napi-rs/canvas 版本对齐 1.0.6(根与 SDK 同版本共享 .pnpm 条目)
- 基准测试重构: 用例表抽取为 基准测试用例.ts 共享,SSIM 计算收敛到 scripts/ssim.ts
- 新增 基准测试_leafer.test.ts: @leafer-ui/node + Skia 渲染验证(无浏览器),ttf 输出用例 SSIM=1.0000;woff2 用例仅计时(Skia 不吃 woff2,容器验证由 puppeteer 版守护)
- Node 端集成测试 scripts/test-leafer-node.mts(插件链路 SSIM=1.0000)
|
2026-08-15 15:51:42 +08:00 |
|
崮生(子虚)
|
0693521716
|
feat: SDK 抽取为 webfont-sdk npm 包 + leafer-x-webfont 插件(浏览器验证通过)
- packages/webfont-sdk:TS 重写,IncrementalEngine 核心(去重/并发池/失败字符记忆/retryFailed)
- CSS 模式(WebFont)API 与旧 public/webfont-sdk.js 完全兼容
- FontFace 模式(WebFontCanvas)供 Canvas 场景,unicodeRange 注册 + onChunk 回调
- tsdown 双产物:dist/(ESM+dts)+ dist-iife/(script 直引)
- scripts/sync-public.mjs 构建后同步到 public/webfont-sdk.js
- 修复 banner 内嵌套块注释导致的语法错误(/* 重绘 */ 提前闭合 banner)
- packages/leafer-x-webfont:LeaferJS 插件,依赖 webfont-sdk
- 监听 property.change + layout.end 防抖扫描 Text 节点聚合字符
- 新旧 API 兼容(on_/on__、off_/off__)
- 注册后自动改写 fontFamily 为合法 CSS 名(去 .ttf 后缀)
- demo/index.html:海报场景(标题/副标题/字体切换/导出 PNG)本地 vendor 验证通过
- backend/app.ts:fs 适配层改为 top-level await import(修复 dev 模式 mkdir 崩溃)
- doc/:商业化思路一/二评估 + 主动拓客文档
|
2026-08-15 13:07:32 +08:00 |
|
崮生(子虚)
|
fe61bace16
|
fix: 修复所有 TypeScript 类型错误
- 修复 fonteditor-core 模块声明(添加 FontEditor 命名空间、FontType 类型、SubsetOptions 接口)
- 修复 llrt.ts 中 mkdir 和 rm 方法的返回类型问题
- 修复 tcp_server.ts 中 chunk 类型问题(添加 Buffer 类型检查和转换)
- 修复 font_detail.ts 中缺失的 ORIGIN 导入
- 修复 subset.ts 中 subsetQueueTimeoutSeconds 的导入
- 为 Font 类添加 optimize() 和 write() 方法声明
|
2026-08-15 07:38:57 +08:00 |
|
崮生(子虚)
|
dc1ee66fe3
|
修复 temp-cleaner 在 LLRT 上的 unlink 兼容性问题
- 修改 interface.ts: 接受 options.unlink 和 options.rm 作为 FS 适配器的可配置方法
- 修改 llrt.ts: 使用箭头函数 (path) => fs.rm(path) 避免 this 绑定问题
- 修改 app.ts: 通过 __RUNTIME__ 条件编译,仅在 LLRT 运行时引入 llrt.ts
- 修改 tsdown.config.ts: format 从字符串数组改为字符串类型,添加 as const
- 修改 tsconfig.node.json: 添加 node 类型支持
- 新增 backend/global.d.ts: 声明 __RUNTIME__ 全局变量类型
- 修改 .gitignore: 添加 dist_backend_node 目录
- 修改 build-backend.ts: 支持 Node.js 版本构建输出到 dist_backend_node
修复问题:
- LLRT fs/promises 没有 unlink 方法,只有 rm 方法
- CJS 格式不支持 top-level await,改用 IIFE + require
- 条件编译避免 Node.js 版本包含不必要的 LLRT 适配代码
|
2026-08-15 07:02:22 +08:00 |
|
崮生(子虚)
|
d16aa46227
|
feat: 离线裁剪统计 + 企业服务板块 + SDK文档独立页(/docs) + 示例改用observeFont
|
2026-08-06 08:57:48 +08:00 |
|
崮生(子虚)
|
09f434bbcf
|
feat: 离线裁剪页面 + 增量预览 + DEV预览页 + tempUploads统计 + SDK缓存破坏 + UI优化
- 新增离线裁剪页面 /offline-subset(纯浏览器端字体裁剪)
- SDK subsetProvider 抽象,离线页面注入本地裁剪 provider
- 预览用增量裁剪(SDK自动去重),下载用全量裁剪
- 拖放区域支持点击和拖拽选择字体文件
- 新增 DEV 预览页 /__dev(仅 dev 模式路由可达)
- FontDebugPreview 从首页提取为独立页面
- tempUploads 统计字段(全链路+持久化)
- webfont-sdk.js 构建时戳缓存破坏
- 首页导航栏新增离线裁剪入口
- UploadSection 离线裁剪入口合并到游客上传卡片
- SDK 文档代码示例补充 HTML 用法
- 导航栏窄屏换行适配
|
2026-08-03 15:18:01 +08:00 |
|
崮生(子虚)
|
5a7c6a9913
|
fix: LLRT readdir 不兼容 withFileTypes 导致临时字体清理失效
根因:LLRT 的 fs.readdir 返回字符串数组而非 Dirent 对象,
entry.isFile() 抛 TypeError 被 catch 静默吞掉,
导致 evictIfNeeded 和 temp_cleaner 从未执行(线上堆积 108 个文件 992M)。
修复:
- node.ts: readdir 改为先拿文件名再 stat 判断
- temp_cleaner.ts: catch 块加日志不再静默吞错误
同时包含:
- font-config.json homepage 链接修复(删除 3 个 404,修正 2 个)
- FontDetail 字符预览改为可实时编辑
- 添加 scripts/bench.mjs 压测脚本
|
2026-08-01 08:03:33 +08:00 |
|
崮生(子虚)
|
1979d7c81e
|
fix: FontMeta 接口补上 metaVersion 字段声明
|
2026-07-31 00:11:23 +08:00 |
|
崮生(子虚)
|
fa3fa15bf7
|
feat: font-meta 并发限制 + metaVersion 磁盘缓存失效 + 清理废弃参数
- font-meta 首次计算复用 withMemoryGate 并发闸门(与子集化共享内存预算)
- FontMeta 加 metaVersion 版本指纹,算法变更后 .meta.json 自动失效
- 删除 withMemoryGate/initMemoryGate 废弃的 _softLimitMB 参数
- 清理旧 .meta.json 缓存文件
|
2026-07-31 00:10:25 +08:00 |
|
崮生(子虚)
|
98c3c5a6e2
|
fix: 路由切换后滚动到顶部
详情页→列表→另一个详情页时滚动位置保留在前一页的偏移,
用 router.afterEach 统一处理,每次导航回到顶部。
|
2026-07-31 00:06:05 +08:00 |
|
崮生(子虚)
|
3e3e8899d5
|
fix: 修复字体详情页字体未应用——@font-face 替代 link stylesheet
根因:API 返回二进制 woff2 字体文件,但前端用 <link rel="stylesheet">
引用它,浏览器无法将 woff2 二进制作为 CSS 解析,导致字体完全未加载。
修复:
- 用 watchEffect + document.createElement('style') 动态注入 @font-face
声明,通过 src: url(...) 引用 API 返回的 woff2 二进制
- 修正 usageCode 示例代码,展示正确的 @font-face 用法
- 添加 SSG/SSR 守卫(typeof document === 'undefined' 跳过)
验证:document.fonts.check() 返回 true,字体 status 为 loaded
|
2026-07-31 00:03:33 +08:00 |
|
崮生(子虚)
|
6421e7d059
|
fix: extractCodePoints 增加 glyph 轮廓验证 + 删除冗余正文预览卡片
- font_meta.ts: extractCodePoints 新增 createGlyphValidator,对 TrueType 字体
检查 loca 表确认 glyph 有真实轮廓数据(非空),CFF 字体保持原逻辑
- lint 同步去掉 bodyTitle/bodyText(FontDetail 已移除正文预览卡片)
- FontDetail.vue: 删除正文预览区块(与大标题预览功能重叠),移除对应 computed
- allPreviewText 只合并 previewText + charsetPreview
|
2026-07-30 23:50:27 +08:00 |
|
崮生(子虚)
|
afbd4db77c
|
fix: 字体加载合并所有预览文字(previewText+bodyTitle+bodyText+charsetPreview)
之前 <link> 只加载 previewText 的字符子集,导致 bodyTitle/bodyText/charsetPreview
区域显示 fallback serif 而非实际字体。现在 allPreviewText 合并所有预览文字请求子集。
|
2026-07-30 23:43:08 +08:00 |
|
崮生(子虚)
|
7638ce7e2d
|
fix: 移除 FontDetail fallback 默认值 + lint 检查缺失字段 + 使用 CodeBlock 组件
- FontDetail.vue: 移除 DEFAULT_PREVIEW 等硬编码 fallback,config 缺字段时不渲染对应区块(避免显示字体不支持的字符)
- lint-font-config.ts: 新增检查 font/ 目录下所有字体是否都在 config 中有完整配置(previewText/bodyTitle/bodyText/charsetPreview 四个必填字段)
- FontDetail.vue: 使用方法代码块从 <pre><code> 改为 CodeBlock 组件(语法高亮)
|
2026-07-30 23:37:18 +08:00 |
|
崮生(子虚)
|
a095cd0590
|
feat: 详情页全面接入 font-config + 防闪烁
- font-config.json: 新增 bodyTitle/bodyText/charsetPreview 字段
为每个字体配置通过 lint 检查的专属文案
- FontDetail.vue: 正文/字符预览使用 config 字段替代写死文案
大标题/正文/字符预览加 v-if=meta 守卫,消除 hydrate 闪烁
h1 标题使用 displayName
- lint-font-config.ts: 扩展检查范围至所有文本字段
- FontUserConfig 类型同步更新(后端+前端)
|
2026-07-30 23:30:40 +08:00 |
|
崮生(子虚)
|
9397e10aad
|
feat: 字体列表/详情页接入 font-config 配置 + lint 脚本
前端:
- FontList.vue: 卡片使用 router-link 跳转;
展示 displayName/description/previewText/tags;
底部添加字体投稿联系文案
- FontDetail.vue: 预览文字使用 config.previewText 替代写死文案
工具:
- scripts/lint-font-config.ts: 检查 previewText 字符是否被字体支持
- package.json: 添加 lint:font-config 脚本
|
2026-07-30 23:23:30 +08:00 |
|
崮生(子虚)
|
23728ba02b
|
refactor: 回退内存闸门为固定并发(保留分组调度) + 前端改进
后端:
- subset_queue.ts: 移除基于内存的门控(LLRT GC 不释放 RSS),
回退到固定并发模型,保留分组调度优化(相同字体批处理重用缓存)
- config.ts: 恢复 subsetConcurrency / subsetQueueTimeoutSeconds,
移除 subsetMemSoftLimitMB
- routes/subset.ts, app.ts, routes/config.ts: 同步恢复
- api.ts, README: 同步更新
前端:
- FontSelector.vue: 下拉项和触发器标记临时字体(橙色徽章)
- CodeBlock.vue: 新增轻量代码块组件,内置 CSS/HTML/JS 分词高亮(0依赖)
- Home.vue: 集成 CodeBlock 替换原始 <pre> 代码块
|
2026-07-30 23:11:54 +08:00 |
|
崮生(子虚)
|
d2f6717348
|
feat: 排队请求按字体分组,同字体连续处理
- withMemoryGate 新增 groupKey 参数,subset.ts 传入 fontPath
- pickNext: 优先唤醒与上一个相同 groupKey 的等待者
- 同字体请求连续处理:字体 buffer/解析对象在 GC 窗口内被复用
- 大幅降低排队积压时的内存峰值(避免反复加载不同字体)
|
2026-07-30 22:53:39 +08:00 |
|
崮生(子虚)
|
7403414439
|
feat: 用内存水位闸门替代固定并发限制
- subset_queue: 新增 withMemoryGate,基于 RSS 决定排队/执行
- getRssMB: Node 用 process.memoryUsage(),LLRT 用 /proc/self/statm
- 请求完成后主动 __gc() 加速内存回收
- config: SUBSET_MEM_SOFT_LIMIT_MB=600 替代 SUBSET_CONCURRENCY=4
- 小请求可高并发(内存够),大请求自动排队(防 OOM)
|
2026-07-30 22:51:37 +08:00 |
|
崮生(子虚)
|
b86d2fcb53
|
fix: 并发默认调到4,队列超时改为可配(30s)
- SUBSET_CONCURRENCY 默认 2 → 4(900M 内存够用)
- 新增 SUBSET_QUEUE_TIMEOUT 环境变量(默认30秒,原硬编码10秒)
- 压测发现10秒超时太短:50并发只有8成功,其余排队超时
|
2026-07-30 21:46:21 +08:00 |
|
崮生(子虚)
|
65ba984972
|
feat: 字体子集化并发队列控制(服务端+客户端)
后端:
- subset_queue.ts: Semaphore 并发控制器,排队超时返回 503
- subset.ts: fontSubset 调用包裹在 withConcurrencyLimit 中
- config.ts: 新增 SUBSET_CONCURRENCY 环境变量(默认 2)
- routes/config.ts: 暴露 subsetConcurrency 到配置 API
前端:
- api.ts: ServerConfig 新增 subsetConcurrency 字段
- webfont-sdk.js: 客户端并发池(默认 4),setMaxConcurrent API
通过 document.fonts.load 精确追踪字体加载完成释放槽位
|
2026-07-30 21:33:45 +08:00 |
|
崮生(子虚)
|
abd75985b7
|
feat: 临时字体保留时限改为秒为单位(TEMP_RETENTION_SECONDS)
- TEMP_RETENTION_HOURS → TEMP_RETENTION_SECONDS,默认 10800(3小时)
- 前端显示自适应:秒/分钟/小时
- README docker-compose 示例同步更新
|
2026-07-30 21:24:38 +08:00 |
|
崮生(子虚)
|
19b14f58ea
|
feat: 字体元数据三层架构 + 临时字体保留机制 + 列表页覆盖率排序
- font_meta.ts: cmap 解析覆盖率 + name 表提取字体信息(版权/作者/许可) + 人工配置(font-config.json)
- 三层缓存: 进程内存 → .meta.json 磁盘 → font-config.json stat mtime 热更新
- 临时字体保留机制: TEMP_RETENTION_HOURS(默认3h), 超时未使用自动删除
- 列表页: 覆盖率标签 + 按字符集覆盖率排序
- 详情页: 标签/开源链接/简介 + 字体信息面板(设计师/版权/许可)
- 首页: 红色警告提示切勿上传非商用字体 + 显示保留时限
- SSG noindex bug 修复
|
2026-07-30 21:19:09 +08:00 |
|
崮生(子虚)
|
5b82dec19a
|
fix: 首页 header 窄屏适配,按钮文字不换行
- header 外层 flex-wrap: wrap,窄屏时标题与按钮组自动换行
- 按钮组 flex-wrap: nowrap + flex-shrink: 0,保持在一行
- 所有按钮/链接 white-space: nowrap + flex-shrink: 0,文字不折行
|
2026-07-30 20:33:32 +08:00 |
|
崮生(子虚)
|
cdffd4cb57
|
feat: 字体列表页 + 详情页 SSG + LazyTrigger 懒加载组件
- FontList.vue: 字体列表页,卡片网格布局,支持拼音搜索,点击进入详情
- FontDetail.vue: 字体详情页,SSG 模板 + 服务端占位符替换
- LazyTrigger.vue: 可复用懒触发组件,IntersectionObserver 进入视口回调
- 首页添加字体列表入口,FontDetail 返回列表
- placeholders.ts: 前后端共享的占位符常量
- 后端 font_detail.ts: 读取 SSG 模板并替换占位符
|
2026-07-30 20:32:42 +08:00 |
|
崮生(子虚)
|
d064e9bc8f
|
fix: 进度条方向 + 宽度
- 进度条缺少 width:100%,导致 absolute 元素宽度为 0 不可见
- keyframes 改为 scaleX(0→1),从空到满增长(符合进度直觉)
|
2026-07-30 19:53:57 +08:00 |
|
崮生(子虚)
|
3af1a19dce
|
fix: StatsPanel 卡片不显示 — IntersectionObserver 死锁
根因: v-if=data 和 ref=rootRef 在同一元素,data 为 null 时
元素不存在 → observer 无法 observe → data 永远不会加载。
修复: initialLoad() 在 onMounted 时立即调用,不依赖 observer。
IntersectionObserver 仅负责后续轮询的暂停/恢复。
同时修复 formatUptime 中文分支的秒数计算 bug。
|
2026-07-30 17:33:20 +08:00 |
|
崮生(子虚)
|
8273508c79
|
feat: StatsPanel 视口内才轮询 + 底部进度条动画
- IntersectionObserver + document.visibilityState 双条件控制轮询
- 卡片底部进度条 (scaleX 动画),每次刷新数据后重启动画
- 避免不可见时浪费请求
- bump version to 1.11.1
|
2026-07-30 17:26:24 +08:00 |
|
崮生(子虚)
|
5c3ff96c00
|
docs: 更新 README 裁剪性能数据(node 实测亚毫秒级)
node v24 实测令东齐伋复刻体 50 轮 min:拉丁 0.05ms、8 汉字 0.08ms、
千字文88字 0.19ms(ttf),均达亚毫秒级。补充 X-Timing-* 响应头说明。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-07-26 10:57:55 +08:00 |
|
崮生(子虚)
|
1c87e8ff46
|
chore: bump version to 1.9.5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-07-26 10:48:42 +08:00 |
|