@akairos/typeset-studio 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +67 -17
  2. package/dist/assets/index-CVzTRIjV.js +317 -0
  3. package/dist/assets/index-JCv_QmUn.css +1 -0
  4. package/dist/index.html +2 -2
  5. package/dist/lib/adapter.js +1 -1
  6. package/dist/lib/{canvas-renderer-cxnar75n.js → canvas-renderer-wce6xgb2.js} +1 -1
  7. package/dist/lib/{index-zdhqg5f0.js → index-697fkv5y.js} +294 -57
  8. package/dist/lib/{index-h2580xma.js → index-dkwbnaj7.js} +3 -3
  9. package/dist/lib/{index-t9w3p2p9.js → index-qszn98j2.js} +73 -5
  10. package/dist/lib/index.js +3 -3
  11. package/dist/lib/{render-xxd348m1.js → render-064weavx.js} +2 -2
  12. package/package.json +3 -3
  13. package/src/adapter.test.ts +3 -1
  14. package/src/adapter.ts +1 -1
  15. package/src/core/canvas-draw.ts +53 -43
  16. package/src/core/canvas-presets.ts +37 -0
  17. package/src/core/canvas-renderer.test.ts +60 -1
  18. package/src/core/canvas-style.ts +149 -0
  19. package/src/core/engine.ts +2 -0
  20. package/src/core/geometry.ts +4 -3
  21. package/src/core/types.ts +30 -3
  22. package/src/index.ts +4 -0
  23. package/src/server/index.ts +1 -1
  24. package/src/server/routes/slots.test.ts +24 -0
  25. package/src/server/routes/templates.ts +17 -2
  26. package/src/web/App.tsx +27 -7
  27. package/src/web/components/CanvasStyleInspector.tsx +95 -0
  28. package/src/web/components/Header.tsx +25 -10
  29. package/src/web/components/ParamsInspector.tsx +6 -1
  30. package/src/web/components/SaveTemplateModal.tsx +106 -0
  31. package/src/web/components/TemplateDrawer.tsx +323 -0
  32. package/src/web/hooks/useTypeset.ts +3 -1
  33. package/dist/assets/index-3Ko1UCBU.css +0 -1
  34. package/dist/assets/index-De-aHsvp.js +0 -317
  35. package/src/web/components/TemplateModal.tsx +0 -393
package/README.md CHANGED
@@ -20,13 +20,24 @@
20
20
 
21
21
  </div>
22
22
 
23
+ ## 生态与使用者
24
+
25
+ | 项目 | 与 Typeset Studio 的关系 |
26
+ | --- | --- |
27
+ | [zzhub-pipeline](https://github.com/k7airos/zzhub-pipeline) · [`@akairos/pipeline`](https://www.npmjs.com/package/@akairos/pipeline) | 当前图片插件消费方,通过 `@akairos/typeset-studio/adapter` 生成文章封面和贴图页面;负责状态机、素材上传与草稿发布 |
28
+ | [myno](https://github.com/k7airos/myno) | 配套正文编辑与排版工作台;生成可复制的微信 HTML 和样式 JSON,与本包的 PNG 渲染职责互补,互不依赖 |
29
+ | [Obsidian 微信发布插件](https://github.com/k7airos/obsidian-wechat-publish) | 通过本机 Pipeline 间接使用已配置的图片渲染器,不直接依赖本包 |
30
+ | [Kairos Skills](https://github.com/k7airos/kairos-skills) | 指导 Agent 选择模板、准备正文与素材,再调用 Pipeline 渲染 |
31
+
32
+ 本包直接使用 `@chenglou/pretext` 和 `@napi-rs/canvas` 排版与出图;React/Vite 提供交互工作台,Hono/Bun 提供独立 HTTP 服务。自有程序也可直接调用包 API,无需 Pipeline 或任何私有应用。仅渲染 PNG 不需要 Chrome;Pipeline 的微信正文 HTML 导出仍需要浏览器。
33
+
23
34
  ## 📖 定位与核心哲学
24
35
 
25
36
  在内容自动化分发、微信公众号文章与小红书图文制作中,传统的卡片出图方案普遍依赖 **Chrome Headless (Puppeteer / Playwright)**。为了获取最佳排版效果,往往需要在浏览器实例中多次反复渲染、测量高度、试探字号并进行 CDP 通信截屏。这种方式**速度缓慢(单次耗时数秒)、内存占用高、排版结果难以量化微调**。
26
37
 
27
38
  **Typeset Studio** 采取了完全不同的技术路线:**以确定性纯数学几何排版与服务端原生渲染为核心**。
28
39
 
29
- - **⚡ 告别试探性重绘与 Chrome 依赖**:底层依托 `@chenglou/pretext`(纯数学文本分词测距)与 `@napi-rs/canvas`(基于 Rust Skia 的原生图形绘制引擎),彻底脱离无头浏览器。从计算到渲染直接输出高清 PNG,具备**毫秒级出图性能**、**系统原生字体支持**与**像素级确定性**。
40
+ - **原生 PNG 渲染**:底层依托 `@chenglou/pretext` 与 `@napi-rs/canvas`,不使用无头浏览器截图。字体和素材来自渲染机器;性能和最终外观取决于文本长度、页面数量、素材与字体,不承诺跨机器像素一致。
30
41
  - **🧩 双模态运行形态**:
31
42
  1. **独立可视化排版工作台 (Standalone Visual Studio)**:具备类 Vercel 极简黑白美学的 Web 设计器,支持多图瀑布流全景平铺、单图聚焦微调、四大标准出版比例切换、模板持久化与一键直接服务端渲染高清下载。
32
43
  2. **自动化发布流水线插件 (Pipeline Image Renderer Plugin)**:作为标准图像渲染插件,可无缝插拔接入 `zzhub-pipeline` 或任意 CI/CD 内容分发系统,直接通过原生 Canvas 生成图片,彻底替代笨重的 Chrome 截屏方案。
@@ -36,13 +47,13 @@
36
47
  ## ✨ 特性亮点
37
48
 
38
49
  ### 1. 📐 四大标准卡片出版规格
39
- - **微信大图封面 (2.35:1)**:`2350 × 1000px`,专为公众号大图封面定制,强化大字视觉冲击力与主副标空间分割。
50
+ - **微信封面原图 (3.35:1)**:`3350 × 1000px`,左侧 `2350 × 1000px` 裁为大封面,右侧 `1000 × 1000px` 裁为小封面。保留 `wechat-cover-2.35` 配置标识以兼容已有模板。
40
51
  - **通用长图文 / 小红书 (3:4)**:`1080 × 1440px`,支持多页流式/显式切分、智能避让多图与目标填充率二分逼近。
41
52
  - **通用宽屏 (16:9)**:`1920 × 1080px`,适用于技术博客 Banner、横版社交媒体卡片。
42
53
  - **通用正方形 (1:1)**:`1200 × 1200px`,适用于金句摘录、名言卡片、社媒方图。
43
54
 
44
55
  ### 2. 🌊 8 大流式排版预设与自由图层 (Absolute Layer)
45
- - **8 种流式避让算法**:自适应 (`auto`)、居左浮动 (`left`)、居右浮动 (`right`)、居中横幅 (`center`)、交错排版 (`staggered`)、角落软着陆 (`corner-soft`)、底部填满 (`fill`) 与自定义坐标 (`custom`)。
56
+ - **8 种流式避让预设**:自适应 (`auto`)、居左浮动 (`mid-left`)、居右浮动 (`mid-right`)、居中横幅 (`center`)、交错排版 (`staggered`)、角落软着陆 (`corner-soft`)、填充 (`fill`) 与自定义坐标 (`custom`)。
46
57
  - **自由图层穿透**:一键将配图转为绝对定位自由图层,正文自动穿透排版流动,支持任意 `x/y`、宽高、`z-index`、旋转角度(`0~360°`)与透明度。
47
58
 
48
59
  ### 3. 🖼️ 多图瀑布流全景平铺与单图聚焦
@@ -57,10 +68,10 @@
57
68
 
58
69
  ### 5. 💾 模板槽位体系与交集应用逻辑
59
70
  - **三大标准模板槽位**:
60
- - `article_cover`(文章封面,默认 2.35:1)
71
+ - `article_cover`(文章封面原图,默认 3.35:1)
61
72
  - `newspic_cover`(贴图封面,默认 3:4)
62
73
  - `newspic_content`(贴图内容,默认 3:4 多页)
63
- - **账号隔离与平滑回退**:不同公众号/发布账号独立配置各槽位的默认模板;未配置时平滑降级至系统内置预设,程序绝不崩溃中断。
74
+ - **账号槽位与默认模板**:各账号可独立配置槽位;未配置时按全局默认和算法默认回退。显式选择不存在的模板、素材缺失或无法满足分页约束时会报错。
64
75
  - **数量不匹配交集算法**:模板配图数与文章实际配图数不一致时安全应用交集(如 1 对多仅覆盖第 1 张,其余保留用户参数;2 对 1 忽略超出项)。
65
76
 
66
77
  ---
@@ -68,8 +79,8 @@
68
79
  ## 🛠️ 运行环境与依赖要求
69
80
 
70
81
  ### 1. 核心运行时
71
- - **推荐运行环境**:[Bun](https://bun.sh/) `>= 1.2`(强烈推荐,启动仅需 5ms,原生支持 TypeScript 与 Watch 模式)
72
- - **兼容运行环境**:Node.js `>= 20.0` (搭配 `tsx` 或预编译)
82
+ - **推荐运行环境**:[Bun](https://bun.sh/) `>= 1.2`,支持 TypeScript 与 Watch 模式
83
+ - **Node.js 调用**:核心库与 npm 构建提供 Node 入口;独立 HTTP 服务使用 `hono/bun`,按下文使用 Bun 启动。
73
84
 
74
85
  ### 2. 底层关键依赖
75
86
  | 依赖包 | 版本 | 角色与用途 |
@@ -88,7 +99,7 @@
88
99
  ### 1. 克隆与安装依赖
89
100
 
90
101
  ```bash
91
- git clone https://github.com/aatrooox/typeset-studio.git
102
+ git clone https://github.com/k7airos/typeset-studio.git
92
103
  cd typeset-studio
93
104
 
94
105
  # 使用 Bun 一键安装
@@ -100,9 +111,12 @@ bun install
100
111
  单进程同时托管后端 API 与前端 Web 工作台:
101
112
 
102
113
  ```bash
114
+ bun run build
103
115
  bun run server
104
116
  ```
105
117
 
118
+ 首次从源码启动或更新前端后,先构建 `dist/`;服务端托管的是构建后的工作台。
119
+
106
120
  服务启动后输出端口信息,管理员密钥保存在环境变量或 `.env` 中:
107
121
  ```text
108
122
  ┌────────────────────────────────────────────────────────┐
@@ -149,9 +163,31 @@ npm install @akairos/typeset-studio
149
163
 
150
164
  源码联调也可将 `imageRenderer` 指向本项目的 `src/adapter.ts` 或构建后的 `dist/lib/adapter.js`。
151
165
 
152
- 默认使用本地原生 Canvas。需要独立渲染服务时,在流水线进程设置 `TYPESET_STUDIO_URL` 和 `TYPESET_ADMIN_KEY`,适配器会传输本地图片并保存返回的 PNG。
166
+ Pipeline 使用 npm 插件的本地原生 Canvas 方法,不需要另启 HTTP 服务,也不需要管理员密钥。建议通过对象配置指定包目录之外的持久化数据目录,并让独立编辑器使用同一目录:
167
+
168
+ ```json
169
+ {
170
+ "plugins": {
171
+ "imageRenderer": {
172
+ "module": "@akairos/typeset-studio/adapter",
173
+ "options": { "dataDir": "/absolute/path/typeset-data" }
174
+ },
175
+ "markdownRenderer": { "module": "@akairos/myno/adapter", "options": {} }
176
+ }
177
+ }
178
+ ```
153
179
 
154
- 配置后执行 `zzp render --state ...` 或 `zzp run` 即可使用该插件。
180
+ `markdownRenderer` 是可选的配套正文插件;只需要出图时不必启用。Pipeline 将 `options.dataDir` 传为插件子进程的 `TYPESET_DATA_DIR`,已有非空环境变量优先。Pipeline 会屏蔽适配器的远程服务地址和密钥,确保走本地 npm 执行。
181
+
182
+ ```bash
183
+ # 在本仓库运行编辑器,与插件共享模板和 uploads
184
+ TYPESET_DATA_DIR=/absolute/path/typeset-data bun run server
185
+ # 在已有发布任务中渲染;下一步由 status 决定
186
+ zzp status --state ./workflow-state.json --view agent
187
+ zzp render --state ./workflow-state.json
188
+ ```
189
+
190
+ 没有 `zzp run` 命令。完整发布流程见 [Pipeline README](https://github.com/k7airos/zzhub-pipeline#readme)。本包不负责微信上传或草稿创建。
155
191
 
156
192
  ---
157
193
 
@@ -162,7 +198,7 @@ npm install @akairos/typeset-studio
162
198
  ### 1. 服务健康检查 (`GET /api/health`)
163
199
  ```bash
164
200
  curl http://localhost:4890/api/health
165
- # {"status":"ok","name":"Typeset Studio Server","version":"0.2.5"}
201
+ # {"status":"ok","name":"Typeset Studio Server","version":"0.2.6"}
166
202
  ```
167
203
 
168
204
  ### 2. 槽位解析与排版 (`POST /api/render`)
@@ -180,7 +216,7 @@ curl -X POST http://localhost:4890/api/render \
180
216
  ```
181
217
 
182
218
  ### 3. 服务端原生 Canvas 生成 PNG (`POST /api/render/png`)
183
- 直接返回二进制 raw `image/png` 数据流,单次响应仅数十毫秒,0 浏览器内存开销:
219
+ 直接返回二进制 `image/png` 数据流,使用原生 Canvas 渲染:
184
220
  ```bash
185
221
  curl -X POST http://localhost:4890/api/render/png \
186
222
  -H "Content-Type: application/json" \
@@ -235,7 +271,7 @@ typeset-studio/
235
271
  │ │ ├── image-layout.ts # 预设布局坐标计算 (computeSafePresetY) 与边界保护
236
272
  │ │ ├── typography.ts # 跨平台字体回退映射与多阶字号行高计算
237
273
  │ │ ├── template.ts # 模板持久化应用与数量不匹配时的交集算法
238
- │ │ ├── geometry.ts # 4 大标准画布比例几何计算 (2.35:1, 3:4, 16:9, 1:1)
274
+ │ │ ├── geometry.ts # 4 大标准画布比例几何计算 (3.35:1, 3:4, 16:9, 1:1)
239
275
  │ │ └── types.ts # 完整 TypeScript 类型契约
240
276
  │ │
241
277
  │ ├── server/ # Hono 后端服务(运行于 Bun,提供持久化与无头渲染 API)
@@ -284,7 +320,7 @@ bun run build
284
320
  - `src/core/template.test.ts`:模板持久化、配图数量交集应用逻辑验证
285
321
  - `src/core/image-layout.test.ts`:流式排版预设坐标、Page 2 边界安全与陈旧坐标免疫验证
286
322
  - `src/server/routes/slots.test.ts`:三大默认模板槽位、账号配置隔离与回退容错验证
287
- - **当前状态**:`24 / 24` 单元测试通过率 100%。
323
+ - 测试数量与结果以本次执行输出为准;此处不将历史统计作为当前验收结论。
288
324
 
289
325
  ---
290
326
 
@@ -296,7 +332,7 @@ bun run build
296
332
 
297
333
  业务 API(模板、上传、排版)均要求 `X-Admin-Key`。本机编辑器通过真实回环连接自动领取密钥;远程编辑器需在设置中填写密钥。密钥来自 `TYPESET_ADMIN_KEY` 或服务目录的 `.env`,跨域网页不能自动领取。反向代理应使用业务域名,并保留原始 Host。
298
334
 
299
- 远程插件设置 `TYPESET_STUDIO_URL` 与 `TYPESET_ADMIN_KEY`。插件会传输本地图片字节;`/uploads/` 路径表示远程服务的上传文件。`TYPESET_DATA_DIR` 统一控制模板、默认配置和上传文件目录。
335
+ 仅直接使用本包适配器的远程模式时才设置 `TYPESET_STUDIO_URL` 与 `TYPESET_ADMIN_KEY`;Pipeline 调用会屏蔽这两个参数。远程模式传输任务本地图片字节,`/uploads/` 表示远端文件。`TYPESET_DATA_DIR` 统一控制模板、默认配置和上传文件目录。
300
336
 
301
337
  插件的模板选择顺序为:`studioTemplates.cover/content` → 旧调用中的具体 `template` 名称 → 当前账号的用途槽位默认模板。`wechat-cover-split`、`poster-3-4`、`longform-3-4` 只表示 pipeline 渲染模式,不作为 Studio 模板名查询。未知模板会报错。
302
338
 
@@ -306,6 +342,20 @@ bun run build
306
342
 
307
343
  服务默认绑定 `127.0.0.1`;需要局域网或远程访问时设置 `TYPESET_HOST=0.0.0.0`。反向代理请求不能自动取钥。
308
344
 
345
+ ### 模板库与保存
346
+
347
+ 顶部“模板库”以右侧无罩层 Drawer 展开,覆盖样式编辑区,模板按列表展示。套用后保持展开,可连续切换并查看画布;顶部显示“模板名-副本”。点击关闭按钮、再次点击“模板库”或按 Esc 可收起。
348
+
349
+ “保存模板”位于右上角,与导出图片并列。保存弹窗可填写模板名称、选择用途槽位或通用模板;另存为新模板后自动刷新列表,不覆盖来源模板。
350
+
351
+ ### 渐变背景、花纹与边框
352
+
353
+ 右侧“背景、花纹与边框”面板可配置纯色、线性或径向渐变(2–8 个颜色节点、节点位置、角度或中心位置),以及横线、网格、圆点、斜线、波浪、同心圆、放射线、棋盘格和纸张颗粒。花纹支持自定义颜色、透明度和间距;边框支持实线、虚线、双线、四角装饰和渐变描边,可调整颜色、粗细、内缩、圆角和透明度。
354
+
355
+ 模板库新增 9 套 3:4 正文模板:浅草信笺、落日来信、工程蓝图、月蚀光场、旧纸书页、玫瑰邮笺、黄油棋盘、日光放射和雾蓝手账。在模板管理的“全部”或“贴图内容”分类中套用,修改颜色后保存为自己的模板。新预设只补充一次,不覆盖已有模板、不修改默认槽位,也不会反复恢复已删除的预设。
356
+
357
+ 这些配置保存在 `TypesetConfig.canvasStyle` 中,随模板在编辑器、渲染 API 和 Pipeline 中复用,并作用于每一页。程序绘制不依赖素材文件;纸张颗粒使用固定种子,重复出图一致。图片图层会覆盖其下方的底色和花纹,边框最后绘制。原有模板不设置 `canvasStyle` 时继续使用原背景;修改原“背景底色”控件会切换为纯色。
358
+
309
359
  ### 固定模板素材
310
360
 
311
361
  在编辑器上传图片后,在图片卡片开启“固定模板素材”,填写同一模板内唯一的标识(如 `background`、`logo`,仅字母、数字、下划线和短横线)。自由图层模式下,勾选“设为整页背景”可将图片放到文字下方并铺满当前画布;取消勾选恢复勾选前的布局。点击“重置布局”恢复本次上传或应用模板时的尺寸、位置和图层设置,图片来源、说明和素材标识不变。保存模板后,新内容会沿用这些设置;文字按实际内容重新换行、分页。
@@ -337,7 +387,7 @@ templateImageOverrides: {
337
387
  },
338
388
  ```
339
389
 
340
- 对应的 pipeline 命令(需使用支持这些参数的 pipeline 源码或本地安装):
390
+ 对应的 Pipeline 命令(当前 npm 0.19.0 已支持):
341
391
 
342
392
  ```bash
343
393
  zzp render --state /absolute/path/workflow-state.json \
@@ -359,4 +409,4 @@ zzp render --state /absolute/path/workflow-state.json \
359
409
 
360
410
  模板只保存文件或 URL 引用,不嵌入、不自动打包迁移。`/uploads/...` 由实际渲染方的 `TYPESET_DATA_DIR` 解析,本地插件和编辑器应使用同一目录;远程模式使用服务端目录。模板中的绝对路径必须在渲染机器存在,HTTP URL 必须可访问。远程调用会传输任务替换中本地文件的字节,但不会复制原模板素材。缺失固定素材、未知替换标识或重复标识会明确报错,终止出图。
361
411
 
362
- 固定素材和模板优先渲染已随 `@akairos/typeset-studio@0.2.5` 发布。正式 Pipeline 使用 npm 入口;本地源码入口仅用于联调未发布的改动。运行时模板和上传图片不打进 npm 包,应通过 Pipeline 运行时配置包同步。
412
+ 固定素材和模板优先渲染从 `@akairos/typeset-studio@0.2.5` 起提供,Pipeline 0.19.0 固定依赖 0.2.6。正式 Pipeline 使用 npm 入口;本地源码入口仅用于联调。运行时模板和上传图片不打进 npm 包,应通过 Pipeline 的 `typeset-assets-sync` 打包,或自行同步目录与素材;说明见 [运行时配置指南](https://github.com/k7airos/zzhub-pipeline/blob/main/docs/visual-studio-and-config-sync.md)。