customforge 0.1.0-alpha.0 → 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.
- package/CHANGELOG.md +61 -27
- package/LICENSE +201 -201
- package/LICENSES/NunitoSans-OFL.txt +93 -0
- package/README.md +339 -152
- package/README.zh-CN.md +337 -152
- package/dist/NunitoSans-Variable.ttf +0 -0
- package/dist/ProductCustomizer-rMRyWe7L.js +1624 -0
- package/dist/ProductCustomizer-rMRyWe7L.js.map +1 -0
- package/dist/core/design.d.ts.map +1 -1
- package/dist/core/types.d.ts +35 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/customizer/ProductCustomizer.d.ts +78 -0
- package/dist/customizer/ProductCustomizer.d.ts.map +1 -1
- package/dist/editor/DesignEditor.d.ts +108 -6
- package/dist/editor/DesignEditor.d.ts.map +1 -1
- package/dist/editor/DesignHistory.d.ts +27 -0
- package/dist/editor/DesignHistory.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1108
- package/dist/index.js.map +1 -1
- package/dist/style.css +1330 -11
- package/dist/workbench/CustomForgeWorkbench.d.ts +128 -0
- package/dist/workbench/CustomForgeWorkbench.d.ts.map +1 -0
- package/dist/workbench/assets/catalog.d.ts +8 -0
- package/dist/workbench/assets/catalog.d.ts.map +1 -0
- package/dist/workbench/config.d.ts +55 -0
- package/dist/workbench/config.d.ts.map +1 -0
- package/dist/workbench/icons.d.ts +4 -0
- package/dist/workbench/icons.d.ts.map +1 -0
- package/dist/workbench/index.d.ts +25 -0
- package/dist/workbench/index.d.ts.map +1 -0
- package/dist/workbench/template.d.ts +3 -0
- package/dist/workbench/template.d.ts.map +1 -0
- package/dist/workbench/types.d.ts +294 -0
- package/dist/workbench/types.d.ts.map +1 -0
- package/dist/workbench.js +1920 -0
- package/dist/workbench.js.map +1 -0
- package/package.json +8 -5
package/README.zh-CN.md
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<p>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
</
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
|
@@ -32,15 +37,19 @@ CustomForge 将常见的二维设计界面与带 UV 的三维模型连接起来
|
|
|
32
37
|
- 将画布的每次变化实时呈现在三维产品上
|
|
33
38
|
- 加载远程 GLB/GLTF 模型和可选的基础纹理
|
|
34
39
|
- 通过 Mesh 名称指定可定制表面
|
|
35
|
-
- 使用 OrbitControls 旋转和缩放三维预览
|
|
36
|
-
- 将合成后的纹理导出为 PNG
|
|
37
|
-
- 通过版本化 Design JSON 保存和恢复可编辑对象
|
|
40
|
+
- 使用 OrbitControls 旋转和缩放三维预览
|
|
41
|
+
- 将合成后的纹理导出为 PNG
|
|
42
|
+
- 通过版本化 Design JSON 保存和恢复可编辑对象
|
|
43
|
+
- 通过名称、显隐、锁定和顺序管理对象图层
|
|
44
|
+
- 使用设计快照撤销和重做修改
|
|
45
|
+
- 使用可配置的文字、背景和装饰素材 Dialog
|
|
46
|
+
- 通过品牌、文案、主题变量和图标适配默认 Workbench
|
|
38
47
|
|
|
39
48
|
工作台内置了一个程序生成的杯子,无需准备外部资源即可直接运行
|
|
40
49
|
|
|
41
|
-
## 仓库开发
|
|
42
|
-
|
|
43
|
-
环境要求:Node.js 22+ 和 pnpm 11+
|
|
50
|
+
## 仓库开发
|
|
51
|
+
|
|
52
|
+
环境要求:Node.js 22+ 和 pnpm 11+
|
|
44
53
|
|
|
45
54
|
```bash
|
|
46
55
|
pnpm install
|
|
@@ -49,43 +58,57 @@ pnpm dev
|
|
|
49
58
|
|
|
50
59
|
打开 Vite 输出的地址
|
|
51
60
|
|
|
52
|
-
内置演示的左侧是 UV 编辑区,右侧是实时三维预览
|
|
53
|
-
|
|
54
|
-
## npm Alpha 制品
|
|
55
|
-
|
|
56
|
-
CustomForge
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```powershell
|
|
61
|
-
pnpm add customforge@alpha
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
|
|
61
|
+
内置演示的左侧是 UV 编辑区,右侧是实时三维预览
|
|
62
|
+
|
|
63
|
+
## npm Alpha 制品
|
|
64
|
+
|
|
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
|
+
```
|
|
86
|
+
|
|
87
|
+
包页面:[npmjs.com/package/customforge](https://www.npmjs.com/package/customforge)
|
|
88
|
+
|
|
89
|
+
发布前如需进行独立于仓库源码的验证,可在仓库根目录构建并生成本地包:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
pnpm pack:local
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
命令依次生成 JavaScript、TypeScript 声明和公开样式,检查 npm 文件清单,并创建:
|
|
96
|
+
|
|
97
|
+
```text
|
|
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
|
+
```
|
|
106
|
+
|
|
107
|
+
仓库中的 `examples/npm-consumer` 提供了一个只通过该 `.tgz` 导入的消费示例。在该目录中使用 `pnpm install --ignore-workspace`,确保 pnpm 将其作为独立于父级 workspace 的项目安装
|
|
85
108
|
|
|
86
109
|
## 加载你的产品
|
|
87
110
|
|
|
88
|
-
在演示页面中选择 **Load
|
|
111
|
+
在演示页面中选择 **Load product**,然后填写:
|
|
89
112
|
|
|
90
113
|
| 字段 | 用途 |
|
|
91
114
|
| --- | --- |
|
|
@@ -103,22 +126,22 @@ UV 坐标应当保存在三维模型中
|
|
|
103
126
|
>
|
|
104
127
|
> 被浏览器阻止或污染 Canvas 的资源可能无法加载,也会导致 PNG 导出失败
|
|
105
128
|
|
|
106
|
-
## 基本用法
|
|
107
|
-
|
|
108
|
-
与框架无关的 Library 入口可以挂载到任意两个 DOM 容器中:
|
|
109
|
-
|
|
110
|
-
CustomForge 仅支持浏览器环境,应在 DOM 挂载容器可用后创建实例
|
|
111
|
-
|
|
112
|
-
编辑器和查看器必须使用两个不同的容器;页面卸载、组件卸载或不再使用实例时必须调用 `destroy()` 释放 Fabric、WebGL、观察器和事件资源
|
|
129
|
+
## 基本用法
|
|
130
|
+
|
|
131
|
+
与框架无关的 Library 入口可以挂载到任意两个 DOM 容器中:
|
|
132
|
+
|
|
133
|
+
CustomForge 仅支持浏览器环境,应在 DOM 挂载容器可用后创建实例
|
|
134
|
+
|
|
135
|
+
编辑器和查看器必须使用两个不同的容器;页面卸载、组件卸载或不再使用实例时必须调用 `destroy()` 释放 Fabric、WebGL、观察器和事件资源
|
|
113
136
|
|
|
114
137
|
```html
|
|
115
138
|
<div id="texture-editor"></div>
|
|
116
139
|
<div id="product-viewer"></div>
|
|
117
140
|
```
|
|
118
141
|
|
|
119
|
-
```ts
|
|
120
|
-
import { createCustomizer } from 'customforge'
|
|
121
|
-
import 'customforge/style.css'
|
|
142
|
+
```ts
|
|
143
|
+
import { createCustomizer } from 'customforge'
|
|
144
|
+
import 'customforge/style.css'
|
|
122
145
|
|
|
123
146
|
const customizer = await createCustomizer({
|
|
124
147
|
editor: '#texture-editor',
|
|
@@ -141,64 +164,222 @@ customizer.addText({
|
|
|
141
164
|
color: '#172126',
|
|
142
165
|
})
|
|
143
166
|
|
|
144
|
-
await customizer.addImage({
|
|
145
|
-
src: 'https://example.com/logo.png',
|
|
146
|
-
x: 720,
|
|
147
|
-
y: 240,
|
|
148
|
-
width: 220,
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
window.addEventListener('beforeunload', () => customizer.destroy(), {
|
|
152
|
-
once: true,
|
|
153
|
-
})
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
公开包与本地 `.tgz` 使用相同的根入口和样式入口;需要可重复安装时应固定具体 alpha 版本
|
|
157
|
-
|
|
158
|
-
##
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
167
|
+
await customizer.addImage({
|
|
168
|
+
src: 'https://example.com/logo.png',
|
|
169
|
+
x: 720,
|
|
170
|
+
y: 240,
|
|
171
|
+
width: 220,
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
window.addEventListener('beforeunload', () => customizer.destroy(), {
|
|
175
|
+
once: true,
|
|
176
|
+
})
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
公开包与本地 `.tgz` 使用相同的根入口和样式入口;需要可重复安装时应固定具体 alpha 版本
|
|
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
|
+
|
|
301
|
+
## Design JSON
|
|
302
|
+
|
|
303
|
+
`saveDesign()` 返回由 Library 自身定义、可安全写入 JSON 的文档,不暴露 Fabric.js 序列化格式。`loadDesign()` 校验未知输入,并异步恢复可编辑对象栈:
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
const design = customizer.saveDesign()
|
|
307
|
+
localStorage.setItem('customforge-design', JSON.stringify(design))
|
|
308
|
+
|
|
309
|
+
const savedDesign = localStorage.getItem('customforge-design')
|
|
310
|
+
if (savedDesign) {
|
|
311
|
+
await customizer.loadDesign(JSON.parse(savedDesign))
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
当前 Schema 版本为 `1`,文档保存逻辑画布尺寸,并按从后到前的渲染顺序保存文字和图片对象,包括稳定对象 ID、名称、显隐、锁定状态、图片用途与基于中心点的变换
|
|
316
|
+
|
|
317
|
+
Design JSON 有意排除产品模型、目标 Mesh 和基础纹理。文档只能加载到逻辑宽高完全相同的编辑器中
|
|
318
|
+
|
|
319
|
+
带有 `role: 'background'` 的图片是设计对象,不是产品基础纹理,只允许存在一个并且必须位于对象数组首位,旧版 v1 文档缺少 `role` 时继续按普通图片元素加载
|
|
320
|
+
|
|
321
|
+
加载具有事务性:只有文档校验通过且全部引用图片成功加载后,当前设计才会被替换。Blob URL 图片会在添加时转换为 Data URL;远程图片仍保留 URL,恢复时必须继续满足浏览器 CORS 要求
|
|
322
|
+
|
|
323
|
+
该 Schema 目前仍属于 alpha 契约,后续 alpha 版本可能调整
|
|
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
|
+
|
|
350
|
+
## 实例 API
|
|
181
351
|
|
|
182
352
|
| 方法 | 说明 |
|
|
183
353
|
| --- | --- |
|
|
184
|
-
| `addText(options)` | 添加并选中文字,自动约束在画布内 |
|
|
185
|
-
| `addImage(options)` |
|
|
186
|
-
| `
|
|
187
|
-
| `
|
|
188
|
-
| `
|
|
189
|
-
| `
|
|
354
|
+
| `addText(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)` | 锁定或解锁画布变换 |
|
|
364
|
+
| `deleteSelected()` | 删除当前对象或选区 |
|
|
365
|
+
| `saveDesign()` | 返回当前版本化 Design JSON 文档 |
|
|
366
|
+
| `loadDesign(value)` | 校验并以事务方式恢复 Design JSON |
|
|
367
|
+
| `canUndo()`、`canRedo()` | 查询当前可用的历史方向 |
|
|
368
|
+
| `undo()`、`redo()` | 恢复前一个或后一个设计快照 |
|
|
369
|
+
| `clearHistory()` | 将当前设计设为新的历史起点 |
|
|
370
|
+
| `loadProduct(product)` | 更换模型、基础纹理和目标 Mesh |
|
|
190
371
|
| `exportTexture(filename?)` | 将合成纹理下载为 PNG |
|
|
191
372
|
| `resetView()` | 恢复默认三维相机位置 |
|
|
192
373
|
| `on(event, listener)` | 订阅实例事件,并返回取消订阅函数 |
|
|
193
374
|
| `destroy()` | 释放 DOM 事件、Fabric 状态和 WebGL 资源 |
|
|
194
375
|
|
|
195
|
-
当前事件包括 `ready`、`change`、`selectionchange`、`status` 和 `error`
|
|
196
|
-
|
|
197
|
-
首个 alpha 的稳定候选边界只包括上表方法、`createCustomizer`、`ProductCustomizer`
|
|
198
|
-
|
|
199
|
-
`ProductCustomizer` 不公开 Fabric.js 编辑器和 Three.js 查看器实例,使用方只通过门面 API 操作定制器
|
|
200
|
-
|
|
201
|
-
不支持从 `core`、`editor`、`viewer`、`bridge` 或其他未声明的包子路径导入模块
|
|
376
|
+
当前事件包括 `ready`、`change`、`selectionchange`、`historychange`、`status` 和 `error`
|
|
377
|
+
|
|
378
|
+
首个 alpha 的稳定候选边界只包括上表方法、`createCustomizer`、`ProductCustomizer`、`customforge/workbench` 入口,以及从已声明入口导出的配置、事件、Workbench 和 Design JSON 类型
|
|
379
|
+
|
|
380
|
+
`ProductCustomizer` 不公开 Fabric.js 编辑器和 Three.js 查看器实例,使用方只通过门面 API 操作定制器
|
|
381
|
+
|
|
382
|
+
不支持从 `core`、`editor`、`viewer`、`bridge` 或其他未声明的包子路径导入模块
|
|
202
383
|
|
|
203
384
|
## 架构
|
|
204
385
|
|
|
@@ -223,7 +404,7 @@ ProductCustomizer
|
|
|
223
404
|
|
|
224
405
|
`ProductCustomizer` 负责协调各模块,并将 Fabric.js 和 Three.js 的实现细节隐藏在小型实例 API 后面
|
|
225
406
|
|
|
226
|
-
|
|
407
|
+
可选 Workbench 和演示界面使用原生 TypeScript,核心不依赖 Vue、React 或其他 UI 框架
|
|
227
408
|
|
|
228
409
|
## 模型约定
|
|
229
410
|
|
|
@@ -240,36 +421,37 @@ ProductCustomizer
|
|
|
240
421
|
## 项目结构
|
|
241
422
|
|
|
242
423
|
```text
|
|
243
|
-
src/
|
|
244
|
-
|-- bridge/ Canvas 与 Three.js 纹理同步
|
|
245
|
-
|-- core/ 公共类型、配置和 DOM 工具
|
|
246
|
-
|-- customizer/ 公共实例编排
|
|
247
|
-
|-- demo/ 可运行的工作台界面
|
|
248
|
-
|-- editor/ Fabric.js
|
|
249
|
-
|-- style.css Library 公开样式入口
|
|
250
|
-
|-- styles/
|
|
251
|
-
|-- viewer/ Three.js 产品预览
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
424
|
+
src/
|
|
425
|
+
|-- bridge/ Canvas 与 Three.js 纹理同步
|
|
426
|
+
|-- core/ 公共类型、配置和 DOM 工具
|
|
427
|
+
|-- customizer/ 公共实例编排
|
|
428
|
+
|-- demo/ 可运行的工作台界面
|
|
429
|
+
|-- editor/ Fabric.js 设计画布和快照历史
|
|
430
|
+
|-- style.css Library 公开样式入口
|
|
431
|
+
|-- styles/ 核心和 Workbench 样式
|
|
432
|
+
|-- viewer/ Three.js 产品预览
|
|
433
|
+
|-- workbench/ 可配置界面、Dialog、图标和预设素材
|
|
434
|
+
`-- index.ts 与框架无关的源码入口
|
|
435
|
+
|
|
436
|
+
examples/
|
|
437
|
+
`-- npm-consumer/ 本地 .tgz 独立消费示例
|
|
438
|
+
|
|
439
|
+
scripts/
|
|
440
|
+
`-- verify-package.mjs npm 文件和制品边界检查
|
|
441
|
+
```
|
|
260
442
|
|
|
261
443
|
## 开发命令
|
|
262
444
|
|
|
263
445
|
```bash
|
|
264
|
-
pnpm check # TypeScript 项目检查
|
|
265
|
-
pnpm test # 单元测试
|
|
266
|
-
pnpm build # 类型检查和生产构建
|
|
267
|
-
pnpm build:lib #
|
|
268
|
-
pnpm verify:package # 检查 dist 和 npm 文件清单
|
|
269
|
-
pnpm pack:local # 构建、检查并生成本地 .tgz
|
|
270
|
-
pnpm release:check # 执行检查、测试、制品构建、校验和本地打包
|
|
271
|
-
pnpm preview # 预览生产构建
|
|
272
|
-
```
|
|
446
|
+
pnpm check # TypeScript 项目检查
|
|
447
|
+
pnpm test # 单元测试
|
|
448
|
+
pnpm build # 类型检查和生产构建
|
|
449
|
+
pnpm build:lib # 构建核心与 Workbench ESM、类型声明和样式
|
|
450
|
+
pnpm verify:package # 检查 dist 和 npm 文件清单
|
|
451
|
+
pnpm pack:local # 构建、检查并生成本地 .tgz
|
|
452
|
+
pnpm release:check # 执行检查、测试、制品构建、校验和本地打包
|
|
453
|
+
pnpm preview # 预览生产构建
|
|
454
|
+
```
|
|
273
455
|
|
|
274
456
|
## 当前范围
|
|
275
457
|
|
|
@@ -277,16 +459,17 @@ pnpm preview # 预览生产构建
|
|
|
277
459
|
|
|
278
460
|
公共 API 和设计文档格式尚未稳定
|
|
279
461
|
|
|
280
|
-
当前里程碑有意聚焦于一张纹理和一个可定制 Mesh
|
|
281
|
-
|
|
282
|
-
在 API 和 Design JSON 契约进入更稳定阶段前,公开 npm 版本统一使用 `alpha` dist-tag
|
|
283
|
-
|
|
284
|
-
|
|
462
|
+
当前里程碑有意聚焦于一张纹理和一个可定制 Mesh
|
|
463
|
+
|
|
464
|
+
在 API 和 Design JSON 契约进入更稳定阶段前,公开 npm 版本统一使用 `alpha` dist-tag
|
|
465
|
+
|
|
466
|
+
多定制面、高级对齐工具和框架适配器仍未实现
|
|
285
467
|
|
|
286
468
|
## 技术栈
|
|
287
469
|
|
|
288
470
|
- [Fabric.js](https://fabricjs.com/):二维编辑画布
|
|
289
471
|
- [Three.js](https://threejs.org/):模型加载和实时三维渲染
|
|
472
|
+
- [Lucide](https://lucide.dev/):打包到 Workbench 中的界面图标
|
|
290
473
|
- [Vite](https://vite.dev/):开发环境和应用构建
|
|
291
474
|
- [TypeScript](https://www.typescriptlang.org/):启用严格类型检查
|
|
292
475
|
|
|
@@ -297,3 +480,5 @@ CustomForge 依据 Apache License 2.0 开源
|
|
|
297
480
|
完整协议内容请参阅 [LICENSE](./LICENSE)
|
|
298
481
|
|
|
299
482
|
第三方依赖和资产仍遵循各自的许可条款
|
|
483
|
+
|
|
484
|
+
随包提供的 Nunito Sans 字体遵循 SIL Open Font License 1.1,完整条款见 [NunitoSans-OFL.txt](./LICENSES/NunitoSans-OFL.txt)
|
|
Binary file
|