APS Viewer v7工具栏按钮随窗口变化消失及缩放/剖面工具失效问题
问题描述
我开发了一个使用APS Viewer v7的Next.js应用,遇到以下问题:
- 窗口处于特定显示尺寸时,工具栏多个按钮消失,放大窗口后又重新出现
- 尝试移除原有按钮再重新添加后,缩放工具失效,剖面工具的折叠按钮完全丢失
- 希望为自定义按钮添加扩展功能,但文档未明确说明实现方法
相关代码如下:
newViewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => { newViewer.fitToView(); const toolbar = newViewer.toolbar; // define then list the contents of the navTools group const navTools = toolbar.getControl("navTools"); console.log("navTools: ", navTools); let firstToolId = navTools.getControlId(0); console.log("1stToolId: ", firstToolId); let secondToolId = navTools.getControlId(1); console.log("2ndToolId: ", secondToolId); let thirdToolId = navTools.getControlId(2); console.log("3rdToolId: ", thirdToolId); let fourthToolId = navTools.getControlId(3); console.log("4thToolId: ", fourthToolId); let fifthToolId = navTools.getControlId(4); console.log("5thToolId: ", fifthToolId); // remove the tools so we can repopulate them navTools.removeControl("toolbar-orbitTools"); navTools.removeControl("toolbar-panTool"); navTools.removeControl("toolbar-zoomTool"); navTools.removeControl("toolbar-bimWalkTool"); navTools.removeControl("toolbar-cameraSubmenuTool"); // define then list the contents of the modelTools group const modelTools = toolbar.getControl("modelTools"); console.log("modelTools: ", modelTools); let firstModelToolId = modelTools.getControlId(0); console.log("1stToolId: ", firstModelToolId); let secondModelToolId = modelTools.getControlId(1); console.log("2ndToolId: ", secondModelToolId); let thirdModelToolId = modelTools.getControlId(2); console.log("3rdToolId: ", thirdModelToolId); let fourthModelToolId = modelTools.getControlId(3); console.log("4thToolId: ", fourthModelToolId); let fifthModelToolId = modelTools.getControlId(4); console.log("5thToolId: ", fifthModelToolId); //remove the tools so we can repopulate them modelTools.removeControl("toolbar-explodeTool"); // modelTools.removeControl("toolbar-sectionTool"); let sectionTool = modelTools.getControl("toolbar-sectionTool"); console.log("sectionTool: ", sectionTool); let orbitButton = new Autodesk.Viewing.UI.Button("orbitToolButton"); orbitButton.onClick = function () { newViewer.setActiveNavigationTool("orbit"); }; orbitButton.setToolTip("Orbit"); orbitButton.setIcon("adsk-icon-orbit-constrained"); let controlGroup = toolbar.getControl("navTools"); // You can use an existing group like navTools controlGroup.addControl(orbitButton); let panButton = new Autodesk.Viewing.UI.Button("panToolButton"); panButton.onClick = function () { newViewer.setActiveNavigationTool("pan"); }; panButton.setToolTip("Pan"); panButton.setIcon("adsk-icon-pan"); controlGroup.addControl(panButton); // zoom dosent work let zoomButton = new Autodesk.Viewing.UI.Button("zoomToolButton"); zoomButton.onClick = function () { newViewer.setActiveNavigationTool("zoom"); }; zoomButton.setToolTip("Zoom"); zoomButton.setIcon("adsk-icon-zoom"); controlGroup.addControl(zoomButton); let fitToViewButton = new Autodesk.Viewing.UI.Button( "fitToViewToolButton" ); fitToViewButton.onClick = function () { newViewer.fitToView(); }; fitToViewButton.setToolTip("fitToView"); fitToViewButton.setIcon("adsk-icon-fit-to-view"); controlGroup.addControl(fitToViewButton); let firstPersonButton = new Autodesk.Viewing.UI.Button( "firstPersonToolButton" ); firstPersonButton.onClick = function () { newViewer.setActiveNavigationTool("bimwalk"); }; firstPersonButton.setToolTip("First Person"); firstPersonButton.setIcon("adsk-icon-first-person"); controlGroup.addControl(firstPersonButton); //model tool group let modelGroup = toolbar.getControl("modelTools"); // dosent work let sectionAnalysisButton = new Autodesk.Viewing.UI.Button( "sectionAnalysisToolButton" ); sectionAnalysisButton.onClick = function () { newViewer.setActiveNavigationTool("section"); }; sectionAnalysisButton.setToolTip("Section Analysis"); sectionAnalysisButton.setIcon("adsk-icon-section-analysis"); modelGroup.addControl(sectionAnalysisButton); });
问题分析与解决
1. 窗口尺寸变化导致按钮消失的根源
APS Viewer原生工具栏自带响应式布局逻辑,当窗口宽度不足时,会自动将部分按钮折叠到右侧的溢出下拉菜单中。你手动移除再重新添加按钮的操作,破坏了原生的响应式机制,反而引发更多问题。正确做法是保留原生工具栏控件,不要手动替换。
2. 缩放工具失效的原因
原生缩放工具包含普通缩放和框选缩放两种模式,原生按钮会自动处理模式切换逻辑。而你自定义的缩放按钮仅调用newViewer.setActiveNavigationTool("zoom"),只激活了基础缩放模式,缺失了模式切换功能。
如果必须自定义缩放按钮,需补充模式切换逻辑:
let zoomButton = new Autodesk.Viewing.UI.Button("zoomToolButton"); zoomButton.onClick = function () { const currentTool = newViewer.getActiveNavigationTool(); if (currentTool === "zoom") { newViewer.setActiveNavigationTool("boxzoom"); // 切换框选缩放 } else if (currentTool === "boxzoom") { newViewer.setActiveNavigationTool("zoom"); // 切回普通缩放 } else { newViewer.setActiveNavigationTool("zoom"); } }; zoomButton.setToolTip("Zoom (点击切换框选模式)"); zoomButton.setIcon("adsk-icon-zoom");
3. 剖面工具折叠按钮丢失的问题
原生剖面工具是一个带子菜单的ControlGroup控件,包含剖面创建、编辑等子按钮。你直接替换成普通按钮后,丢失了原有的折叠/展开逻辑。正确做法是保留原生的toolbar-sectionTool控件,如需修改剖面工具行为,可通过监听Autodesk.Viewing.SECTION_CHANGED_EVENT事件扩展功能,而非替换整个控件。
4. 自定义按钮添加扩展功能的实现
APS Viewer官方推荐用Extension机制封装自定义功能,步骤如下:
步骤1:创建扩展类
class CustomExtension extends Autodesk.Viewing.Extension { constructor(viewer, options) { super(viewer, options); this.button = null; } load() { // 创建自定义按钮 this.button = new Autodesk.Viewing.UI.Button("custom-extension-btn"); this.button.setIcon("adsk-icon-custom"); this.button.setToolTip("我的自定义功能"); this.button.onClick = () => { // 这里编写扩展逻辑 alert("自定义功能触发!"); // 示例:隔离指定ID的模型元素 this.viewer.isolateById(123); }; // 添加按钮到工具栏自定义分组 const toolbar = this.viewer.toolbar; let customGroup = toolbar.getControl("custom-tool-group"); if (!customGroup) { customGroup = new Autodesk.Viewing.UI.ControlGroup("custom-tool-group"); toolbar.addControl(customGroup); } customGroup.addControl(this.button); return true; } unload() { // 卸载扩展时清理按钮 const toolbar = this.viewer.toolbar; const customGroup = toolbar.getControl("custom-tool-group"); if (customGroup) { customGroup.removeControl(this.button); if (customGroup.getNumberOfControls() === 0) { toolbar.removeControl(customGroup); } } this.button = null; return true; } } // 注册扩展 Autodesk.Viewing.theExtensionManager.registerExtension('CustomExtension', CustomExtension);
步骤2:加载扩展
在Viewer初始化完成后调用:
viewer.loadExtension('CustomExtension');
总结优化方案
- 放弃手动替换原生工具栏按钮的操作,保留Viewer原生响应式布局,解决窗口尺寸变化导致按钮消失的问题
- 如需修改原生工具行为,通过监听事件或扩展原有工具实现,而非完全替换
- 使用官方Extension机制封装自定义按钮功能,便于功能管理和复用
内容的提问来源于stack exchange,提问作者Duncan Findlay
相关产品推荐
相关产品推荐

