在Forge Viewer上显示自订义属性

最近有 Autodesk Forge 的小伙伴们都在询问要怎么在 Viewer 里显示自订义属性,要做到这个是挺容易的。目前有两种方式可以做到这个效果,一种是直接添加自定属性到 Viewer 自带的属性面板上,另一种是使用自定义属性面板,其作法如下所示:

一、添加自定属性到 Viewer 自带的属性面板上:

  1. 要添加自定义属性到自带的属性面板上前必需先获取属性面板的实体:

    const propPanel = viewer.getPropertyPanel( true );
  2. 透过 propPanel.addProperty() 添加自订义属性,例如:

    propPanel.addProperty( '所属房名', '课厅', '其他' );
  3. 一般我们不会这样直接调用这些方法,而是将它写到一个 Viewer 扩展里,其范例如下 (使用 ES2017 的语法):

    class CustomProperyPanelExt extends Autodesk.Viewing.Extension {
        constructor( viewer, options ) {
            super( viewer, options );
            
            this.onSelectionChanged = this.onSelectionChanged.bind( this );
        }
        
        getRemoteProps( dbId ) {
            return new Promise(( resolve, reject ) => {
                fetch( `http://127.0.0.1/api/props/${ dbId }`, {
                    method: 'get',
                    headers: new Headers({
                        'Content-Type': 'application/json'
                    })
                })
                .then( ( response ) => {
                    if( response.status === 200 ) {
                      return response.json();
                    } else {
                      return reject( new Error( response.statusText ) );
                    }
                })
                .then( ( data ) => {
                   if( !data ) return reject( new Error( '无法从服务器获取属性' ) );
                
                   return resolve( data );
                })
                .catch( ( error ) => reject( new Error( error ) ) );
            });
        }
        
        async onSelectionChanged( event ) {
            if( !event.selections || event.selections.length <= 0
                || !event.selections[0].dbIdArray
                || event.selections[0].dbIdArray.length <= 0 ) return;
            
            const dbId = event.selections[0].dbIdArray[0];
            const propPanel = this.viewer.getPropertyPanel( true );
            
            try {
              const props = await this.getRemoteProps( dbId );
    
              for( let i = 0; i < props.length; i++ ) {
                  const prop = props[i];
                  propPanel.addProperty( prop.name, prop.value, prop.category );
              }
            } catch( error ) {
                console.error( 
            }
        }
        
        load() {
            this.viewer.addEventListener(
                Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,
                this.onSelectionChanged
            );
            return true;
        }
        
        unload() {
            this.viewer.removeEventListener(
                Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT,
                this.onSelectionChanged
            );
            return true;
        }
    }
    Autodesk.Viewing.theExtensionManager.registerExtension( 'Autodesk.ADN.CustomPropsPanel', CustomProperyPanelExt );

二、使用自定义属性面板

  1. 使用这个方法是创建一个自定义的属性面板,并透过 viewer.setPropertyPanel() 取代Viewer 自带的属性面板。
  2. 在来我们透过继承 Autodesk.Viewing.Extensions.ViewerPropertyPanel 来创建自个的属性面板(使用 ES2017 的语法,部份代码来自 Forge Viewer 的 viewer3D.js):

    class CustomPropsPanel extends Autodesk.Viewing.Extensions.ViewerPropertyPanel {
        constructor( viewer ) {
            super( viewer );
        }
        
        getRemoteProps( dbId ) {
            return new Promise(( resolve, reject ) => {
                fetch( `http://127.0.0.1/api/props/${ dbId }`, {
                    method: 'get',
                    headers: new Headers({
                        'Content-Type': 'application/json'
                    })
                })
                .then( ( response ) => {
                    if( response.status === 200 ) {
                      return response.json();
                    } else {
                      return reject( new Error( response.statusText ) );
                    }
                })
                .then( ( data ) => {
                   if( !data ) return reject( new Error( '无法从服务器获取属性' ) );
                
                   return resolve( data );
                })
                .catch( ( error ) => reject( new Error( error ) ) );
            });
        }
        
        async setNodeProperties( dbId ) {
            this.propertyNodeId = dbId;
            
            if( !this.viewer ) return;
            
            try {
                const reuslt = await this.getRemoteProps( dbId );
    
                this.setTitle( reuslt.Name, { localizeTitle: true } );
                this.setProperties( reuslt.properties );
                this.highlight( this.viewer.searchText );
        
                this.resizeToContent();
        
                if( this.isVisible() ) {
                    const toolController = this.viewer.toolController,
                    mx = toolController.lastClickX,
                    my = toolController.lastClickY,
                    panelRect = this.container.getBoundingClientRect(),
                    px = panelRect.left,
                    py = panelRect.top,
                    pw = panelRect.width,
                    ph = panelRect.height,
                    canvasRect = this.viewer.canvas.getBoundingClientRect(),
                    cx = canvasRect.left,
                    cy = canvasRect.top,
                    cw = canvasRect.width,
                    ch = canvasRect.height;
            
                    if( (px <= mx && mx < px + pw) && (py <= my && my < py + ph) ) {
                        if( (mx < px + (pw / 2)) && (mx + pw) < (cx + cw) ) {
                           this.container.style.left = Math.round( mx - cx ) + 'px';
                           this.container.dockRight = false;
                        } else if( cx <= (mx - pw) ) {
                           this.container.style.left = Math.round( mx - cx - pw ) + 'px';
                           this.container.dockRight = false;
                        } else if( (mx + pw) < (cx + cw) ) {
                           this.container.style.left = Math.round( mx - cx ) + 'px';
                           this.container.dockRight = false;
                        } else if( (my + ph) < (cy + ch) ) {
                           this.container.style.top = Math.round( my - cy ) + 'px';
                           this.container.dockBottom = false;
                        } else if( cy <= (my - ph) ) {
                           this.container.style.top = Math.round( my - cy - ph ) + 'px';
                           this.container.dockBottom = false;
                        }
                   }
              }
           } catch( error ) {
               this.showDefaultProperties();
           }
        }
    }
  3. 透过撰写括展让自定义属性窗取代自带的:

    class CustomProperyPanelExt extends Autodesk.Viewing.Extension {
        constructor( viewer, options ) {
            super( viewer, options );
        }
    
        load() {
            this.viewer.setPropertyPanel( new CustomPropsPanel( viewer ) );
            return true;
        }
        
        unload() {
            return true;
        }
    }
    Autodesk.Viewing.theExtensionManager.registerExtension( 'Autodesk.ADN.CustomPropsPanel', CustomProperyPanelExt );

以上希望对各为小伙伴有帮助~

参考:https://github.com/Autodesk-F...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值