如何在Forge Viewer模型浏览器隐藏对象但保持场景可见?
解决Forge Viewer模型浏览器隐藏对象但保留场景可见的问题
针对你使用@contecht/react-adsk-forge-viewer React TypeScript封装库时遇到的需求,以下是可行的解决方案,避开你之前踩过的DOM操作坑:
方案一:利用Viewer原生过滤API(推荐)
Forge Viewer的模型结构面板支持通过自定义过滤器控制节点显示,无需直接操作DOM,适配动态生成的折叠节点:
获取Viewer实例
在React组件中,通过封装库的回调或ref拿到Viewer核心实例:import { ForgeViewer } from '@contecht/react-adsk-forge-viewer'; import { useRef } from 'react'; function MyViewerComponent() { const viewerRef = useRef<any>(null); const onViewerReady = (viewer: Autodesk.Viewing.GuiViewer3D) => { viewerRef.current = viewer; setupModelTreeFilter(viewer); }; return ( <ForgeViewer onViewerReady={onViewerReady} {/* 填入你的模型配置、token等参数 */} /> ); }注册模型树过滤器
通过viewer.modelStructurePanel.setFilter()方法添加自定义过滤逻辑,指定需要隐藏的节点(按dbId或节点名称):function setupModelTreeFilter(viewer: Autodesk.Viewing.GuiViewer3D) { // 等待模型对象树构建完成 viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, () => { const modelTreePanel = viewer.getPanel('modelStructurePanel'); if (modelTreePanel) { // 过滤规则:返回true显示节点,false隐藏节点 modelTreePanel.setFilter((node: Autodesk.Viewing.ModelNode) => { // 示例:隐藏指定dbId的节点,可替换为名称匹配逻辑 const targetDbIds = [123, 456]; // 替换成你的目标对象dbId return !targetDbIds.includes(node.dbId); }); } }); }这个方法会自动处理折叠节点的显示逻辑,无需手动展开DOM,且模型浏览器未打开时也能提前注册规则。
方案二:监听模型面板UI生成事件(适配动态DOM)
如果方案一无法满足需求,可通过监听面板激活事件,动态处理DOM元素,同时强制展开目标节点的父级:
function setupDomBasedHiding(viewer: Autodesk.Viewing.GuiViewer3D) { const targetDbId = 123; // 替换为你的目标对象dbId viewer.addEventListener(Autodesk.Viewing.PANEL_CREATED_EVENT, (event) => { if (event.panelId === 'modelStructurePanel') { const modelTreePanel = viewer.getPanel('modelStructurePanel'); // 监听面板打开事件 modelTreePanel.addEventListener(Autodesk.Viewing.PANEL_ACTIVATED_EVENT, () => { const tree = modelTreePanel.tree; if (tree) { // 递归展开目标节点的所有父级,确保DOM元素生成 expandParentNodes(tree, targetDbId); // 等待DOM更新后隐藏节点 setTimeout(() => { const nodeElement = document.querySelector(`[data-node-id="${targetDbId}"]`); if (nodeElement) { (nodeElement as HTMLElement).style.display = 'none'; } }, 100); } }); } }); } // 递归展开父节点的工具函数 function expandParentNodes(tree: any, dbId: number) { const parentId = tree.getParentId(dbId); if (parentId && parentId !== tree.rootId) { tree.expand(parentId); expandParentNodes(tree, parentId); } }
注意事项
- 避免直接操作
viewer.modelstructure下的私有属性,这类属性在新版本Viewer或封装库中可能被隐藏或修改 - 确保在Viewer实例完全初始化后(通过
onViewerReady或类似回调)再执行逻辑 - 方案一的过滤逻辑会全局影响模型树显示,若需临时切换显示状态,可通过重置过滤器实现
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

