HTML export for @mlightcad/cad-simple-viewer: snapshot format, offline viewer runtime, and optional plugin integration.
| Command | Description |
|---|---|
-chtml |
Export via command-line prompts (no dialog; AutoCAD-style - prefix) |
chtml |
Same as -chtml when no UI command is registered (e.g. cad-simple-viewer only). In cad-viewer, chtml opens an export options dialog instead |
The plugin path is designed for lazy loading so the export bundle is only downloaded when a user runs -chtml or confirms export from the chtml dialog (or runs chtml in a host that has no dialog command). Low-level APIs (packHtml, snapshot types, scene collectors) are also exported for custom pipelines and the headless CLI @mlightcad/cad-simple-viewer-cli.
- Display-only snapshot — layers, layouts, line/mesh batches, extents, and drawing units (no editable DXF/DWG payload)
- Self-contained HTML — gzip/base64 snapshot + inline viewer runtime; opens offline in any modern browser
- Multi-file ACEX package — generic
viewer.html+ fixeddrawing.acex.json+ per-chunk*.acex.gz; export downloads a zip (unzip before hosting for progressive load). The shell does not hard-code a drawing-specific data path: it probes siblingdrawing.acex.json, supports?manifest=/?acex=URLs, and can open a local package folder or a pasted manifest URL when the default file is missing - Offline viewer — select / pan / zoom (extents, window, original view), layer panel, layout switching, measurement, Design Review markup annotations, object snap (OSNAP). Select, pan, and zoom tools exit any active measurement or review drawing tool.
- i18n — embedded English / Chinese / Czech / Turkish UI; initial language follows the browser (
zh*→ Chinese,cs*→ Czech,tr*→ Turkish, otherwise English); the toolbar language button opens a strip to pick a locale, and the choice persists inlocalStorage - Plugin API — implements
AcApPlugin; register once withregisterLazyHtmlPlugin - Composable API — build snapshots from your own pipeline or call
packHtml/buildAcExPackagewith a pre-built snapshot
pnpm add @mlightcad/cad-html-pluginPeer dependencies:
@mlightcad/cad-simple-viewer(for-chtml/ scene snapshot builder)@mlightcad/data-model@mlightcad/three-rendererthree
Runtime dependency (bundled with this package):
fflate
The package produces two artifacts:
| Output | Description |
|---|---|
dist/index.js |
Library entry (snapshot types, codec, packHtml, createHtmlPlugin, …) |
dist/register.js |
Lightweight lazy-registration entry (safe for static import in app bundles) |
dist/viewer-runtime.iife.js |
Offline viewer bootstrap (loaded/inlined into exported HTML) |
pnpm --filter @mlightcad/cad-html-plugin buildCopy or serve viewer-runtime.iife.js from your app assets when using the browser export path (see Integration below).
Register the plugin with the document manager's plugin manager. Import from the /register subpath so only the registration stub enters your initial bundle; the main plugin chunk loads on first use of -chtml or chtml (see command table above):
import { AcApDocManager } from '@mlightcad/cad-simple-viewer'
import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register'
AcApDocManager.createInstance({
container: document.getElementById('cad-container')!
})
// viewerRuntimeUrl is HTML-export only — not required to open DXF/DWG
registerLazyHtmlPlugin(AcApDocManager.instance.pluginManager, {
viewerRuntimeUrl: './viewer-runtime.iife.js'
})Do not import registerLazyHtmlPlugin from the package root (@mlightcad/cad-html-plugin) in application code — that resolves to the full library build and defeats lazy loading.
After registration (command-line export):
await AcApDocManager.instance.editor.executeCommand('-chtml')
// or
AcApDocManager.instance.sendStringToExecute('-chtml')In cad-viewer, use chtml to open the export options dialog; -chtml remains available on the command line for prompt-based export.
cad-viewer registers this plugin automatically via registerLazyPlugins() in its app bootstrap and registers the chtml dialog command separately.
import { AcApHtmlConvertor } from '@mlightcad/cad-html-plugin'
// Self-contained .html (default)
await new AcApHtmlConvertor().convert('my-drawing.dwg')
// Multi-file package as one .zip download (unzip before hosting)
await new AcApHtmlConvertor().convert('my-drawing.dwg', {
exportFormat: 'multi'
})-chtml prompts for export format (Single / Multi). In cad-viewer, the chtml dialog offers the same choice.
See docs/acex-package-format.md for the on-disk format, and docs/acex-web-hosting-guide.md for static hosting / CDN deployment (includes a live progressive demo).
import {
ACEX_DEFAULT_MANIFEST_FILE,
buildAcExPackage,
zipAcExPackageFiles,
packHtmlPackage
} from '@mlightcad/cad-html-plugin'
// Always writes viewer.html + drawing.acex.json + chunks/
// (baseName is retained for API compatibility; it does not rename the manifest).
const pkg = buildAcExPackage(snapshot, {
viewerRuntime: runtime,
baseName: 'my-drawing'
})
// pkg.manifestFileName === ACEX_DEFAULT_MANIFEST_FILE ('drawing.acex.json')
const zipBytes = zipAcExPackageFiles(pkg)
// Or serve pkg.files as a static directory after unzipHow generic viewer.html finds data (in order):
- Query string —
?manifest=<url>or?acex=<url>(relative or absolutehttp(s)) - Sibling file —
./drawing.acex.jsonnext to the HTML - If missing — UI to pick a local package folder (must contain
drawing.acex.json) or paste a manifest URL
Unsupported package / snapshot versions surface as an on-page error.
import {
ACEX_SNAPSHOT_VERSION,
type AcExSnapshotV1,
buildViewerMetadata,
collectBatchesFromObject3D,
buildOsnapCatalog,
packHtml,
HTML_VIEWER_RUNTIME_FILE
} from '@mlightcad/cad-html-plugin'
const snapshot: AcExSnapshotV1 = /* built via AcApHtmlSnapshotBuilder or manually */
const runtime = await fetch(`./${HTML_VIEWER_RUNTIME_FILE}`).then(r => r.text())
const html = packHtml(snapshot, {
title: 'My Drawing',
viewerRuntime: runtime
})import { AcApHtmlSnapshotBuilder } from '@mlightcad/cad-html-plugin'
const snapshot = await new AcApHtmlSnapshotBuilder().buildAsync(
view.cadScene,
document.database,
{ title: 'Drawing', background: view.backgroundColor }
)For DXF/DWG → HTML without a browser UI, use @mlightcad/cad-simple-viewer-cli with examples/export-html.scr (single-file) or examples/export-html-multi.scr (multi-file zip), or your own .scr that runs -chtml. It runs the same snapshot + pack pipeline inside Playwright.
When embedding HTML export in a web app:
- Build
@mlightcad/cad-html-pluginand exposeviewer-runtime.iife.jsat a URL your app canfetch(e.g. Vitepublic/copy — seecad-viewer-example/cad-simple-viewer-examplevite configs). Skip this step if you do not use HTML export — opening DXF/DWG does not need this file or this package. - Register via
@mlightcad/cad-html-plugin/register(or load the plugin eagerly). - Pass
viewerRuntimeUrltoregisterLazyHtmlPlugin/createHtmlPlugin/AcApHtmlConvertor(default./viewer-runtime.iife.js). Do not put this onAcApDocManager.createInstance(). - Ensure fonts used by the drawing are reachable during export if you rely on web-font substitution.
The generated HTML itself needs no backend; only the export step may fetch the runtime bundle and fonts.
Subpath exports:
import { registerLazyHtmlPlugin } from '@mlightcad/cad-html-plugin/register'
import '@mlightcad/cad-html-plugin/viewer-runtime' // dist/viewer-runtime.iife.js| Export | Role |
|---|---|
createHtmlPlugin |
Async factory used by the lazy loader |
HTML_PLUGIN_NAME, HTML_PLUGIN_TRIGGERS |
Plugin id and command triggers |
@mlightcad/cad-html-plugin/register |
registerLazyHtmlPlugin and registration constants |
AcApExportHtmlCmd, AcApHtmlConvertor |
-chtml command and full export workflow |
AcApHtmlSnapshotBuilder |
Live Three.js scene → AcExSnapshotV1 |
packHtml, AcExPackHtmlOptions |
Assemble self-contained HTML from snapshot + runtime |
packHtmlPackage, buildAcExPackage, zipAcExPackageFiles |
Multi-file package shell, builder, and export zip |
ACEX_DEFAULT_MANIFEST_FILE, ACEX_DEFAULT_MANIFEST_HREF, package bootstrap helpers |
Canonical drawing.acex.json name and generic viewer resolve / probe / directory-fetch helpers |
HTML_VIEWER_RUNTIME_FILE |
Default runtime filename (viewer-runtime.iife.js) |
AcExSnapshot, ACEX_SNAPSHOT_VERSION, batch/layer types |
Snapshot schema |
| Package format doc | docs/acex-package-format.md |
| Web hosting guide | docs/acex-web-hosting-guide.md |
encodeSnapshot, decodeSnapshot |
Gzip/base64 codec for embedded payloads |
collectBatchesFromObject3D |
THREE.js scene → line/mesh batches |
buildViewerMetadata |
Database → viewer meta (units, extents, background, …) |
buildOsnapCatalog, OSNAP primitive helpers |
Analytic snap geometry for the offline viewer |
AcExHtmlI18n, detectAcExHtmlLocale, detectBrowserAcExHtmlLocale, resolveAcExHtmlLocale |
Viewer UI strings and locale detection |
| Path | Role |
|---|---|
src/register.ts |
Lazy plugin registration (/register entry) and createHtmlPlugin |
src/AcApHtmlPlugin.ts |
Plugin lifecycle (onLoad / onUnload) |
src/AcApExportHtmlCmd.ts |
-chtml command (command-line prompts) |
src/AcApHtmlConvertor.ts |
Export orchestration (snapshot, runtime fetch, download) |
src/AcApHtmlSnapshotBuilder.ts |
Three.js scene → snapshot builder |
src/AcExSnapshotTypes.ts |
Snapshot schema (v1) |
src/AcExSnapshotCodec.ts |
Encode/decode embedded snapshot script tag |
src/AcExSceneBatchCollector.ts |
THREE.js traversal → export batches |
src/AcExHtmlPackager.ts |
packHtml / packHtmlPackage — shell + snapshot or package marker + runtime |
src/AcExPackageBuilder.ts |
Multi-file package builder (viewer.html + drawing.acex.json + chunks) |
src/AcExHtmlPackageBootstrap.ts |
Generic package resolve (query / sibling / probe / local directory fetch) |
src/AcExHtmlPackageSourceGate.ts |
Folder / URL picker when sibling drawing.acex.json is missing |
src/AcExHtmlViewerRuntime.ts |
Offline viewer (built as IIFE) |
src/AcExHtmlShell.ts |
Static HTML/CSS shell markup |
src/AcExOsnap*.ts |
Object snap index and primitives |
src/AcExMeasurement.ts |
Distance/area measurement in the offline viewer |
src/AcExMeasurementSidecar.ts |
Measurement sidecar JSON import/export (*.measurement.json, compatible with cad-simple-viewer) |
src/AcExMarkup.ts |
Design Review markup tools (cloud, callout, text, rect, circle, arrow, stamp) with sidecar JSON import/export |
src/AcExHtmlI18n.ts |
English / Chinese / Czech / Turkish UI messages |
This package combines the export format / offline viewer runtime with viewer integration (plugin, snapshot builder, -chtml command). @mlightcad/cad-simple-viewer stays free of HTML export code; heavy export logic can be lazy-loaded. cad-viewer adds a chtml dialog command on top. @mlightcad/cad-simple-viewer-cli provides a Node/Playwright entry point for batch conversion via .scr scripts.
MIT