@file-viewer/renderer-cad 3.0.1 → 3.0.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/README.en.md +24 -0
- package/README.md +24 -0
- package/dist/cad.js +103 -22
- package/dist/colorMode.d.ts +15 -0
- package/dist/colorMode.js +47 -0
- package/dist/export.d.ts +6 -0
- package/dist/export.js +28 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +5 -4
package/README.en.md
CHANGED
|
@@ -49,3 +49,27 @@ For private deployments, override them with `options.cad.wasmPath`, `options.cad
|
|
|
49
49
|
## Migration Note
|
|
50
50
|
|
|
51
51
|
CAD preview has moved completely out of `@file-viewer/core`. Core now only keeps the asset manifest, shared types, and a compatibility error message, and it no longer installs `@flyfish-dev/cad-viewer` by default. Install this package and pass it through `renderers`, or use `@file-viewer/preset-all` for the complete CAD experience.
|
|
52
|
+
|
|
53
|
+
## Monochrome plot mode
|
|
54
|
+
|
|
55
|
+
Set `cad.colorMode` to `source` or `monochrome`. Monochrome rendering uses the CAD engine's entity-color policy rather than a CSS filter, keeping Canvas, WebGL, text overlays and native DWF output consistent while preserving alpha, line types, line weights and source data.
|
|
56
|
+
|
|
57
|
+
Source mode defaults to a dark background; monochrome defaults to black lines on white paper. Adaptive contrast makes lines and text near the background color readable. Use `cad.canvasOptions.contrastMode: 'preserve'` for exact source colors. Explicit `cad.canvasOptions.background` / `cad.dwfBackground` values survive mode changes.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
{
|
|
61
|
+
cad: {
|
|
62
|
+
colorMode: 'monochrome',
|
|
63
|
+
monochromeColor: '#000000',
|
|
64
|
+
showColorModeToggle: true,
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Images, print and offline HTML
|
|
70
|
+
|
|
71
|
+
Select the color mode, then use Print or HTML in the shared toolbar. Output redraws and captures the current view, including WebGL lines and text overlays, without layer panels or controls. HTML embeds a PNG instead of a temporary blob URL. The print window supports the browser's Save as PDF and retains File Viewer permission checks, watermarks and masks.
|
|
72
|
+
|
|
73
|
+
PNG and JPEG buttons download the same rendered view, including configured text or image watermarks. Both `toolbar.permissions.download` and `toolbar.permissions['export-html']` must allow the operation. The owning viewer runs its normal `beforeOperation`, toolbar `beforeOperation` and `beforeDownload` hooks before capture; cancellation or a document/permission change prevents the download. Use `cad.showImageExport: false` to hide these renderer-local buttons. A missing watermark fails explicitly without breaking the live preview. Print masks apply to Print, not to image downloads.
|
|
74
|
+
|
|
75
|
+
This is a raster snapshot of the current camera view / current DWF page, not a vector conversion or batch export of every sheet. Use Fit first to include the full drawing. Original-file download never changes the input bytes.
|
package/README.md
CHANGED
|
@@ -49,3 +49,27 @@ const options = {
|
|
|
49
49
|
## 迁移说明
|
|
50
50
|
|
|
51
51
|
CAD 预览已经从 `@file-viewer/core` 中彻底移出,core 只保留资产 manifest、类型和兼容错误提示,不再默认安装 `@flyfish-dev/cad-viewer`。完整 CAD 能力请安装本包并传入 `renderers`,或直接使用 `@file-viewer/preset-all`。
|
|
52
|
+
|
|
53
|
+
## 黑白出图模式
|
|
54
|
+
|
|
55
|
+
`cad.colorMode` 可设为 `source` 或 `monochrome`。黑白模式通过 CAD 引擎的实体颜色策略实现,不使用 CSS 滤镜,因此 Canvas、WebGL、文字覆盖层及原生 DWF 渲染可保持一致,同时保留透明度、线型、线宽和源文件数据。
|
|
56
|
+
|
|
57
|
+
默认原色模式使用深色背景,黑白模式使用白纸黑线。自适应对比度会提高与背景过近的线条和文字的可见性;要求严格显示源颜色时可设 `cad.canvasOptions.contrastMode: 'preserve'`。显式设置的 `cad.canvasOptions.background` / `cad.dwfBackground` 不会被模式切换覆盖。
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
{
|
|
61
|
+
cad: {
|
|
62
|
+
colorMode: 'monochrome',
|
|
63
|
+
monochromeColor: '#000000',
|
|
64
|
+
showColorModeToggle: true,
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 图片、打印与离线 HTML
|
|
70
|
+
|
|
71
|
+
先选择原色或黑白模式,再使用统一工具栏的“打印”或“HTML”。输出会重新绘制并立即捕获当前视图,包含 WebGL 线条和文字覆盖层,不含图层面板或工具栏。HTML 内嵌 PNG,不依赖临时 blob 地址;打印窗口可使用浏览器的“另存为 PDF”,并保留 File Viewer 的权限检查、水印和遮罩。
|
|
72
|
+
|
|
73
|
+
CAD 工具栏的 PNG、JPEG 按钮下载同一视图,并保留配置的文本或图片水印。`toolbar.permissions.download` 与 `toolbar.permissions['export-html']` 都必须允许;捕获前由所属组件执行既有 `beforeOperation`、工具栏 `beforeOperation` 和 `beforeDownload` 钩子。取消操作、切换文档或撤销权限后不会下载旧快照。`cad.showImageExport: false` 可隐藏这两个格式专用按钮。水印资源不可读时明确失败,预览仍保持可用。打印遮罩仅作用于打印,不作用于图片下载。
|
|
74
|
+
|
|
75
|
+
这里输出的是当前相机视图 / 当前 DWF 页的栅格快照,不是整个 CAD 文件的矢量转换,也不会自动批量打印其他图纸页。需要完整图纸时先点击“适配”。原文件下载始终保持输入字节不变。
|
package/dist/cad.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { CadViewer, inferEntityKind, } from '@flyfish-dev/cad-viewer';
|
|
2
2
|
import { resolveFileViewerCadAssetUrls, resolveFileViewerRuntimeAssetBaseUrl, } from '@file-viewer/core/assets';
|
|
3
|
-
import { createFileViewerViewStateChange, createFileViewerViewStateChangeEmitter, createFileViewerTranslator, createFileViewerZoomChangeEmitter, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, resolveFileViewerLocale, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
|
|
3
|
+
import { createFileViewerViewStateChange, createFileViewerViewStateChangeEmitter, createFileViewerTranslator, createFileViewerZoomChangeEmitter, createFileViewerCanvasImageBlob, isFileViewerSnapshotDownloadPermitted, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, resolveFileViewerLocale, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
|
|
4
|
+
import { applyCadViewerColorMode, normalizeFileViewerCadColorMode, resolveFileViewerCadMonochromeColor, resolveFileViewerCadCanvasOptions, resolveCadViewerSourceDocument, supportsCadViewerColorMode, } from './colorMode.js';
|
|
5
|
+
import { captureFileViewerCadCanvas, createFileViewerCadExportAdapter } from './export.js';
|
|
4
6
|
const CAD_WORKER_TIMEOUT = 120000;
|
|
5
7
|
const CAD_DEFAULT_FIT_PADDING = 0.92;
|
|
6
8
|
const CAD_BOUNDS_EPSILON = 1e-9;
|
|
@@ -8,12 +10,21 @@ const CAD_BEST_FIT_OUTLIER_RATIO = 8;
|
|
|
8
10
|
const CAD_NATIVE_MIN_ZOOM_RATIO = 0.05;
|
|
9
11
|
const CAD_NATIVE_MAX_ZOOM_RATIO = 64;
|
|
10
12
|
const cadStyle = `
|
|
11
|
-
.cad-shell{display:flex;height:100%;min-height:100%;flex-direction:column;background:#f5f7fb;color:#142335}
|
|
13
|
+
.cad-shell{display:flex;height:100%;min-height:100%;flex-direction:column;background:#f5f7fb;color:#142335;container-type:inline-size;container-name:file-viewer-cad}
|
|
12
14
|
.cad-shell *{box-sizing:border-box}
|
|
13
|
-
.cad-toolbar{display:flex;min-height:48px;align-items:center;justify-content:space-between;gap:16px;padding:0 14px;border-bottom:1px solid rgba(15,23,42,.08);background:#fff}
|
|
15
|
+
.cad-toolbar{display:flex;flex-shrink:0;min-height:48px;align-items:center;justify-content:space-between;gap:16px;padding:0 14px;border-bottom:1px solid rgba(15,23,42,.08);background:#fff}
|
|
14
16
|
.cad-tools,.cad-meta{display:flex;align-items:center;gap:8px}
|
|
17
|
+
.cad-tools{flex-wrap:wrap;padding:6px 0}
|
|
18
|
+
.cad-tools button.cad-export-image{min-width:44px;min-height:40px;padding:0 10px;white-space:nowrap}
|
|
19
|
+
.cad-tools button[hidden]{display:none}
|
|
20
|
+
.cad-tools button:disabled{cursor:not-allowed;opacity:.46}
|
|
21
|
+
.cad-export-error{margin:0;padding:6px 14px;background:#fff4ed;color:#b42318;font-size:12px}
|
|
22
|
+
.cad-export-error[hidden]{display:none}
|
|
15
23
|
.cad-tools button{min-width:34px;min-height:30px;border:0;border-radius:8px;background:rgba(15,23,42,.06);color:#25344c;cursor:pointer;font-weight:800;letter-spacing:0;transition:background-color .18s ease,color .18s ease}
|
|
16
24
|
.cad-tools button:hover{background:rgba(31,150,110,.14);color:#0f8f62}
|
|
25
|
+
.cad-tools button.cad-color-mode{min-width:52px;padding:0 10px;font-size:12px}
|
|
26
|
+
.cad-tools button.cad-color-mode[aria-pressed='true']{background:#0f172a;color:#fff}
|
|
27
|
+
.cad-tools button.cad-color-mode:disabled{cursor:not-allowed;opacity:.46}
|
|
17
28
|
.cad-zoom,.cad-meta span{color:#64748b;font-size:12px;font-weight:800;letter-spacing:0}
|
|
18
29
|
.cad-meta span{border-radius:999px;padding:5px 9px;background:rgba(15,23,42,.06)}
|
|
19
30
|
.cad-body{display:grid;min-height:0;flex:1;grid-template-columns:minmax(176px,236px) minmax(0,1fr) minmax(142px,176px);background:#eef2f7}
|
|
@@ -94,7 +105,8 @@ const cadStyle = `
|
|
|
94
105
|
[data-viewer-theme='dark'] .cad-canvas-wrap{background:linear-gradient(90deg,rgba(148,163,184,.08) 1px,transparent 1px),linear-gradient(180deg,rgba(148,163,184,.08) 1px,transparent 1px),#090d14;background-size:28px 28px}
|
|
95
106
|
[data-viewer-theme='dark'] .cad-state{background:rgba(15,23,42,.92);color:#cbd5e1;box-shadow:0 18px 44px rgba(0,0,0,.34)}
|
|
96
107
|
@media (prefers-color-scheme:dark){[data-viewer-theme='system'] .cad-shell{background:#111827;color:#e5edf6}[data-viewer-theme='system'] .cad-body{background:#0d1117}[data-viewer-theme='system'] .cad-toolbar,[data-viewer-theme='system'] .cad-layers,[data-viewer-theme='system'] .cad-inspector{border-color:rgba(139,148,158,.2);background:#111827;color:#e5edf6}[data-viewer-theme='system'] .cad-layers-head{border-color:rgba(139,148,158,.2);background:rgba(17,24,39,.96);color:#f8fafc}[data-viewer-theme='system'] .cad-tools button,[data-viewer-theme='system'] .cad-meta span,[data-viewer-theme='system'] .cad-inspector dl div{background:#1f2937;color:#cbd5e1}[data-viewer-theme='system'] .cad-layers button,[data-viewer-theme='system'] .cad-inspector strong,[data-viewer-theme='system'] .cad-inspector dd{color:#e5edf6}[data-viewer-theme='system'] .cad-layers button:hover{background:#1f2937}[data-viewer-theme='system'] .cad-zoom,[data-viewer-theme='system'] .cad-meta span,[data-viewer-theme='system'] .cad-inspector dt,[data-viewer-theme='system'] .cad-layers-head span{color:#94a3b8}[data-viewer-theme='system'] .cad-canvas-wrap{background:linear-gradient(90deg,rgba(148,163,184,.08) 1px,transparent 1px),linear-gradient(180deg,rgba(148,163,184,.08) 1px,transparent 1px),#090d14;background-size:28px 28px}[data-viewer-theme='system'] .cad-state{background:rgba(15,23,42,.92);color:#cbd5e1;box-shadow:0 18px 44px rgba(0,0,0,.34)}}
|
|
97
|
-
@media (max-width:860px){.cad-body,.cad-body.without-layers{grid-template-columns:minmax(0,1fr)}.cad-layers,.cad-inspector{display:none}}
|
|
108
|
+
@media (max-width:860px){.cad-body,.cad-body.without-layers{grid-template-columns:minmax(0,1fr)}.cad-layers,.cad-inspector,.cad-meta{display:none}.cad-tools{flex:1}.cad-tools button{min-width:44px;min-height:40px}}
|
|
109
|
+
@container file-viewer-cad (max-width:600px){.cad-meta{display:none}.cad-tools{flex:1}.cad-tools button{min-width:44px;min-height:40px}}
|
|
98
110
|
`;
|
|
99
111
|
const createStyle = () => {
|
|
100
112
|
const style = document.createElement('style');
|
|
@@ -643,11 +655,13 @@ const resolveLayerSourceNames = (document, layer) => {
|
|
|
643
655
|
return Array.from(names);
|
|
644
656
|
};
|
|
645
657
|
export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
646
|
-
var _a;
|
|
658
|
+
var _a, _b;
|
|
647
659
|
const normalizedType = normalizeType(type);
|
|
648
660
|
const options = ((_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.cad) || {};
|
|
649
661
|
const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
|
|
650
662
|
const locale = resolveFileViewerLocale(context === null || context === void 0 ? void 0 : context.options);
|
|
663
|
+
const monochromeColor = resolveFileViewerCadMonochromeColor(options.monochromeColor);
|
|
664
|
+
let colorMode = normalizeFileViewerCadColorMode(options.colorMode);
|
|
651
665
|
let status = 'loading';
|
|
652
666
|
let progressMessage = t('cad.state.loadingViewer');
|
|
653
667
|
let errorMessage = '';
|
|
@@ -663,6 +677,7 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
663
677
|
let fitViewActive = true;
|
|
664
678
|
let nativeZoomRatio = 1;
|
|
665
679
|
let disposed = false;
|
|
680
|
+
let exportingImage = false;
|
|
666
681
|
const style = createStyle();
|
|
667
682
|
const shell = createElement('div', 'cad-shell');
|
|
668
683
|
shell.dataset.viewerZoomProvider = 'cad';
|
|
@@ -672,18 +687,61 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
672
687
|
const zoomOutButton = createElement('button', undefined, '-');
|
|
673
688
|
const zoomText = createElement('span', 'cad-zoom', '100%');
|
|
674
689
|
const zoomInButton = createElement('button', undefined, '+');
|
|
690
|
+
const colorModeButton = createElement('button', 'cad-color-mode');
|
|
691
|
+
colorModeButton.hidden = options.showColorModeToggle === false;
|
|
675
692
|
const meta = createElement('div', 'cad-meta');
|
|
676
693
|
const typeMeta = createElement('span', undefined, normalizedType.toUpperCase());
|
|
677
694
|
const backendMeta = createElement('span', undefined, 'AUTO');
|
|
678
|
-
[fitButton, zoomOutButton, zoomInButton].forEach(button => {
|
|
695
|
+
[fitButton, zoomOutButton, zoomInButton, colorModeButton].forEach(button => {
|
|
679
696
|
button.type = 'button';
|
|
680
697
|
});
|
|
681
698
|
fitButton.title = t('cad.toolbar.fit');
|
|
682
699
|
zoomOutButton.title = t('cad.toolbar.zoomOut');
|
|
683
700
|
zoomInButton.title = t('cad.toolbar.zoomIn');
|
|
684
|
-
tools.append(fitButton, zoomOutButton, zoomText, zoomInButton);
|
|
701
|
+
tools.append(fitButton, zoomOutButton, zoomText, zoomInButton, colorModeButton);
|
|
702
|
+
const imageButtons = ['png', 'jpeg'].map(format => {
|
|
703
|
+
const button = createElement('button', `cad-export-image cad-export-${format}`, format.toUpperCase());
|
|
704
|
+
button.type = 'button';
|
|
705
|
+
button.title = t('cad.toolbar.exportImage', { format: format.toUpperCase() });
|
|
706
|
+
button.setAttribute('aria-label', button.title);
|
|
707
|
+
button.hidden = !(context === null || context === void 0 ? void 0 : context.requestSnapshotDownload) || options.showImageExport === false ||
|
|
708
|
+
!isFileViewerSnapshotDownloadPermitted(context === null || context === void 0 ? void 0 : context.options);
|
|
709
|
+
button.addEventListener('click', async () => {
|
|
710
|
+
var _a;
|
|
711
|
+
if (disposed || status !== 'ready' || exportingImage)
|
|
712
|
+
return;
|
|
713
|
+
exportingImage = true;
|
|
714
|
+
exportError.hidden = true;
|
|
715
|
+
syncState();
|
|
716
|
+
try {
|
|
717
|
+
await ((_a = context === null || context === void 0 ? void 0 : context.requestSnapshotDownload) === null || _a === void 0 ? void 0 : _a.call(context, async (watermark) => {
|
|
718
|
+
const snapshot = await captureFileViewerCadCanvas(() => viewer);
|
|
719
|
+
const blob = await createFileViewerCanvasImageBlob(snapshot, format, watermark, snapshot.width / stage.clientWidth);
|
|
720
|
+
const name = buildFileName().replace(/\.[^.]+$/, '') || 'drawing';
|
|
721
|
+
return { blob, filename: `${name}.${format === 'jpeg' ? 'jpg' : 'png'}` };
|
|
722
|
+
}));
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
if (!disposed) {
|
|
726
|
+
exportError.textContent = t('cad.error.exportFailed', { message: error instanceof Error ? error.message : String(error) });
|
|
727
|
+
exportError.hidden = false;
|
|
728
|
+
console.error(error);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
finally {
|
|
732
|
+
exportingImage = false;
|
|
733
|
+
if (!disposed)
|
|
734
|
+
syncState();
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
tools.append(button);
|
|
738
|
+
return button;
|
|
739
|
+
});
|
|
685
740
|
meta.append(typeMeta, backendMeta);
|
|
686
741
|
toolbar.append(tools, meta);
|
|
742
|
+
const exportError = createElement('p', 'cad-export-error');
|
|
743
|
+
exportError.setAttribute('role', 'alert');
|
|
744
|
+
exportError.hidden = true;
|
|
687
745
|
const body = createElement('div', 'cad-body without-layers');
|
|
688
746
|
const layersPanel = createElement('aside', 'cad-layers');
|
|
689
747
|
layersPanel.hidden = true;
|
|
@@ -705,7 +763,7 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
705
763
|
warningText.hidden = true;
|
|
706
764
|
inspector.append(inspectorTitle, inspectorList, warningText);
|
|
707
765
|
body.append(layersPanel, canvasWrap, inspector);
|
|
708
|
-
shell.append(toolbar, body);
|
|
766
|
+
shell.append(toolbar, exportError, body);
|
|
709
767
|
target.replaceChildren(style, shell);
|
|
710
768
|
const buildFileName = () => {
|
|
711
769
|
return (context === null || context === void 0 ? void 0 : context.filename) || `drawing.${normalizedType}`;
|
|
@@ -749,6 +807,8 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
749
807
|
status,
|
|
750
808
|
view: viewState ? { ...viewState } : null,
|
|
751
809
|
backend: renderStats === null || renderStats === void 0 ? void 0 : renderStats.backend,
|
|
810
|
+
colorMode,
|
|
811
|
+
monochromeColor: colorMode === 'monochrome' ? monochromeColor : undefined,
|
|
752
812
|
layerCount: layers.length,
|
|
753
813
|
visibleLayers: layers
|
|
754
814
|
.filter(layer => layer.isVisible !== false && !layer.isFrozen)
|
|
@@ -885,12 +945,15 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
885
945
|
: layer.name;
|
|
886
946
|
button.setAttribute('aria-pressed', String(layerVisible));
|
|
887
947
|
const color = createElement('span', 'cad-layer-color');
|
|
888
|
-
if (
|
|
948
|
+
if (colorMode === 'monochrome') {
|
|
949
|
+
color.style.background = monochromeColor;
|
|
950
|
+
}
|
|
951
|
+
else if (typeof layer.color === 'string') {
|
|
889
952
|
color.style.background = layer.color;
|
|
890
953
|
}
|
|
891
954
|
button.append(color, createElement('span', undefined, layer.name));
|
|
892
955
|
button.addEventListener('click', () => {
|
|
893
|
-
const document = viewer
|
|
956
|
+
const document = resolveCadViewerSourceDocument(viewer);
|
|
894
957
|
if (!document) {
|
|
895
958
|
return;
|
|
896
959
|
}
|
|
@@ -915,8 +978,21 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
915
978
|
}));
|
|
916
979
|
};
|
|
917
980
|
const syncState = () => {
|
|
981
|
+
imageButtons.forEach(button => {
|
|
982
|
+
button.disabled = status !== 'ready' || exportingImage || !viewer ||
|
|
983
|
+
typeof viewer.captureCanvas !== 'function';
|
|
984
|
+
});
|
|
918
985
|
zoomText.textContent = `${getZoomPercent()}%`;
|
|
919
986
|
backendMeta.textContent = ((renderStats === null || renderStats === void 0 ? void 0 : renderStats.backend) || 'auto').toUpperCase();
|
|
987
|
+
const colorModeSupported = supportsCadViewerColorMode(viewer);
|
|
988
|
+
colorModeButton.disabled = status !== 'ready' || !colorModeSupported;
|
|
989
|
+
colorModeButton.setAttribute('aria-pressed', String(colorMode === 'monochrome'));
|
|
990
|
+
colorModeButton.textContent = t(colorMode === 'monochrome'
|
|
991
|
+
? 'cad.toolbar.monochrome'
|
|
992
|
+
: 'cad.toolbar.colorSource');
|
|
993
|
+
colorModeButton.title = t(colorMode === 'monochrome'
|
|
994
|
+
? 'cad.toolbar.colorSource'
|
|
995
|
+
: 'cad.toolbar.monochrome');
|
|
920
996
|
state.hidden = status === 'ready';
|
|
921
997
|
state.classList.toggle('error', status === 'error');
|
|
922
998
|
if (status === 'loading') {
|
|
@@ -1054,20 +1130,21 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
1054
1130
|
fitButton.addEventListener('click', () => fitToView());
|
|
1055
1131
|
zoomInButton.addEventListener('click', zoomIn);
|
|
1056
1132
|
zoomOutButton.addEventListener('click', zoomOut);
|
|
1133
|
+
colorModeButton.addEventListener('click', () => {
|
|
1134
|
+
const previousMode = colorMode;
|
|
1135
|
+
colorMode = colorMode === 'monochrome' ? 'source' : 'monochrome';
|
|
1136
|
+
if (!applyCadViewerColorMode(viewer, colorMode, monochromeColor, options)) {
|
|
1137
|
+
colorMode = previousMode;
|
|
1138
|
+
syncState();
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
syncUi();
|
|
1142
|
+
emitCadViewStateChange('cad-view-change', 'user');
|
|
1143
|
+
});
|
|
1057
1144
|
const createViewer = () => {
|
|
1058
1145
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
1059
1146
|
const { wasmPath, workerUrl, dwfWasmUrl } = resolveFileViewerCadAssetUrls(options, getCadDocumentBaseUrl(target));
|
|
1060
|
-
const canvasOptions =
|
|
1061
|
-
background: '#f8fafc',
|
|
1062
|
-
foreground: '#0f172a',
|
|
1063
|
-
contrastMode: 'adaptive',
|
|
1064
|
-
minColorContrast: 2.4,
|
|
1065
|
-
showPageBounds: true,
|
|
1066
|
-
showUnsupportedMarkers: true,
|
|
1067
|
-
enableSpatialIndex: true,
|
|
1068
|
-
maxVisibleTextLabels: 2400,
|
|
1069
|
-
...(options.canvasOptions || {}),
|
|
1070
|
-
};
|
|
1147
|
+
const canvasOptions = resolveFileViewerCadCanvasOptions(options, colorMode);
|
|
1071
1148
|
const nextViewer = new CadViewer({
|
|
1072
1149
|
container: stage,
|
|
1073
1150
|
nativeHost,
|
|
@@ -1084,7 +1161,7 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
1084
1161
|
keepRaw: (_e = options.keepRaw) !== null && _e !== void 0 ? _e : false,
|
|
1085
1162
|
dwfPreferWebgl: (_f = options.dwfPreferWebgl) !== null && _f !== void 0 ? _f : true,
|
|
1086
1163
|
dwfPreferWasm: (_g = options.dwfPreferWasm) !== null && _g !== void 0 ? _g : true,
|
|
1087
|
-
dwfBackground: options.dwfBackground
|
|
1164
|
+
dwfBackground: options.dwfBackground,
|
|
1088
1165
|
dwfMaxDevicePixelRatio: options.dwfMaxDevicePixelRatio,
|
|
1089
1166
|
dwfMaxCanvasPixels: options.dwfMaxCanvasPixels,
|
|
1090
1167
|
dwfMaxGpuCacheBytes: options.dwfMaxGpuCacheBytes,
|
|
@@ -1094,6 +1171,7 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
1094
1171
|
dwfMaxOverviewStrokeCssPx: options.dwfMaxOverviewStrokeCssPx,
|
|
1095
1172
|
dwfMinTextCssPx: options.dwfMinTextCssPx,
|
|
1096
1173
|
dwfMinFilledAreaCssPx: options.dwfMinFilledAreaCssPx,
|
|
1174
|
+
...{ colorMode, monochromeColor },
|
|
1097
1175
|
autoFit: true,
|
|
1098
1176
|
canvasOptions,
|
|
1099
1177
|
onLoadProgress: updateProgress,
|
|
@@ -1210,11 +1288,14 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
|
|
|
1210
1288
|
resizeObserver.observe(stage);
|
|
1211
1289
|
}
|
|
1212
1290
|
syncUi();
|
|
1291
|
+
(_b = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _b === void 0 ? void 0 : _b.call(context, createFileViewerCadExportAdapter(() => viewer, context.filename, () => stage.querySelector('.dwfv-stage') || stage));
|
|
1213
1292
|
void loadCad();
|
|
1214
1293
|
return {
|
|
1215
1294
|
$el: shell,
|
|
1216
1295
|
unmount() {
|
|
1296
|
+
var _a;
|
|
1217
1297
|
disposed = true;
|
|
1298
|
+
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
|
|
1218
1299
|
unregisterFileViewerViewStateProvider(shell);
|
|
1219
1300
|
unregisterFileViewerZoomProvider(shell);
|
|
1220
1301
|
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FileViewerCadColorMode, FileViewerCadOptions } from '@file-viewer/core';
|
|
2
|
+
import type { CanvasViewerOptions } from '@flyfish-dev/cad-viewer';
|
|
3
|
+
export interface CadViewerColorModeAdapter {
|
|
4
|
+
setColorMode?: (mode: FileViewerCadColorMode, monochromeColor?: string) => void;
|
|
5
|
+
getColorMode?: () => FileViewerCadColorMode;
|
|
6
|
+
getMonochromeColor?: () => string | undefined;
|
|
7
|
+
setCanvasOptions?: (options: CanvasViewerOptions) => void;
|
|
8
|
+
isNativeRendererActive?: () => boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function normalizeFileViewerCadColorMode(value: unknown): FileViewerCadColorMode;
|
|
11
|
+
export declare function resolveFileViewerCadMonochromeColor(value: unknown, fallback?: string): string;
|
|
12
|
+
export declare function resolveFileViewerCadCanvasOptions(options: FileViewerCadOptions, mode: FileViewerCadColorMode): CanvasViewerOptions;
|
|
13
|
+
export declare function supportsCadViewerColorMode(value: unknown): value is CadViewerColorModeAdapter;
|
|
14
|
+
export declare function resolveCadViewerSourceDocument(viewer: unknown): unknown;
|
|
15
|
+
export declare function applyCadViewerColorMode(viewer: unknown, mode: FileViewerCadColorMode, monochromeColor: string, options?: FileViewerCadOptions): boolean;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export function normalizeFileViewerCadColorMode(value) {
|
|
2
|
+
return value === 'monochrome' ? 'monochrome' : 'source';
|
|
3
|
+
}
|
|
4
|
+
export function resolveFileViewerCadMonochromeColor(value, fallback = '#000000') {
|
|
5
|
+
if (typeof value === 'string' && value.trim())
|
|
6
|
+
return value.trim();
|
|
7
|
+
return fallback;
|
|
8
|
+
}
|
|
9
|
+
export function resolveFileViewerCadCanvasOptions(options, mode) {
|
|
10
|
+
return {
|
|
11
|
+
background: mode === 'monochrome' ? '#ffffff' : '#05070d',
|
|
12
|
+
foreground: mode === 'monochrome'
|
|
13
|
+
? resolveFileViewerCadMonochromeColor(options.monochromeColor)
|
|
14
|
+
: '#f8fafc',
|
|
15
|
+
contrastMode: 'adaptive',
|
|
16
|
+
minColorContrast: 2.4,
|
|
17
|
+
showPageBounds: true,
|
|
18
|
+
showUnsupportedMarkers: true,
|
|
19
|
+
enableSpatialIndex: true,
|
|
20
|
+
maxVisibleTextLabels: 2400,
|
|
21
|
+
...options.canvasOptions,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function supportsCadViewerColorMode(value) {
|
|
25
|
+
return Boolean(value && typeof value.setColorMode === 'function');
|
|
26
|
+
}
|
|
27
|
+
export function resolveCadViewerSourceDocument(viewer) {
|
|
28
|
+
var _a, _b, _c;
|
|
29
|
+
const candidate = viewer;
|
|
30
|
+
return (_b = (_a = candidate === null || candidate === void 0 ? void 0 : candidate.getSourceDocument) === null || _a === void 0 ? void 0 : _a.call(candidate)) !== null && _b !== void 0 ? _b : (_c = candidate === null || candidate === void 0 ? void 0 : candidate.getDocument) === null || _c === void 0 ? void 0 : _c.call(candidate);
|
|
31
|
+
}
|
|
32
|
+
export function applyCadViewerColorMode(viewer, mode, monochromeColor, options) {
|
|
33
|
+
var _a, _b, _c;
|
|
34
|
+
if (!supportsCadViewerColorMode(viewer))
|
|
35
|
+
return false;
|
|
36
|
+
(_a = viewer.setColorMode) === null || _a === void 0 ? void 0 : _a.call(viewer, mode, monochromeColor);
|
|
37
|
+
if (options) {
|
|
38
|
+
const canvasOptions = resolveFileViewerCadCanvasOptions(options, mode);
|
|
39
|
+
// The native setter also forwards the canvas background to DWF. Keep an
|
|
40
|
+
// explicitly configured DWF background instead of overwriting it on toggle.
|
|
41
|
+
if (((_b = viewer.isNativeRendererActive) === null || _b === void 0 ? void 0 : _b.call(viewer)) && options.dwfBackground) {
|
|
42
|
+
canvasOptions.background = options.dwfBackground;
|
|
43
|
+
}
|
|
44
|
+
(_c = viewer.setCanvasOptions) === null || _c === void 0 ? void 0 : _c.call(viewer, canvasOptions);
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FileRenderExportAdapter } from '@file-viewer/core';
|
|
2
|
+
export interface CadCanvasCaptureAdapter {
|
|
3
|
+
captureCanvas?: () => Promise<HTMLCanvasElement>;
|
|
4
|
+
}
|
|
5
|
+
export declare function captureFileViewerCadCanvas(getViewer: () => CadCanvasCaptureAdapter | null): Promise<HTMLCanvasElement>;
|
|
6
|
+
export declare function createFileViewerCadExportAdapter(getViewer: () => CadCanvasCaptureAdapter | null, filename?: string, getPage?: () => HTMLElement): FileRenderExportAdapter;
|
package/dist/export.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export async function captureFileViewerCadCanvas(getViewer) {
|
|
2
|
+
const viewer = getViewer();
|
|
3
|
+
if (!(viewer === null || viewer === void 0 ? void 0 : viewer.captureCanvas))
|
|
4
|
+
throw new Error('The CAD engine does not support canvas snapshots.');
|
|
5
|
+
const snapshot = await viewer.captureCanvas();
|
|
6
|
+
if (getViewer() !== viewer)
|
|
7
|
+
throw new Error('The CAD document changed during export.');
|
|
8
|
+
return snapshot;
|
|
9
|
+
}
|
|
10
|
+
export function createFileViewerCadExportAdapter(getViewer, filename = 'CAD drawing', getPage) {
|
|
11
|
+
return {
|
|
12
|
+
includeDocumentStyles: false,
|
|
13
|
+
getPrintMaskPages: getPage ? () => [getPage()] : undefined,
|
|
14
|
+
async toHtml() {
|
|
15
|
+
const snapshot = await captureFileViewerCadCanvas(getViewer);
|
|
16
|
+
const image = snapshot.ownerDocument.createElement('img');
|
|
17
|
+
image.src = snapshot.toDataURL('image/png');
|
|
18
|
+
image.alt = filename;
|
|
19
|
+
image.width = snapshot.width;
|
|
20
|
+
image.height = snapshot.height;
|
|
21
|
+
image.style.cssText = 'display:block;max-width:100%;height:auto;margin:0 auto;';
|
|
22
|
+
const page = snapshot.ownerDocument.createElement('div');
|
|
23
|
+
page.dataset.viewerPrintPageIndex = '0';
|
|
24
|
+
page.appendChild(image);
|
|
25
|
+
return page.outerHTML;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type FileRenderHandler, type FileViewerRenderedInstance, type FileViewerRendererPlugin, type RendererDefinition } from '@file-viewer/core';
|
|
2
|
+
export { applyCadViewerColorMode, normalizeFileViewerCadColorMode, resolveCadViewerSourceDocument, resolveFileViewerCadMonochromeColor, supportsCadViewerColorMode, } from './colorMode.js';
|
|
3
|
+
export type { CadViewerColorModeAdapter } from './colorMode.js';
|
|
2
4
|
export declare const cadRendererDefinition: RendererDefinition;
|
|
3
5
|
export declare const renderFileViewerCad: FileRenderHandler<FileViewerRenderedInstance, HTMLDivElement>;
|
|
4
6
|
export declare const cadRenderer: FileViewerRendererPlugin<FileRenderHandler<FileViewerRenderedInstance, HTMLDivElement>>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_RENDERER_DEFINITIONS, } from '@file-viewer/core';
|
|
2
|
+
export { applyCadViewerColorMode, normalizeFileViewerCadColorMode, resolveCadViewerSourceDocument, resolveFileViewerCadMonochromeColor, supportsCadViewerColorMode, } from './colorMode.js';
|
|
2
3
|
const cadDefinition = DEFAULT_RENDERER_DEFINITIONS.find(definition => definition.id === 'cad');
|
|
3
4
|
if (!cadDefinition) {
|
|
4
5
|
throw new Error('@file-viewer/renderer-cad could not locate the shared CAD format definition.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/renderer-cad",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Standalone CAD renderer plugin for File Viewer powered by @flyfish-dev/cad-viewer.",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"LICENSE"
|
|
57
57
|
],
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@file-viewer/core": "3.0.
|
|
60
|
-
"@flyfish-dev/cad-viewer": "0.8.
|
|
59
|
+
"@file-viewer/core": "3.0.3",
|
|
60
|
+
"@flyfish-dev/cad-viewer": "0.8.2"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"typescript": "^6.0.3"
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"license": "Apache-2.0",
|
|
66
66
|
"scripts": {
|
|
67
67
|
"build": "tsc -b tsconfig.json",
|
|
68
|
-
"type-check": "tsc -b tsconfig.json"
|
|
68
|
+
"type-check": "tsc -b tsconfig.json",
|
|
69
|
+
"verify:color-mode": "node scripts/verify-color-mode.mjs"
|
|
69
70
|
}
|
|
70
71
|
}
|