customforge 0.1.0-alpha.1 → 0.1.0-alpha.2

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 (38) hide show
  1. package/CHANGELOG.md +37 -11
  2. package/LICENSES/NunitoSans-OFL.txt +93 -0
  3. package/README.md +233 -62
  4. package/README.zh-CN.md +231 -60
  5. package/dist/NunitoSans-Variable.ttf +0 -0
  6. package/dist/ProductCustomizer-rMRyWe7L.js +1624 -0
  7. package/dist/ProductCustomizer-rMRyWe7L.js.map +1 -0
  8. package/dist/core/design.d.ts.map +1 -1
  9. package/dist/core/types.d.ts +35 -4
  10. package/dist/core/types.d.ts.map +1 -1
  11. package/dist/customizer/ProductCustomizer.d.ts +78 -0
  12. package/dist/customizer/ProductCustomizer.d.ts.map +1 -1
  13. package/dist/editor/DesignEditor.d.ts +108 -6
  14. package/dist/editor/DesignEditor.d.ts.map +1 -1
  15. package/dist/editor/DesignHistory.d.ts +27 -0
  16. package/dist/editor/DesignHistory.d.ts.map +1 -0
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -1108
  20. package/dist/index.js.map +1 -1
  21. package/dist/style.css +1319 -0
  22. package/dist/workbench/CustomForgeWorkbench.d.ts +128 -0
  23. package/dist/workbench/CustomForgeWorkbench.d.ts.map +1 -0
  24. package/dist/workbench/assets/catalog.d.ts +8 -0
  25. package/dist/workbench/assets/catalog.d.ts.map +1 -0
  26. package/dist/workbench/config.d.ts +55 -0
  27. package/dist/workbench/config.d.ts.map +1 -0
  28. package/dist/workbench/icons.d.ts +4 -0
  29. package/dist/workbench/icons.d.ts.map +1 -0
  30. package/dist/workbench/index.d.ts +25 -0
  31. package/dist/workbench/index.d.ts.map +1 -0
  32. package/dist/workbench/template.d.ts +3 -0
  33. package/dist/workbench/template.d.ts.map +1 -0
  34. package/dist/workbench/types.d.ts +294 -0
  35. package/dist/workbench/types.d.ts.map +1 -0
  36. package/dist/workbench.js +1920 -0
  37. package/dist/workbench.js.map +1 -0
  38. package/package.json +70 -71
package/README.zh-CN.md CHANGED
@@ -1,23 +1,28 @@
1
- <div align="center">
2
-
3
- # CustomForge
4
-
5
- **让二维纹理画布实时呈现在三维产品上**
6
-
7
- 一个轻量、与前端框架无关的产品定制原型,基于 Fabric.js 和 Three.js 构建浏览器端 2D 到 3D 定制体验
8
-
9
- <p>
10
- <img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white">
11
- <img alt="Vite" src="https://img.shields.io/badge/Vite-8-646CFF?logo=vite&logoColor=white">
12
- <img alt="Three.js" src="https://img.shields.io/badge/Three.js-r185-111111?logo=threedotjs&logoColor=white">
13
- <img alt="Fabric.js" src="https://img.shields.io/badge/Fabric.js-7-DB4D6D">
14
- <img alt="License" src="https://img.shields.io/badge/License-Apache%202.0-2F6F9F">
15
- </p>
16
-
17
- <p>
18
- <a href="./README.md">English</a> |
19
- <strong>中文简体</strong>
20
- </p>
1
+ <div align="center">
2
+
3
+ <img src="./src/workbench/assets/CustomForgeLogo.png" alt="CustomForge Logo" width="136">
4
+
5
+ <h1>CustomForge</h1>
6
+
7
+ <hr>
8
+
9
+ <p><strong>让二维纹理画布实时呈现在三维产品上</strong></p>
10
+
11
+ <p>一个轻量、与前端框架无关的产品定制工具,基于 Fabric.js 和 Three.js 构建浏览器端 2D 到 3D 定制体验</p>
12
+
13
+ <p>
14
+ <a href="./README.md">English</a>
15
+ <span> · </span>
16
+ <strong>简体中文</strong>
17
+ </p>
18
+
19
+ <p>
20
+ <img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-strict-2563EB?style=flat-square&logo=typescript&logoColor=white&labelColor=1F2937">
21
+ <img alt="Vite" src="https://img.shields.io/badge/Vite-8-7C3AED?style=flat-square&logo=vite&logoColor=white&labelColor=1F2937">
22
+ <img alt="Three.js" src="https://img.shields.io/badge/Three.js-r185-27272A?style=flat-square&logo=threedotjs&logoColor=white&labelColor=1F2937">
23
+ <img alt="Fabric.js" src="https://img.shields.io/badge/Fabric.js-7-BE185D?style=flat-square&labelColor=1F2937">
24
+ <img alt="License" src="https://img.shields.io/badge/License-Apache%202.0-0F766E?style=flat-square&logo=apache&logoColor=white&labelColor=1F2937">
25
+ </p>
21
26
 
22
27
  </div>
23
28
 
@@ -35,6 +40,10 @@ CustomForge 将常见的二维设计界面与带 UV 的三维模型连接起来
35
40
  - 使用 OrbitControls 旋转和缩放三维预览
36
41
  - 将合成后的纹理导出为 PNG
37
42
  - 通过版本化 Design JSON 保存和恢复可编辑对象
43
+ - 通过名称、显隐、锁定和顺序管理对象图层
44
+ - 使用设计快照撤销和重做修改
45
+ - 使用可配置的文字、背景和装饰素材 Dialog
46
+ - 通过品牌、文案、主题变量和图标适配默认 Workbench
38
47
 
39
48
  工作台内置了一个程序生成的杯子,无需准备外部资源即可直接运行
40
49
 
@@ -53,27 +62,27 @@ pnpm dev
53
62
 
54
63
  ## npm Alpha 制品
55
64
 
56
- CustomForge 已通过 `alpha` dist-tag 发布到 npm Registry,不同 alpha 版本之间的 API 和 Design JSON Schema 可能发生变化
57
-
58
- 使用以下命令安装当前公开 alpha:
59
-
60
- ```powershell
61
- pnpm add customforge@alpha
62
- ```
63
-
64
- Fabric.js 和 Three.js 会作为传递依赖自动安装
65
-
66
- pnpm 可能提示可选的原生 `canvas` 构建脚本已被忽略,CustomForge 运行在浏览器中,不使用 Node 原生 canvas,因此不需要执行 `pnpm approve-builds`
67
-
68
- 消费项目可以在 `package.json` 中明确记录这一浏览器端选择:
69
-
70
- ```json
71
- {
72
- "pnpm": {
73
- "ignoredBuiltDependencies": ["canvas"]
74
- }
75
- }
76
- ```
65
+ CustomForge 已通过 `alpha` dist-tag 发布到 npm Registry,不同 alpha 版本之间的 API 和 Design JSON Schema 可能发生变化
66
+
67
+ 使用以下命令安装当前公开 alpha:
68
+
69
+ ```powershell
70
+ pnpm add customforge@alpha
71
+ ```
72
+
73
+ Fabric.js 和 Three.js 会作为传递依赖自动安装
74
+
75
+ pnpm 可能提示可选的原生 `canvas` 构建脚本已被忽略,CustomForge 运行在浏览器中,不使用 Node 原生 canvas,因此不需要执行 `pnpm approve-builds`
76
+
77
+ 消费项目可以在 `package.json` 中明确记录这一浏览器端选择:
78
+
79
+ ```json
80
+ {
81
+ "pnpm": {
82
+ "ignoredBuiltDependencies": ["canvas"]
83
+ }
84
+ }
85
+ ```
77
86
 
78
87
  包页面:[npmjs.com/package/customforge](https://www.npmjs.com/package/customforge)
79
88
 
@@ -83,23 +92,23 @@ pnpm 可能提示可选的原生 `canvas` 构建脚本已被忽略,CustomForge
83
92
  pnpm pack:local
84
93
  ```
85
94
 
86
- 命令依次生成 JavaScript、TypeScript 声明、核心样式,检查 npm 文件清单,并创建:
95
+ 命令依次生成 JavaScript、TypeScript 声明和公开样式,检查 npm 文件清单,并创建:
87
96
 
88
97
  ```text
89
- customforge-0.1.0-alpha.1.tgz
90
- ```
91
-
92
- 在独立 Vite TypeScript 项目中安装该本地制品:
93
-
94
- ```powershell
95
- pnpm add D:\projects\3DRendering\core_code\customforge-0.1.0-alpha.1.tgz
96
- ```
98
+ customforge-0.1.0-alpha.2.tgz
99
+ ```
100
+
101
+ 在独立 Vite TypeScript 项目中安装该本地制品:
102
+
103
+ ```powershell
104
+ pnpm add D:\projects\3DRendering\core_code\customforge-0.1.0-alpha.2.tgz
105
+ ```
97
106
 
98
107
  仓库中的 `examples/npm-consumer` 提供了一个只通过该 `.tgz` 导入的消费示例。在该目录中使用 `pnpm install --ignore-workspace`,确保 pnpm 将其作为独立于父级 workspace 的项目安装
99
108
 
100
109
  ## 加载你的产品
101
110
 
102
- 在演示页面中选择 **Load remote**,然后填写:
111
+ 在演示页面中选择 **Load product**,然后填写:
103
112
 
104
113
  | 字段 | 用途 |
105
114
  | --- | --- |
@@ -169,6 +178,126 @@ window.addEventListener('beforeunload', () => customizer.destroy(), {
169
178
 
170
179
  公开包与本地 `.tgz` 使用相同的根入口和样式入口;需要可重复安装时应固定具体 alpha 版本
171
180
 
181
+ ## 开箱即用的 Workbench
182
+
183
+ 不希望从零编写控制界面时,可以使用可选的 Workbench 入口
184
+
185
+ 挂载元素必须设置明确高度,设计画布、图层面板和三维区域才能正确计算可用空间
186
+
187
+ ```html
188
+ <div id="customforge-workbench" style="height: 720px"></div>
189
+ ```
190
+
191
+ ```ts
192
+ import { createWorkbench } from 'customforge/workbench'
193
+ import 'customforge/style.css'
194
+
195
+ const workbench = await createWorkbench({
196
+ container: '#customforge-workbench',
197
+ product: {
198
+ modelUrl: 'https://example.com/product.glb',
199
+ surfaceMesh: 'PrintArea',
200
+ },
201
+ features: {
202
+ presetBackgrounds: true,
203
+ presetElements: true,
204
+ },
205
+ layout: {
206
+ header: true,
207
+ layers: true,
208
+ },
209
+ branding: {
210
+ logoUrl: '/brand/logo.png',
211
+ title: '定制工作室',
212
+ subtitle: '产品个性化设计',
213
+ },
214
+ labels: {
215
+ addText: '文字设计',
216
+ addImage: '图片素材',
217
+ },
218
+ theme: {
219
+ accent: '#0057b8',
220
+ accentHover: '#003f87',
221
+ accentContrast: '#ffffff',
222
+ },
223
+ assets: {
224
+ backgrounds: [
225
+ { id: 'floral', name: '花卉背景', url: '/presets/floral.png' },
226
+ ],
227
+ elements: [
228
+ { id: 'flower', name: '小花', url: '/presets/flower.png' },
229
+ ],
230
+ },
231
+ })
232
+ ```
233
+
234
+ 默认使用包内的 CustomForge Logo,可以通过 `branding` 替换或隐藏
235
+
236
+ `labels` 用于替换 Workbench 可见文案,`theme` 映射到限定作用域的 CSS 变量,`icons` 可以关闭内置图标或用图片地址替换指定语义图标
237
+
238
+ 默认界面字体栈优先使用圆润的 `Nunito Sans`,不可用时回退到系统无衬线字体
239
+
240
+ CustomForge 会随制品提供该字体资源,不会在运行时请求第三方字体服务
241
+
242
+ 文字和图片命令现在会打开专用 Dialog,不会在点击工具栏按钮后立即修改画布
243
+
244
+ - 文字 Dialog 提供文本输入、颜色选择和可替换的排版预设
245
+ - 图片 Dialog 提供本地上传、预设背景和装饰元素
246
+ - 设计背景会替换已有设计背景、铺满画布、默认锁定在最底层并保存到 Design JSON
247
+
248
+ 功能和布局开关也可以在初始化后动态调整
249
+
250
+ ```ts
251
+ workbench.setFeature('addText', true)
252
+ workbench.setLayout('header', true)
253
+ ```
254
+
255
+ | 功能开关 | 控制内容 |
256
+ | --- | --- |
257
+ | `addText`、`addImage`、`deleteSelection` | 对象 Dialog 和删除操作 |
258
+ | `undoRedo` | 撤销、重做按钮和 Workbench 键盘快捷键 |
259
+ | `saveDesign`、`loadDesign` | Design JSON 操作 |
260
+ | `loadRemoteProduct`、`exportTexture`、`resetView` | 产品和输出操作 |
261
+ | `reorderObjects`、`toggleObjectVisibility`、`lockObjects`、`renameObjects` | 图层管理 |
262
+ | `presetBackgrounds`、`presetElements` | 图片 Dialog 中的预设素材页签 |
263
+
264
+ | 布局开关 | 控制区域 |
265
+ | --- | --- |
266
+ | `header` | 品牌和全局产品操作 |
267
+ | `editorHeader`、`viewerHeader` | 工作区面板标题栏 |
268
+ | `toolbar` | 设计工具栏 |
269
+ | `layers` | 对象图层面板 |
270
+ | `status` | 运行状态和对象数量 |
271
+
272
+ 所有功能和布局开关默认均为 `true`
273
+
274
+ 功能开关只控制 Workbench 自带控件,不会移除 `workbench.customizer` 上的底层方法
275
+
276
+ 主题配置用于统一的产品级视觉调整,不提供难以维护的逐按钮颜色配置
277
+
278
+ ```ts
279
+ const workbench = await createWorkbench({
280
+ container: '#customforge-workbench',
281
+ icons: {
282
+ enabled: true,
283
+ sources: {
284
+ addText: '/icons/typography.svg',
285
+ exportTexture: null,
286
+ },
287
+ },
288
+ textPresets: [
289
+ {
290
+ id: 'brand-display',
291
+ name: '品牌展示',
292
+ fontFamily: 'Arial',
293
+ fontSize: 72,
294
+ width: 460,
295
+ color: '#17191c',
296
+ },
297
+ ],
298
+ })
299
+ ```
300
+
172
301
  ## Design JSON
173
302
 
174
303
  `saveDesign()` 返回由 Library 自身定义、可安全写入 JSON 的文档,不暴露 Fabric.js 序列化格式。`loadDesign()` 校验未知输入,并异步恢复可编辑对象栈:
@@ -183,32 +312,70 @@ if (savedDesign) {
183
312
  }
184
313
  ```
185
314
 
186
- 当前 Schema 版本为 `1`。文档保存逻辑画布尺寸,并按从后到前的渲染顺序保存文字和图片对象,包括稳定对象 ID 与基于中心点的变换
315
+ 当前 Schema 版本为 `1`,文档保存逻辑画布尺寸,并按从后到前的渲染顺序保存文字和图片对象,包括稳定对象 ID、名称、显隐、锁定状态、图片用途与基于中心点的变换
187
316
 
188
317
  Design JSON 有意排除产品模型、目标 Mesh 和基础纹理。文档只能加载到逻辑宽高完全相同的编辑器中
189
318
 
319
+ 带有 `role: 'background'` 的图片是设计对象,不是产品基础纹理,只允许存在一个并且必须位于对象数组首位,旧版 v1 文档缺少 `role` 时继续按普通图片元素加载
320
+
190
321
  加载具有事务性:只有文档校验通过且全部引用图片成功加载后,当前设计才会被替换。Blob URL 图片会在添加时转换为 Data URL;远程图片仍保留 URL,恢复时必须继续满足浏览器 CORS 要求
191
322
 
192
323
  该 Schema 目前仍属于 alpha 契约,后续 alpha 版本可能调整
193
324
 
325
+ ## 撤销与重做
326
+
327
+ 无界面核心和 Workbench 都支持历史记录,默认保留 50 个撤销步骤
328
+
329
+ 可以在 `createCustomizer` 或 `createWorkbench` 配置中通过 `historyLimit` 调整保留的撤销深度
330
+
331
+ ```ts
332
+ if (customizer.canUndo()) {
333
+ await customizer.undo()
334
+ }
335
+
336
+ await customizer.redo()
337
+ customizer.clearHistory()
338
+
339
+ const stop = customizer.on('historychange', ({ canUndo, canRedo }) => {
340
+ console.log({ canUndo, canRedo })
341
+ })
342
+ ```
343
+
344
+ 历史记录覆盖对象添加、删除、画布变换、文字编辑、图层排序、名称、显隐、锁定和 Design JSON 加载
345
+
346
+ Workbench 在焦点不位于表单控件时支持 `Ctrl` 或 `Cmd` + `Z`、`Ctrl` 或 `Cmd` + `Shift` + `Z` 和 `Ctrl` + `Y`
347
+
348
+ 成功更换产品后会保留当前设计对象,但以当前设计重新开始历史记录
349
+
194
350
  ## 实例 API
195
351
 
196
352
  | 方法 | 说明 |
197
353
  | --- | --- |
198
354
  | `addText(options)` | 添加并选中文字,自动约束在画布内 |
199
- | `addImage(options)` | 加载并选中图片,自动约束在画布内 |
355
+ | `addImage(options)` | 加载普通图片元素或替换设计背景 |
356
+ | `getObjects()` | 按从后到前的图层顺序返回当前对象 |
357
+ | `getSelectedObjectIds()` | 返回当前选区中的稳定对象 ID |
358
+ | `selectObject(id)` | 根据稳定 ID 选中可见对象 |
359
+ | `removeObject(id)` | 根据稳定 ID 删除对象 |
360
+ | `moveObject(id, index)` | 将对象移动到从 0 开始的图层索引 |
361
+ | `renameObject(id, name)` | 修改图层工具中显示的对象名称 |
362
+ | `setObjectVisibility(id, visible)` | 设置对象是否参与渲染 |
363
+ | `setObjectLocked(id, locked)` | 锁定或解锁画布变换 |
200
364
  | `deleteSelected()` | 删除当前对象或选区 |
201
365
  | `saveDesign()` | 返回当前版本化 Design JSON 文档 |
202
366
  | `loadDesign(value)` | 校验并以事务方式恢复 Design JSON |
367
+ | `canUndo()`、`canRedo()` | 查询当前可用的历史方向 |
368
+ | `undo()`、`redo()` | 恢复前一个或后一个设计快照 |
369
+ | `clearHistory()` | 将当前设计设为新的历史起点 |
203
370
  | `loadProduct(product)` | 更换模型、基础纹理和目标 Mesh |
204
371
  | `exportTexture(filename?)` | 将合成纹理下载为 PNG |
205
372
  | `resetView()` | 恢复默认三维相机位置 |
206
373
  | `on(event, listener)` | 订阅实例事件,并返回取消订阅函数 |
207
374
  | `destroy()` | 释放 DOM 事件、Fabric 状态和 WebGL 资源 |
208
375
 
209
- 当前事件包括 `ready`、`change`、`selectionchange`、`status` 和 `error`
376
+ 当前事件包括 `ready`、`change`、`selectionchange`、`historychange`、`status` 和 `error`
210
377
 
211
- 首个 alpha 的稳定候选边界只包括上表方法、`createCustomizer`、`ProductCustomizer` 以及从根入口导出的配置、事件和 Design JSON 类型
378
+ 首个 alpha 的稳定候选边界只包括上表方法、`createCustomizer`、`ProductCustomizer`、`customforge/workbench` 入口,以及从已声明入口导出的配置、事件、Workbench Design JSON 类型
212
379
 
213
380
  `ProductCustomizer` 不公开 Fabric.js 编辑器和 Three.js 查看器实例,使用方只通过门面 API 操作定制器
214
381
 
@@ -237,7 +404,7 @@ ProductCustomizer
237
404
 
238
405
  `ProductCustomizer` 负责协调各模块,并将 Fabric.js 和 Three.js 的实现细节隐藏在小型实例 API 后面
239
406
 
240
- 演示界面使用原生 TypeScript,核心不依赖 Vue、React 或其他 UI 框架
407
+ 可选 Workbench 和演示界面使用原生 TypeScript,核心不依赖 Vue、React 或其他 UI 框架
241
408
 
242
409
  ## 模型约定
243
410
 
@@ -259,10 +426,11 @@ src/
259
426
  |-- core/ 公共类型、配置和 DOM 工具
260
427
  |-- customizer/ 公共实例编排
261
428
  |-- demo/ 可运行的工作台界面
262
- |-- editor/ Fabric.js 设计画布
429
+ |-- editor/ Fabric.js 设计画布和快照历史
263
430
  |-- style.css Library 公开样式入口
264
- |-- styles/ Library 核心样式
431
+ |-- styles/ 核心和 Workbench 样式
265
432
  |-- viewer/ Three.js 产品预览
433
+ |-- workbench/ 可配置界面、Dialog、图标和预设素材
266
434
  `-- index.ts 与框架无关的源码入口
267
435
 
268
436
  examples/
@@ -278,7 +446,7 @@ scripts/
278
446
  pnpm check # TypeScript 项目检查
279
447
  pnpm test # 单元测试
280
448
  pnpm build # 类型检查和生产构建
281
- pnpm build:lib # 构建 ESM、类型声明和核心样式
449
+ pnpm build:lib # 构建核心与 Workbench ESM、类型声明和样式
282
450
  pnpm verify:package # 检查 dist 和 npm 文件清单
283
451
  pnpm pack:local # 构建、检查并生成本地 .tgz
284
452
  pnpm release:check # 执行检查、测试、制品构建、校验和本地打包
@@ -295,12 +463,13 @@ pnpm preview # 预览生产构建
295
463
 
296
464
  在 API 和 Design JSON 契约进入更稳定阶段前,公开 npm 版本统一使用 `alpha` dist-tag
297
465
 
298
- 多定制面、撤销与重做和框架适配器仍未实现。撤销与重做是下一阶段计划,并将复用 Design JSON 快照契约
466
+ 多定制面、高级对齐工具和框架适配器仍未实现
299
467
 
300
468
  ## 技术栈
301
469
 
302
470
  - [Fabric.js](https://fabricjs.com/):二维编辑画布
303
471
  - [Three.js](https://threejs.org/):模型加载和实时三维渲染
472
+ - [Lucide](https://lucide.dev/):打包到 Workbench 中的界面图标
304
473
  - [Vite](https://vite.dev/):开发环境和应用构建
305
474
  - [TypeScript](https://www.typescriptlang.org/):启用严格类型检查
306
475
 
@@ -311,3 +480,5 @@ CustomForge 依据 Apache License 2.0 开源
311
480
  完整协议内容请参阅 [LICENSE](./LICENSE)
312
481
 
313
482
  第三方依赖和资产仍遵循各自的许可条款
483
+
484
+ 随包提供的 Nunito Sans 字体遵循 SIL Open Font License 1.1,完整条款见 [NunitoSans-OFL.txt](./LICENSES/NunitoSans-OFL.txt)
Binary file