@flyfish-dev/cad-viewer 0.5.3
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/LICENSE +661 -0
- package/NOTICE +11 -0
- package/README.md +411 -0
- package/README.zh-CN.md +411 -0
- package/dist/assets/DwgWorker-CuZJ5EUe.js +349 -0
- package/dist/assets/DwgWorker-CuZJ5EUe.js.map +1 -0
- package/dist/assets/index-C365l3i9.js +4161 -0
- package/dist/assets/index-C365l3i9.js.map +1 -0
- package/dist/cad-viewer.es.js +2992 -0
- package/dist/cad-viewer.es.js.map +1 -0
- package/dist/cad-viewer.umd.cjs +30 -0
- package/dist/cad-viewer.umd.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/style.css +1 -0
- package/dist/types/core/color.d.ts +21 -0
- package/dist/types/core/color.d.ts.map +1 -0
- package/dist/types/core/entity.d.ts +34 -0
- package/dist/types/core/entity.d.ts.map +1 -0
- package/dist/types/core/format.d.ts +8 -0
- package/dist/types/core/format.d.ts.map +1 -0
- package/dist/types/core/geometry.d.ts +17 -0
- package/dist/types/core/geometry.d.ts.map +1 -0
- package/dist/types/core/transform.d.ts +20 -0
- package/dist/types/core/transform.d.ts.map +1 -0
- package/dist/types/core/types.d.ts +195 -0
- package/dist/types/core/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/loaders/CadLoaderRegistry.d.ts +15 -0
- package/dist/types/loaders/CadLoaderRegistry.d.ts.map +1 -0
- package/dist/types/loaders/dwf/DwfLoader.d.ts +15 -0
- package/dist/types/loaders/dwf/DwfLoader.d.ts.map +1 -0
- package/dist/types/loaders/dwg/DwgLoader.d.ts +15 -0
- package/dist/types/loaders/dwg/DwgLoader.d.ts.map +1 -0
- package/dist/types/loaders/dwg/DwgParser.d.ts +24 -0
- package/dist/types/loaders/dwg/DwgParser.d.ts.map +1 -0
- package/dist/types/loaders/dwg/DwgWorker.d.ts +2 -0
- package/dist/types/loaders/dwg/DwgWorker.d.ts.map +1 -0
- package/dist/types/loaders/dwg/DwgWorkerClient.d.ts +18 -0
- package/dist/types/loaders/dwg/DwgWorkerClient.d.ts.map +1 -0
- package/dist/types/loaders/dwg/dwgVersion.d.ts +9 -0
- package/dist/types/loaders/dwg/dwgVersion.d.ts.map +1 -0
- package/dist/types/loaders/dwg/libredwgWasmModuleProxy.d.ts +14 -0
- package/dist/types/loaders/dwg/libredwgWasmModuleProxy.d.ts.map +1 -0
- package/dist/types/loaders/dxf/DxfLoader.d.ts +12 -0
- package/dist/types/loaders/dxf/DxfLoader.d.ts.map +1 -0
- package/dist/types/loaders/index.d.ts +8 -0
- package/dist/types/loaders/index.d.ts.map +1 -0
- package/dist/types/viewer/CadCanvasRenderer.d.ts +142 -0
- package/dist/types/viewer/CadCanvasRenderer.d.ts.map +1 -0
- package/dist/types/viewer/CadViewer.d.ts +55 -0
- package/dist/types/viewer/CadViewer.d.ts.map +1 -0
- package/dist/types/viewer/CadWebGLRenderer.d.ts +69 -0
- package/dist/types/viewer/CadWebGLRenderer.d.ts.map +1 -0
- package/dist/wasm/libredwg-web.js +15 -0
- package/dist/wasm/libredwg-web.wasm +0 -0
- package/package.json +103 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# @flyfish-dev/cad-viewer
|
|
2
|
+
|
|
3
|
+
一个专业、轻量、可扩展的**纯前端 CAD Viewer**。
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/@flyfish-dev/cad-viewer)
|
|
7
|
+
|
|
8
|
+
**在线 Demo:** [cad-viewer-iys.pages.dev](https://cad-viewer-iys.pages.dev)
|
|
9
|
+
**源码仓库:** [github.com/flyfish-dev/cad-viewer](https://github.com/flyfish-dev/cad-viewer)
|
|
10
|
+
|
|
11
|
+
本仓库提供面向浏览器的 loader 架构,支持 **DWG**、**DXF**、以及 **DWFx/XPS 兼容 DWF 预览**,将不同 CAD 格式归一化为统一 `CadDocument`,并通过 WebGL retained-mode 渲染,文字/图片使用轻量 Canvas overlay。文件在浏览器本地读取,组件不会把图纸上传到服务端。
|
|
12
|
+
|
|
13
|
+
> DWG 使用 `@mlightcad/libredwg-web` / LibreDWG WebAssembly。DXF 使用 JavaScript 解析器并带内置 fallback。DWFx 使用 XPS `FixedPage` 2D 页面解析。经典 `.dwf` 里的 WHIP/W2D/W3D 流会被检测并给出明确提示;若要完整解码经典 DWF,仍需要专门 WHIP 解码器或 DWF Toolkit/WASM 实现。
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## 0.5.3 变更
|
|
17
|
+
|
|
18
|
+
- 修复 DWG 图层索引色显示。LibreDWG 输出的索引色图层会优先按 ACI 解析,不再被 converter 的 `0xffffff` 占位值渲染成单色白图。
|
|
19
|
+
- 保留 DWG true-color 数值,即使 RGB 整数落在 ACI 范围内,例如 `0x0000ff`。
|
|
20
|
+
- 展开 INSERT/block 时增加 BYBLOCK 颜色继承。
|
|
21
|
+
|
|
22
|
+
## 0.5.2 变更
|
|
23
|
+
|
|
24
|
+
- 修复 `@mlightcad/libredwg-web` 入口导致的 Vite 超长 `data:application/wasm;base64,...` warning。
|
|
25
|
+
- DWG worker 构建改为使用 LibreDWG 的轻量 ESM wrapper,并在运行时从 `wasmPath` 加载 `/wasm/libredwg-web.js` 和 `/wasm/libredwg-web.wasm`,避免重复打包内联 wasm。
|
|
26
|
+
- `build:lib` 会生成 `dist/index.js` 兼容入口,兼容仍然请求 `/dist/index.js` 的旧集成方式。
|
|
27
|
+
- Vite dev 模式下新增 `/dist/index.js` 兼容路由,旧 demo 页面会被转到 `/demo/main.ts`,不再直接 404。
|
|
28
|
+
- `npm run preview` 会先构建 demo,干净仓库也可以直接预览。
|
|
29
|
+
|
|
30
|
+
## 0.5 变更
|
|
31
|
+
|
|
32
|
+
- 默认渲染后端升级为 **WebGL retained renderer**,首帧把 CAD 图元扁平化并上传为 GPU buffer,缩放/平移只更新 view uniform。
|
|
33
|
+
- 新增空间索引和 viewport culling:线段、三角面、点会按图纸范围分桶,放大查看局部区域时只提交可见 batch。
|
|
34
|
+
- 新增大图纸内存策略:坐标以图纸中心为 origin 存入 `Float32Array`,颜色存入 `Uint8Array`,上传后释放 CPU 临时数组,避免 Canvas2D 每帧重建路径。
|
|
35
|
+
- 文字、图片走独立 overlay,并带屏幕尺寸阈值和最大可见 label 限制,避免高密度图纸在缩放时被文字拖慢。
|
|
36
|
+
- `CadViewer` 新增 `renderer: 'auto' | 'webgl' | 'canvas2d'`;`auto` 优先 WebGL,不可用时回退 Canvas2D。
|
|
37
|
+
- Demo 新增 Renderer、visible primitives、GPU memory 指标,便于排查大图纸性能。
|
|
38
|
+
|
|
39
|
+
## 0.4 变更
|
|
40
|
+
|
|
41
|
+
- DWG 解析默认放到**独立 Web Worker** 中执行,LibreDWG WASM 初始化和二进制解析不会阻塞 UI、缩放和平移。
|
|
42
|
+
- Worker 会常驻并复用 LibreDWG WASM 实例,连续打开多个 DWG 时不重复初始化。
|
|
43
|
+
- 增加 `AbortSignal` 取消加载、worker timeout、加载进度事件,以及显式 worker 资源配置。
|
|
44
|
+
- 默认不再把 DWG raw parser 对象传回主线程,降低内存占用并避免 structured clone 失败;确实需要时可显式设置 `keepRaw: true`。
|
|
45
|
+
- Demo 增加加载遮罩、进度条、取消按钮和 loader mode 指示。
|
|
46
|
+
- `viewer.destroy()` 会清理 Canvas 监听器并终止持有的 DWG worker,适合 SPA 路由切换。
|
|
47
|
+
- 导出 `supportsDwgWorker` 和 `DwgWorkerClient`,方便高级集成。
|
|
48
|
+
|
|
49
|
+
## 功能特性
|
|
50
|
+
|
|
51
|
+
- **纯前端组件**:`new CadViewer({ container })` 或 `new CadViewer({ canvas })`。
|
|
52
|
+
- **正确的 loader 架构**:DWG / DXF / DWF 独立 loader,可替换、可扩展。
|
|
53
|
+
- **DWG 预览**:通过 LibreDWG WebAssembly 在浏览器本地解析,默认在 Web Worker 中执行。
|
|
54
|
+
- **DXF 预览**:JavaScript 解析,支持常见 ASCII DXF `ENTITIES`,并带 fallback parser。
|
|
55
|
+
- **DWF/DWFx 预览**:支持 DWFx/XPS 2D `FixedPage` 的 Path、Glyphs、图片预览。
|
|
56
|
+
- **CAD 颜色处理**:支持 ACI、BYLAYER、BYBLOCK 继承、DWG 图层颜色、true color、填充色、透明度和自适应对比度。
|
|
57
|
+
- **WebGL 高性能交互**:GPU retained buffers、空间分桶、视口裁剪、缩放、平移、适配窗口、世界坐标、缩放百分比。
|
|
58
|
+
- **专业 Demo**:拖拽打开、紧凑工具栏、状态条、解析/渲染耗时、实体类型统计、warnings 展示。
|
|
59
|
+
- **发布友好**:同时提供 npm library build 和 Cloudflare Pages demo build。
|
|
60
|
+
|
|
61
|
+
## 安装
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm install @flyfish-dev/cad-viewer
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
本仓库本地开发:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install
|
|
71
|
+
npm run dev
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
DWG loader 需要将 LibreDWG WASM 文件放到公开目录。Demo 使用以下命令复制并校验到 `public/wasm`:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm run copy:wasm
|
|
78
|
+
npm run check:wasm
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Demo 会先把 `wasmPath` 解析为绝对 URL,再发送给 worker。你自己的应用也建议使用绝对路径或绝对 URL,例如 `/wasm` 或 `new URL('wasm/', document.baseURI).href`。不要直接把未解析的 `./wasm` 传入 worker,否则它可能会相对于 worker chunk 请求资源。
|
|
82
|
+
|
|
83
|
+
发布 npm 包时,`build:lib` 也会把这些文件复制到 `dist/wasm` 并作为 package subpath 暴露出来。应用侧仍需要把 `.wasm` 放到可公开访问的 URL,并把该目录传给 `wasmPath`。
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## Demo 启动说明
|
|
87
|
+
|
|
88
|
+
源码 demo 必须通过 Vite 启动:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm install
|
|
92
|
+
npm run dev
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
生产预览使用:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npm run preview
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
不要直接用普通静态服务器托管源码目录并期望 TypeScript 入口能运行。如果旧页面仍请求 `/dist/index.js`,请先执行 `npm run build:lib` 生成兼容入口,或者直接使用上面的 Vite dev server。
|
|
102
|
+
|
|
103
|
+
## 基础用法
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { CadViewer } from '@flyfish-dev/cad-viewer';
|
|
107
|
+
import '@flyfish-dev/cad-viewer/style.css';
|
|
108
|
+
|
|
109
|
+
const viewer = new CadViewer({
|
|
110
|
+
container: document.querySelector('#viewer')!,
|
|
111
|
+
renderer: 'auto', // WebGL first, Canvas2D fallback
|
|
112
|
+
wasmPath: new URL('wasm/', document.baseURI).href,
|
|
113
|
+
canvasOptions: {
|
|
114
|
+
background: '#05070d',
|
|
115
|
+
foreground: '#f8fafc',
|
|
116
|
+
contrastMode: 'adaptive',
|
|
117
|
+
minColorContrast: 2.45
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const input = document.querySelector<HTMLInputElement>('input[type=file]')!;
|
|
122
|
+
input.addEventListener('change', async () => {
|
|
123
|
+
const file = input.files?.[0];
|
|
124
|
+
if (!file) return;
|
|
125
|
+
await viewer.loadFile(file);
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
## WebGL 渲染与性能策略
|
|
131
|
+
|
|
132
|
+
默认 `renderer: 'auto'` 会优先创建 `CadWebGLRenderer`。它不是每次缩放都用 Canvas2D 重新遍历实体,而是在 `setDocument()` 时构建一次 retained scene:
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
CadDocument
|
|
136
|
+
↓
|
|
137
|
+
flatten blocks / curves / fills
|
|
138
|
+
↓
|
|
139
|
+
Float32Array positions + Uint8Array colors
|
|
140
|
+
↓
|
|
141
|
+
spatial GPU batches
|
|
142
|
+
↓
|
|
143
|
+
WebGL drawArrays with viewport culling
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
可调参数:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
new CadViewer({
|
|
150
|
+
container,
|
|
151
|
+
renderer: 'auto', // 'webgl' 强制 WebGL;'canvas2d' 强制兼容模式
|
|
152
|
+
canvasOptions: {
|
|
153
|
+
enableSpatialIndex: true,
|
|
154
|
+
spatialIndexCellCount: 96,
|
|
155
|
+
maxVerticesPerBatch: 32768,
|
|
156
|
+
maxCurveSegments: 72,
|
|
157
|
+
textMinPixelHeight: 4,
|
|
158
|
+
maxVisibleTextLabels: 2400,
|
|
159
|
+
powerPreference: 'high-performance',
|
|
160
|
+
preserveDrawingBuffer: false
|
|
161
|
+
},
|
|
162
|
+
onRenderStats(stats) {
|
|
163
|
+
console.log(stats.backend, stats.visiblePrimitiveCount, stats.gpuMemoryBytes);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
对超大图纸,优先调小 `maxCurveSegments`、增大 `spatialIndexCellCount`,并限制 `maxVisibleTextLabels`。
|
|
169
|
+
|
|
170
|
+
## Worker 化 DWG 解析
|
|
171
|
+
|
|
172
|
+
`DwgLoader` 在浏览器里默认使用 module Web Worker。Worker 内部导入 `@mlightcad/libredwg-web`,初始化 LibreDWG WASM,缓存该 WASM 实例,解码 DWG 字节,并把结果归一化为可 structured-clone 的 `CadDocument` 后发送回 UI 线程。Canvas 渲染仍然留在主线程。
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
|
|
177
|
+
const viewer = new CadViewer({
|
|
178
|
+
container,
|
|
179
|
+
wasmPath: new URL('wasm/', document.baseURI).href,
|
|
180
|
+
useWorker: true,
|
|
181
|
+
workerTimeoutMs: 120_000,
|
|
182
|
+
onLoadProgress(progress) {
|
|
183
|
+
console.log(progress.phase, progress.message, progress.percent);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
await viewer.preloadDwg(); // 可选:首个文件打开前预热 worker
|
|
188
|
+
await viewer.loadFile(file, { signal: controller.signal });
|
|
189
|
+
|
|
190
|
+
// 取消大型 DWG 加载
|
|
191
|
+
controller.abort();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
如果你的构建系统或 CDN 对 worker 资源路径有特殊要求,可以显式传入 worker 地址:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
new CadViewer({
|
|
198
|
+
container,
|
|
199
|
+
wasmPath: new URL('wasm/', document.baseURI).href,
|
|
200
|
+
workerUrl: new URL('/assets/dwg-worker.js', window.location.origin)
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
默认包是 worker-first 设计。非浏览器运行时建议注册自定义 DWG loader,而不是关闭 worker。
|
|
205
|
+
|
|
206
|
+
## 组件 API
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
const viewer = new CadViewer({
|
|
210
|
+
container, // 容器元素,组件会自动创建 canvas
|
|
211
|
+
canvas, // 也可以传入已有 canvas
|
|
212
|
+
renderer: 'auto', // 'auto' | 'webgl' | 'canvas2d'
|
|
213
|
+
wasmPath: '/wasm', // LibreDWG WebAssembly 资源路径。Worker 场景建议使用绝对路径/URL
|
|
214
|
+
autoFit: true,
|
|
215
|
+
canvasOptions: {
|
|
216
|
+
background: '#05070d',
|
|
217
|
+
foreground: '#ffffff',
|
|
218
|
+
contrastMode: 'adaptive', // 'adaptive' | 'preserve'
|
|
219
|
+
minColorContrast: 2.45,
|
|
220
|
+
showPageBounds: true,
|
|
221
|
+
showUnsupportedMarkers: false,
|
|
222
|
+
trueColorByteOrder: 'rgb',
|
|
223
|
+
enableSpatialIndex: true,
|
|
224
|
+
spatialIndexCellCount: 96,
|
|
225
|
+
maxVerticesPerBatch: 32768,
|
|
226
|
+
maxCurveSegments: 72,
|
|
227
|
+
textMinPixelHeight: 4,
|
|
228
|
+
maxVisibleTextLabels: 2400
|
|
229
|
+
},
|
|
230
|
+
useWorker: true, // DWG 默认开启
|
|
231
|
+
workerTimeoutMs: 0, // 0 表示不限制
|
|
232
|
+
onLoadProgress(progress) {},
|
|
233
|
+
onLoad(result) {},
|
|
234
|
+
onError(error) {},
|
|
235
|
+
onRenderStats(stats) {},
|
|
236
|
+
onViewChange(event) {}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
await viewer.loadFile(file);
|
|
240
|
+
await viewer.loadBuffer(arrayBuffer, 'drawing.dxf');
|
|
241
|
+
viewer.fit();
|
|
242
|
+
viewer.zoomIn();
|
|
243
|
+
viewer.zoomOut();
|
|
244
|
+
await viewer.preloadDwg(); // 可选 DWG worker/WASM 预热
|
|
245
|
+
viewer.setCanvasOptions({ background: '#f7f8fb', foreground: '#111827' });
|
|
246
|
+
viewer.clear();
|
|
247
|
+
viewer.destroy();
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Loader 架构
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
File / ArrayBuffer
|
|
254
|
+
↓
|
|
255
|
+
CadLoaderRegistry
|
|
256
|
+
↓
|
|
257
|
+
DwgLoader | DxfLoader | DwfLoader | 自定义 loader
|
|
258
|
+
↓
|
|
259
|
+
CadDocument
|
|
260
|
+
↓
|
|
261
|
+
CadWebGLRenderer | CadCanvasRenderer fallback
|
|
262
|
+
↓
|
|
263
|
+
WebGL preview + Canvas overlay
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
所有 loader 都输出统一的 `CadDocument`:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
interface CadDocument {
|
|
270
|
+
format: 'dwg' | 'dxf' | 'dwf' | 'dwfx' | 'xps' | 'unknown';
|
|
271
|
+
layers: Record<string, CadLayer>;
|
|
272
|
+
blocks: Record<string, CadBlock>;
|
|
273
|
+
entities: CadEntity[];
|
|
274
|
+
pages?: CadPage[];
|
|
275
|
+
warnings: string[];
|
|
276
|
+
raw?: unknown;
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
注册自定义 loader:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
viewer.registerLoader({
|
|
284
|
+
id: 'my-cad-format',
|
|
285
|
+
label: 'My CAD Format',
|
|
286
|
+
formats: ['unknown'],
|
|
287
|
+
accepts(input) {
|
|
288
|
+
return input.fileName?.endsWith('.cad') ?? false;
|
|
289
|
+
},
|
|
290
|
+
async load(input) {
|
|
291
|
+
return {
|
|
292
|
+
document: {
|
|
293
|
+
format: 'unknown',
|
|
294
|
+
layers: {},
|
|
295
|
+
blocks: {},
|
|
296
|
+
entities: [],
|
|
297
|
+
metadata: {},
|
|
298
|
+
warnings: []
|
|
299
|
+
},
|
|
300
|
+
bytes: input.buffer instanceof Uint8Array ? input.buffer.byteLength : 0,
|
|
301
|
+
elapsedMs: 0,
|
|
302
|
+
format: 'unknown',
|
|
303
|
+
warnings: []
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## 格式支持说明
|
|
310
|
+
|
|
311
|
+
| 格式 | Loader | 支持范围 |
|
|
312
|
+
|---|---|---|
|
|
313
|
+
| DWG | `DwgLoader` | 使用 LibreDWG WebAssembly。渲染完整度取决于 LibreDWG converter 暴露出的实体。 |
|
|
314
|
+
| DXF | `DxfLoader` | 使用 `dxf-parser` + 内置 fallback。支持基础实体、block/insert、颜色/图层、多段线、文字、hatch boundary、spline 预览。 |
|
|
315
|
+
| DWFx / XPS | `DwfLoader` | 解析 ZIP/OPC 包,并渲染 2D `FixedPage` path/glyph/image 内容。 |
|
|
316
|
+
| 经典 DWF | `DwfLoader` 检测 | 能检测 WHIP/W2D/W3D 包内容并给出明确错误。完整经典 DWF 需要专门 WHIP 解码器或 DWF Toolkit/WASM。 |
|
|
317
|
+
|
|
318
|
+
## 颜色处理
|
|
319
|
+
|
|
320
|
+
颜色解析遵循 CAD 语义,而不是把所有数字都当成 RGB:
|
|
321
|
+
|
|
322
|
+
1. 显式 CSS color 或 true color 对象;
|
|
323
|
+
2. 显式 DWG true-color 整数,包括 `0x0000ff` 这类落在 ACI 数值范围内的低 RGB 值;
|
|
324
|
+
3. 实体 ACI:`colorIndex`、`colorNumber`、`color` 的 `1..255`;
|
|
325
|
+
4. 展开 INSERT/block 时处理 BYBLOCK:`0` 继承插入引用颜色;
|
|
326
|
+
5. BYLAYER:`256` 或未设置时查图层颜色;
|
|
327
|
+
6. viewer foreground 兜底。
|
|
328
|
+
|
|
329
|
+
当 converter 同时暴露有效 ACI 和占位 RGB 值时,图层颜色优先使用 ACI。ACI `7` 会根据画布前景色显示:深色画布上为浅色,浅色画布上为深色。开启 `contrastMode: 'adaptive'` 后,和当前画布背景过近的颜色会被轻量调整,保证可读性。需要严格保留绘图颜色时,可以使用 `contrastMode: 'preserve'`。
|
|
330
|
+
|
|
331
|
+
如果某个 converter 输出的是 BGR true-color 整数:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
new CadViewer({ canvasOptions: { trueColorByteOrder: 'bgr' } });
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## 开发命令
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npm install
|
|
341
|
+
npm run dev # 运行 demo
|
|
342
|
+
npm run typecheck # TypeScript 检查
|
|
343
|
+
npm run build # 构建 library + demo
|
|
344
|
+
npm run preview # 预览构建后的 demo
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## npm 发布命令
|
|
348
|
+
|
|
349
|
+
1. 构建并检查包内容:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
npm run build:lib
|
|
353
|
+
npm run pack:dry
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
2. 发布:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
npm login
|
|
360
|
+
npm publish --access public
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
仓库内也提供:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
npm run release:npm
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Cloudflare Pages 发布命令
|
|
370
|
+
|
|
371
|
+
使用 Wrangler Direct Upload:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
npm install
|
|
375
|
+
npm run build:demo
|
|
376
|
+
npx wrangler pages deploy dist-demo --project-name cad-viewer
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
或直接使用:
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
npm run deploy:pages
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
GitHub Actions 自动发布需要配置仓库 secrets:
|
|
386
|
+
|
|
387
|
+
```text
|
|
388
|
+
CLOUDFLARE_API_TOKEN
|
|
389
|
+
CLOUDFLARE_ACCOUNT_ID
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
工作流文件在 `.github/workflows/pages.yml`。
|
|
393
|
+
|
|
394
|
+
## 目录结构
|
|
395
|
+
|
|
396
|
+
```text
|
|
397
|
+
src/
|
|
398
|
+
core/ 格式检测、颜色、几何、变换、统一类型
|
|
399
|
+
loaders/ DwgLoader、DxfLoader、DwfLoader、CadLoaderRegistry
|
|
400
|
+
viewer/ CadViewer 组件和 Canvas renderer
|
|
401
|
+
demo/ 专业 Vite demo UI
|
|
402
|
+
docs/ 中英文架构/格式文档
|
|
403
|
+
scripts/ clean 和 LibreDWG WASM 复制脚本
|
|
404
|
+
public/wasm/ demo 的 WASM 输出目录
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## 许可证
|
|
408
|
+
|
|
409
|
+
AGPL-3.0-only。这是严格 copyleft 许可证:如果你分发修改版本,或通过网络提供修改版本服务,请认真审查源码公开义务。
|
|
410
|
+
|
|
411
|
+
默认 DWG loader 依赖 `@mlightcad/libredwg-web`,该包为 GPL-3.0-only。若用于闭源商业产品,请替换为合规授权的 DWG parser/converter,并重新审查依赖许可证。
|