Viewer 查看模式
文档:
vjcad/doc/ui/viewer-mode.md示例:
vjcad/example/ui/09viewermode.js— viewMode 配置vjcad/example/basic/05mapoverlay.js— 多图层只读浏览
viewMode: "viewer" 是 vjcad 提供的"轻量查看模式",用于嵌入到第三方系统、移动端、或纯只读场景。
1. 一键启用
const cadView = new MainView({
appname: '唯杰CAD',
version: 'v1.0.0',
serviceUrl: env.serviceUrl,
accessToken: env.accessToken,
viewMode: 'viewer', // 关键
showUcsIcon: false,
showAxis: false,
});
initCadContainer('cad-container', cadView);
await cadView.onLoad();
启用后默认行为:
| UI | 默认 |
|---|---|
| 菜单栏 | 隐藏 |
| Ribbon | 隐藏 |
| 工具栏 | 隐藏 |
| 状态栏 | 隐藏 |
| 侧边栏 | 隐藏 |
| 命令行 | 隐藏 |
| 右键菜单 | 完全禁用(enableContextMenu: true 才开启,开启后是与编辑器相同的完整默认菜单) |
| 键盘命令 | 关闭 |
| 选择实体 | 允许 |
| 拾取夹点 | 关闭 |
viewMode 只支持两个值:
"full"(默认) — 完整编辑器(不是'editor')"viewer"— 只读查看器
2. 细粒度 UI 控制
viewMode 会一次性关掉一组 UI;如果只想关其中几项,保留 viewMode: 'full' 然后用 MainViewConfig 的真实开关:
new MainView({
showMenuBar: false, // 隐藏菜单栏
showToolBar: false, // 隐藏工具栏
showBottomBar: false, // 隐藏底栏
showDocBar: false, // 隐藏文档标签栏
showCoordsBar: false, // 隐藏坐标显示
showCommandLine: false, // 隐藏命令行
sidebarStyle: 'none', // 隐藏侧边栏('both'|'left'|'right'|'none')
showUcsIcon: false, // UCS 图标
showAxis: false, // 坐标轴
enableContextMenu: false, // 右键菜单
showGrips: false, // 夹点
showCrosshair: false, // 十字光标
disablePointerEvents: true // 画布不吃指针事件
});
// ⚠️ 不存在的键:showRibbon / showFuncButtons / showFps / enableHotkeys /
// enableSelection(MainViewConfig 上无此项) / autoZoomExtents —— 写了静默无效。
// Ribbon 定制走 ribbon: RibbonCustomConfig(removeTabs/modifyTabs),没有总开关。
或反过来:用 viewMode: 'viewer' 后再 打开 部分组件——但 viewer 分支在隐藏完 UI 后直接 return,只认这三项:
new MainView({
viewMode: 'viewer',
sidebarStyle: 'right', // 显式给值才保留侧边栏(不给则强制 'none')
enableContextMenu: true, // 必须严格 === true 才开启右键菜单
showGrips: true, // 必须严格 === true 才显示夹点
});
// ⚠️ showCoordsBar / showMenuBar / showToolBar / showCommandLine / showBottomBar 等在 viewer 下全部无效
// (菜单/工具/文档/坐标/命令行/底栏一律隐藏);要保留坐标条就别用 viewer,改用 viewMode:'full' + 细粒度开关
3. 交互细节
new MainView({
viewMode: 'viewer',
enableContextMenu: true, // 是否允许右键菜单(viewer 默认关)
showGrips: false, // viewer 下默认关闭夹点
disablePointerEvents: true // 完全不响应画布指针
});
// 选择/快捷键/自动缩放没有独立开关:viewer 模式内部用只读交互集;
// "选中但不给夹点"用 showGrips:false;加载后缩放自己调 Engine.zoomExtents()
4. 加载本地 / 远程图
viewer 模式 依然走完整 vjcad 引擎,加载图纸的 API 与 editor 一致:
// 远程图:Engine.service.openMap 只是后端 openmap 接口调用,不会把图加载进编辑器
const dm = new DrawingManagerService();
const r = await dm.openDrawing({ type: 'imports', mapid: 'demo.dwg', version: 'v1', branch: 'main' });
if (r.success) {
await Engine.view.openDbDoc(new File([r.webcadJson], 'demo.webcad', { type: 'application/json' }), r.webcadData);
}
// 或页面 URL 带 ?vcad_mapid=demo.dwg&vcad_version=v1,MainView 初始化时自动打开
// 本地 dwg / dxf 文件
const file = e.target.files[0];
await cadView.openDocumentByFile(file); // MainView.openDocumentByFile(file, readOnly?)
// 直接给 vcadData / vcadJson
// 或用 drawingManager.openDrawing + Engine.view.openDbDoc(见 file/server.md)
5. 监听用户操作
const events = CadEventManager.getInstance();
events.on(CadEvents.SelectionChanged, args => {
const ents = args.currentSelection ?? []; // 字段是 currentSelection/selections/added/removed,无 entities
if (ents.length === 1) {
const e = ents[0];
showInfo(`类型: ${e.type}, 图层: ${e.layer}, 颜色: ${e.color}`);
}
});
events.on(CadEvents.PointerDown, args => { // 无 LeftClick;PointerEventArgs: canvasX/canvasY/worldX/worldY/button
console.log('点击:', args.canvasX, args.canvasY);
});
6. 应用场景
6.1 嵌入到业务系统
<iframe src="https://yoursite.com/viewer?mapid=demo.dwg" width="100%" height="600"></iframe>
主页面挂 vjcad:URL 用 vcad_mapid / vcad_version(另有 vcad_branch / vcad_readonly 等)时 MainView 会自动打开;自定义参数名则自己解析后走上面的 openDrawing + openDbDoc。
6.2 多图层只读对比
打开主图后再叠加只读图层(不允许编辑):
// 主图照常打开
const r1 = await drawingManager.openDrawing({ type:'imports', mapid:'base.dwg', version:'v1' });
await Engine.view.openDbDoc(new File([r1.webcadJson], 'base.dwg'), r1.webcadData);
// 叠加层用 WMS 瓦片只读铺底(vjcad 无"多文档叠加"API)
Engine.pcanvas.enableWmsTileLayer(drawingManager.getService(), {
mapid: 'plan.dwg', version: 'v1', transparent: true
});
详见 tile/webmap-overlay 相关文档。
6.3 移动端简化
new MainView({
viewMode: 'viewer',
sidebarStyle: 'none',
showBottomBar: false, // 移动端不需要底栏
enableContextMenu: false // 移动端不弹右键
});
7. 切换 / 退出
viewMode 是构造时配置,不能在运行时切换为 editor。如需切换,重建 MainView:
await cadView.destroy();
const newView = new MainView({ viewMode: 'full', /* ... */ }); // viewMode 只有 'full' | 'viewer'
initCadContainer('cad-container', newView);
await newView.onLoad();
红旗
viewMode: 'viewer'默认关闭命令交互;用户按L不会启动直线命令。如果你额外注册了浮动按钮直接调用Engine.editor.executerWithOp是可以的,但 会立刻提示"只读"(如果用户登录权限是只读)- viewer 不等于"后端只读";要彻底只读还要后端
auth_callback拒绝写操作 showGrips: false可以"选中但不能拖夹点改",常用于"测量 / 标注"(选择本身在 viewer 下没有独立开关)- viewer 下右键菜单默认整个禁用(连
ContextMenuOpening都不触发);enableContextMenu: true后出现的是完整默认菜单(剪切/复制/粘贴/绘图次序等编辑项),只想要视图操作就在ContextMenuOpening里args.useDefaultItems = false再自己 prepend - 视图加载失败(认证失败 / mapid 不存在)不会调用
onAuthError(vjcad@1.0.16 只保存该回调、从不触发);靠try/catch和检查接口返回的status/errorCode自行处理 - viewer 模式下
Engine.regen()/Engine.zoomExtents()仍可用;不要误以为 viewer = "engine 也只读"
参考(官方文档 MCP)
- 文档:
vjcad/doc/ui/viewer-mode.md - 示例:
vjcad/example/ui/09viewermode.js— viewMode 配置vjcad/example/basic/05mapoverlay.js— 多图层只读浏览