@file-viewer/renderer-cad 3.0.1 → 3.0.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/README.en.md CHANGED
@@ -49,3 +49,17 @@ 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
+ ```ts
58
+ {
59
+ cad: {
60
+ colorMode: 'monochrome',
61
+ monochromeColor: '#000000',
62
+ showColorModeToggle: true,
63
+ },
64
+ }
65
+ ```
package/README.md CHANGED
@@ -49,3 +49,17 @@ 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
+ ```ts
58
+ {
59
+ cad: {
60
+ colorMode: 'monochrome',
61
+ monochromeColor: '#000000',
62
+ showColorModeToggle: true,
63
+ },
64
+ }
65
+ ```
package/dist/cad.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { CadViewer, inferEntityKind, } from '@flyfish-dev/cad-viewer';
2
2
  import { resolveFileViewerCadAssetUrls, resolveFileViewerRuntimeAssetBaseUrl, } from '@file-viewer/core/assets';
3
3
  import { createFileViewerViewStateChange, createFileViewerViewStateChangeEmitter, createFileViewerTranslator, createFileViewerZoomChangeEmitter, registerFileViewerViewStateProvider, registerFileViewerZoomProvider, resolveFileViewerLocale, unregisterFileViewerViewStateProvider, unregisterFileViewerZoomProvider, } from '@file-viewer/core';
4
+ import { applyCadViewerColorMode, normalizeFileViewerCadColorMode, resolveFileViewerCadMonochromeColor, resolveCadViewerSourceDocument, supportsCadViewerColorMode, } from './colorMode.js';
4
5
  const CAD_WORKER_TIMEOUT = 120000;
5
6
  const CAD_DEFAULT_FIT_PADDING = 0.92;
6
7
  const CAD_BOUNDS_EPSILON = 1e-9;
@@ -14,6 +15,9 @@ const cadStyle = `
14
15
  .cad-tools,.cad-meta{display:flex;align-items:center;gap:8px}
15
16
  .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
17
  .cad-tools button:hover{background:rgba(31,150,110,.14);color:#0f8f62}
18
+ .cad-tools button.cad-color-mode{min-width:52px;padding:0 10px;font-size:12px}
19
+ .cad-tools button.cad-color-mode[aria-pressed='true']{background:#0f172a;color:#fff}
20
+ .cad-tools button.cad-color-mode:disabled{cursor:not-allowed;opacity:.46}
17
21
  .cad-zoom,.cad-meta span{color:#64748b;font-size:12px;font-weight:800;letter-spacing:0}
18
22
  .cad-meta span{border-radius:999px;padding:5px 9px;background:rgba(15,23,42,.06)}
19
23
  .cad-body{display:grid;min-height:0;flex:1;grid-template-columns:minmax(176px,236px) minmax(0,1fr) minmax(142px,176px);background:#eef2f7}
@@ -648,6 +652,8 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
648
652
  const options = ((_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.cad) || {};
649
653
  const t = createFileViewerTranslator(context === null || context === void 0 ? void 0 : context.options);
650
654
  const locale = resolveFileViewerLocale(context === null || context === void 0 ? void 0 : context.options);
655
+ const monochromeColor = resolveFileViewerCadMonochromeColor(options.monochromeColor);
656
+ let colorMode = normalizeFileViewerCadColorMode(options.colorMode);
651
657
  let status = 'loading';
652
658
  let progressMessage = t('cad.state.loadingViewer');
653
659
  let errorMessage = '';
@@ -672,16 +678,18 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
672
678
  const zoomOutButton = createElement('button', undefined, '-');
673
679
  const zoomText = createElement('span', 'cad-zoom', '100%');
674
680
  const zoomInButton = createElement('button', undefined, '+');
681
+ const colorModeButton = createElement('button', 'cad-color-mode');
682
+ colorModeButton.hidden = options.showColorModeToggle === false;
675
683
  const meta = createElement('div', 'cad-meta');
676
684
  const typeMeta = createElement('span', undefined, normalizedType.toUpperCase());
677
685
  const backendMeta = createElement('span', undefined, 'AUTO');
678
- [fitButton, zoomOutButton, zoomInButton].forEach(button => {
686
+ [fitButton, zoomOutButton, zoomInButton, colorModeButton].forEach(button => {
679
687
  button.type = 'button';
680
688
  });
681
689
  fitButton.title = t('cad.toolbar.fit');
682
690
  zoomOutButton.title = t('cad.toolbar.zoomOut');
683
691
  zoomInButton.title = t('cad.toolbar.zoomIn');
684
- tools.append(fitButton, zoomOutButton, zoomText, zoomInButton);
692
+ tools.append(fitButton, zoomOutButton, zoomText, zoomInButton, colorModeButton);
685
693
  meta.append(typeMeta, backendMeta);
686
694
  toolbar.append(tools, meta);
687
695
  const body = createElement('div', 'cad-body without-layers');
@@ -749,6 +757,8 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
749
757
  status,
750
758
  view: viewState ? { ...viewState } : null,
751
759
  backend: renderStats === null || renderStats === void 0 ? void 0 : renderStats.backend,
760
+ colorMode,
761
+ monochromeColor: colorMode === 'monochrome' ? monochromeColor : undefined,
752
762
  layerCount: layers.length,
753
763
  visibleLayers: layers
754
764
  .filter(layer => layer.isVisible !== false && !layer.isFrozen)
@@ -885,12 +895,15 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
885
895
  : layer.name;
886
896
  button.setAttribute('aria-pressed', String(layerVisible));
887
897
  const color = createElement('span', 'cad-layer-color');
888
- if (typeof layer.color === 'string') {
898
+ if (colorMode === 'monochrome') {
899
+ color.style.background = monochromeColor;
900
+ }
901
+ else if (typeof layer.color === 'string') {
889
902
  color.style.background = layer.color;
890
903
  }
891
904
  button.append(color, createElement('span', undefined, layer.name));
892
905
  button.addEventListener('click', () => {
893
- const document = viewer === null || viewer === void 0 ? void 0 : viewer.getDocument();
906
+ const document = resolveCadViewerSourceDocument(viewer);
894
907
  if (!document) {
895
908
  return;
896
909
  }
@@ -917,6 +930,15 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
917
930
  const syncState = () => {
918
931
  zoomText.textContent = `${getZoomPercent()}%`;
919
932
  backendMeta.textContent = ((renderStats === null || renderStats === void 0 ? void 0 : renderStats.backend) || 'auto').toUpperCase();
933
+ const colorModeSupported = supportsCadViewerColorMode(viewer);
934
+ colorModeButton.disabled = status !== 'ready' || !colorModeSupported;
935
+ colorModeButton.setAttribute('aria-pressed', String(colorMode === 'monochrome'));
936
+ colorModeButton.textContent = t(colorMode === 'monochrome'
937
+ ? 'cad.toolbar.monochrome'
938
+ : 'cad.toolbar.colorSource');
939
+ colorModeButton.title = t(colorMode === 'monochrome'
940
+ ? 'cad.toolbar.colorSource'
941
+ : 'cad.toolbar.monochrome');
920
942
  state.hidden = status === 'ready';
921
943
  state.classList.toggle('error', status === 'error');
922
944
  if (status === 'loading') {
@@ -1054,6 +1076,17 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
1054
1076
  fitButton.addEventListener('click', () => fitToView());
1055
1077
  zoomInButton.addEventListener('click', zoomIn);
1056
1078
  zoomOutButton.addEventListener('click', zoomOut);
1079
+ colorModeButton.addEventListener('click', () => {
1080
+ const previousMode = colorMode;
1081
+ colorMode = colorMode === 'monochrome' ? 'source' : 'monochrome';
1082
+ if (!applyCadViewerColorMode(viewer, colorMode, monochromeColor)) {
1083
+ colorMode = previousMode;
1084
+ syncState();
1085
+ return;
1086
+ }
1087
+ syncUi();
1088
+ emitCadViewStateChange('cad-view-change', 'user');
1089
+ });
1057
1090
  const createViewer = () => {
1058
1091
  var _a, _b, _c, _d, _e, _f, _g;
1059
1092
  const { wasmPath, workerUrl, dwfWasmUrl } = resolveFileViewerCadAssetUrls(options, getCadDocumentBaseUrl(target));
@@ -1094,6 +1127,7 @@ export default async function renderCad(buffer, target, type = 'dxf', context) {
1094
1127
  dwfMaxOverviewStrokeCssPx: options.dwfMaxOverviewStrokeCssPx,
1095
1128
  dwfMinTextCssPx: options.dwfMinTextCssPx,
1096
1129
  dwfMinFilledAreaCssPx: options.dwfMinFilledAreaCssPx,
1130
+ ...{ colorMode, monochromeColor },
1097
1131
  autoFit: true,
1098
1132
  canvasOptions,
1099
1133
  onLoadProgress: updateProgress,
@@ -0,0 +1,11 @@
1
+ import type { FileViewerCadColorMode } from '@file-viewer/core';
2
+ export interface CadViewerColorModeAdapter {
3
+ setColorMode?: (mode: FileViewerCadColorMode, monochromeColor?: string) => void;
4
+ getColorMode?: () => FileViewerCadColorMode;
5
+ getMonochromeColor?: () => string | undefined;
6
+ }
7
+ export declare function normalizeFileViewerCadColorMode(value: unknown): FileViewerCadColorMode;
8
+ export declare function resolveFileViewerCadMonochromeColor(value: unknown, fallback?: string): string;
9
+ export declare function supportsCadViewerColorMode(value: unknown): value is CadViewerColorModeAdapter;
10
+ export declare function resolveCadViewerSourceDocument(viewer: unknown): unknown;
11
+ export declare function applyCadViewerColorMode(viewer: unknown, mode: FileViewerCadColorMode, monochromeColor: string): boolean;
@@ -0,0 +1,23 @@
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 supportsCadViewerColorMode(value) {
10
+ return Boolean(value && typeof value.setColorMode === 'function');
11
+ }
12
+ export function resolveCadViewerSourceDocument(viewer) {
13
+ var _a, _b, _c;
14
+ const candidate = viewer;
15
+ 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);
16
+ }
17
+ export function applyCadViewerColorMode(viewer, mode, monochromeColor) {
18
+ var _a;
19
+ if (!supportsCadViewerColorMode(viewer))
20
+ return false;
21
+ (_a = viewer.setColorMode) === null || _a === void 0 ? void 0 : _a.call(viewer, mode, monochromeColor);
22
+ return true;
23
+ }
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.1",
3
+ "version": "3.0.2",
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.1",
60
- "@flyfish-dev/cad-viewer": "0.8.0"
59
+ "@file-viewer/core": "3.0.2",
60
+ "@flyfish-dev/cad-viewer": "0.8.1"
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
  }