如何在Forge Viewer中修改模型属性面板并过滤隐藏指定属性?
嘿,我来帮你搞定Forge Viewer里属性面板的定制和属性过滤问题——这在实际项目中太常见了,毕竟没人想让用户看到一堆无关的内部属性对吧?下面我分步骤给你讲清楚怎么操作:
调整属性面板与过滤属性的实用方法
1. 先搞懂默认属性面板的底层逻辑
Forge Viewer的默认属性面板是由Autodesk.Viewing.Extensions.ViewerPropertyPanel这个扩展提供的。要定制它,有两种主流思路:要么扩展/修改默认面板(省心,适合简单过滤需求),要么完全自定义一个新面板(灵活性拉满,但代码量更大)。咱们先从最常用的第一种开始讲。
2. 过滤属性:基于默认面板的两种实现方式
方法一:监听propertyPanel:update事件拦截属性
这种方式最直接,就是在属性面板准备渲染前,拦截并过滤掉不需要的属性项。代码示例如下:
// 等Viewer初始化完成后再操作 viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, () => { // 获取默认属性面板的扩展实例 const propertyPanelExt = viewer.getExtension('Autodesk.PropertiesManager'); if (!propertyPanelExt) return; const propertyPanel = propertyPanelExt.panel; // 监听面板的更新事件 propertyPanel.addEventListener('propertyPanel:update', (event) => { // event.properties就是即将显示的属性数组,在这里过滤 event.properties = event.properties.filter(prop => { // 这里写你的过滤规则:比如排除名称带"Internal"的属性,或者特定属性名 return !prop.displayName.includes('Internal') && prop.displayName !== 'Object ID'; }); }); });
方法二:重写面板的setProperties方法
如果需要更复杂的逻辑(比如根据选中元素的类型动态调整过滤规则),可以直接重写面板的setProperties方法,从根源上控制要显示的属性:
viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, () => { const propertyPanelExt = viewer.getExtension('Autodesk.PropertiesManager'); if (!propertyPanelExt) return; // 先保存原始的setProperties方法,避免覆盖后丢失功能 const originalSetProperties = propertyPanelExt.panel.setProperties; // 重写方法 propertyPanelExt.panel.setProperties = function(properties, options) { // 自定义过滤逻辑:比如只保留类别不是"Internal"且名称不是"HiddenProp"的属性 const filteredProps = properties.filter(prop => { return prop.category !== 'Internal' && prop.displayName !== 'HiddenProp'; }); // 调用原始方法渲染过滤后的属性 originalSetProperties.call(this, filteredProps, options); }; });
3. 调整属性面板的位置、大小等样式
如果还要调整面板的位置或尺寸,直接操作DOM或者调用面板内置方法就行:
// 获取属性面板的DOM元素 const panelDom = propertyPanel.container; // 调整位置:比如距离顶部100px,固定在右侧 panelDom.style.top = '100px'; // 调整宽度 panelDom.style.width = '400px'; // 也可以用面板内置方法控制显示/隐藏或位置 propertyPanel.setVisible(true); // 显示面板 propertyPanel.setPosition('right'); // 固定在右侧(可选值:left/right)
4. 进阶:完全自定义属性面板
如果默认面板的定制满足不了你的需求(比如要加自定义按钮、特殊样式),可以自己写一个扩展来实现。核心思路是监听Viewer的选择事件,获取选中元素的属性,然后自己渲染过滤后的内容。示例代码片段:
// 自定义属性面板扩展 class CustomPropertyPanel extends Autodesk.Viewing.Extension { constructor(viewer, options) { super(viewer, options); this.panelDom = null; } load() { // 创建自定义面板的DOM结构 this.panelDom = document.createElement('div'); this.panelDom.style.cssText = ` position:absolute; right:20px; top:100px; width:350px; background:white; padding:15px; border:1px solid #ccc; border-radius:4px; z-index:1000; `; this.viewer.container.appendChild(this.panelDom); // 监听元素选择变化事件 this.viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, (event) => { if (event.dbIdArray.length === 0) { this.panelDom.innerHTML = ''; return; } const selectedDbId = event.dbIdArray[0]; // 获取选中元素的属性 this.viewer.getProperties(selectedDbId, (props) => { // 过滤属性 const filteredProps = props.properties.filter(p => !p.displayName.includes('Internal')); // 渲染到面板 let htmlContent = '<h3>元素属性</h3><ul style="list-style:none; padding:0;">'; filteredProps.forEach(prop => { htmlContent += ` <li style="padding:8px 0; border-bottom:1px solid #eee;"> <strong style="display:inline-block; width:120px;">${prop.displayName}:</strong> <span>${prop.displayValue}</span> </li> `; }); htmlContent += '</ul>'; this.panelDom.innerHTML = htmlContent; }); }); return true; } unload() { // 卸载时清理DOM this.viewer.container.removeChild(this.panelDom); this.panelDom = null; return true; } } // 注册自定义扩展 Autodesk.Viewing.theExtensionManager.registerExtension('CustomPropertyPanel', CustomPropertyPanel); // 在Viewer初始化完成后加载扩展 viewer.loadExtension('CustomPropertyPanel');
内容的提问来源于stack exchange,提问作者Danila Eremenko
相关产品推荐
相关产品推荐

