资讯专栏INFORMATION COLUMN

在Forge Viewer上显示自订义属性

seasonley / 1891人阅读

摘要:最近有的小伙伴们都在询问要怎么在里显示自订义属性,要做到这个是挺容易的。在来我们透过继承来创建自个的属性面板使用的语法,部份代码来自的无法从服务器获取属性透过撰写括展让自定义属性窗取代自带的以上希望对各为小伙伴有帮助参考

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

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

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

const propPanel = viewer.getPropertyPanel( true );

透过 propPanel.addProperty() 添加自订义属性,例如:

propPanel.addProperty( "所属房名", "课厅", "其他" );

一般我们不会这样直接调用这些方法,而是将它写到一个 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 );

二、使用自定义属性面板

使用这个方法是创建一个自定义的属性面板,并透过 viewer.setPropertyPanel() 取代Viewer 自带的属性面板。

在来我们透过继承 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();
       }
    }
}

透过撰写括展让自定义属性窗取代自带的:

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...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89251.html

相关文章

  • 订义 Forge Viewer ModelStructurePanel 的交互行为

    摘要:在官方释出版的同时发布了新版本的,这个面版已被整个重新改写,这次更新也加入一些新的交互行为,下面我们将会稍作解释。 这礼拜的小技巧是关于如何以不加入太多的 JavaScript 的方式自订义 ModelStructurePanel 的交互行为,这个小技巧受到这篇问与答的启发:Prevent zoom in Forge viewer when clicking in Model Brow...

    xialong 评论0 收藏0
  • Forge Viewer 里加入订义线

    摘要:可能有许多原因你想在里加入自订义的线型,例如显示线框几何视觉化包围箱或者其他你想带给使用者的视觉回馈。下面是我传写的一个例子,他可以在选重构件后在场景里用自定义线型描绘它的包围箱,在线示例可以参考这里 showImg(https://segmentfault.com/img/bVVaUx?w=1794&h=930); 这篇文章的原著是 Autodesk AND 的 Philippe L...

    zilu 评论0 收藏0
  • 自定义 Forge Viewer 右键菜单(Context Menu)

    摘要:前阵子有些圈的朋友们都在询问同一个问题要怎么在的自带右键菜单上添加自定义项目或是只显示自订义项目以下将针对在自带右键菜单上添加自定义项目和只显示自订义项目的右键菜单进行说明。 前阵子有些 Autodesk Forge 圈的朋友们都在询问同一个问题『要怎么在 Viewer 的自带右键菜单上添加自定义项目或是只显示自订义项目』~ 以下将针对『在自带右键菜单上添加自定义项目』和『只显示自订义...

    Harriet666 评论0 收藏0
  • Forge Viewer 里展示/隐藏构件材质

    摘要:对于大多数的模型文档都可以透过服务提取转换在里渲染构件外观时所需的材质及贴图。所以我们可以透过它遍历所有材质,找出我们想隐藏贴图的那些材质,将它的颜色设置为灰色,同时也可以透过它将隐藏贴图的材质回复。 这篇文章来自 Autodesk ADN 的梁晓冬,以下以我简称。 对于大多数的模型文档都可以透过 Autodesk Forge Model Derivative 服务提取、转换在 Vie...

    Dean 评论0 收藏0
  • Autodesk Forge Viewer 信息本地化技术分析

    摘要:默认情况下,是英文环境,调取的是的资源其实无需翻译。但是,如前面提到的,语言包只是包含了部分常规字串的翻译,如果遇到没有包含的常规字串怎么办呢例如,本例中的语言包并没有对,进行翻译,所以即使切换了语言,它们仍旧是英文。 注:本文是个人调试分析所得,非官方文档,请酌情选用参考。文中分析的数据由https://extract.autodesk.io转换下载而来。 谈到信息本地化,个人觉得包...

    littleGrow 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<