前阵子有些 Autodesk Forge 圈的朋友们都在询问同一个问题『要怎么在 Viewer 的自带右键菜单上添加自定义项目或是只显示自订义项目』~ 如下将针对『在自带右键菜单上添加自定义项目』和『只显示自订义项目的右键菜单』进行说明。canvas
1、 在自带右键菜单上添加自定义项目:api
在自带右键菜单上添加自定义项目是很是容易的,Forge Viewer 提供了一个 API 让使用者能够很是轻易的在自带菜单上添加自个的项目,而你须要作的就是像下面这段代码同样作一个简单的 API 调用。下面这个例子会在右键菜单上添加两个新项目,一个是『改变已选构件的颜色成红色(Override color of selected elements to red)』,另外一个是『回复颜色变动(Clear overridden corlor)』:async
viewer.registerContextMenuCallback( 'MyChangingColorMenuItems', ( menu, status ) => { if( status.hasSelected ) { menu.push({ title: 'Override color of selected elements to red', target: () => { const selSet = this.viewer.getSelection(); this.viewer.clearSelection(); const color = new THREE.Vector4( 255 / 255, 0, 0, 1 ); for( let i = 0; i < selSet.length; i++ ) { this.viewer.setThemingColor( selSet[i], color ); } } }); } else { menu.push({ title: 'Clear overridden corlor', target: () => { this.viewer.clearThemingColors(); } }); } });
在执行完上面的代码后就在右键菜单上看到这两个项目:ide
但通常状况下,咱们会将上面的代码放到一个自定义括展里头,让咱们能够灵活的使用:函数
class MyMenuItemExtension extends Autodesk.Viewing.Extension { constructor( viewer, options ) { super( viewer, options ); this.onBuildingContextMenuItem = this.onBuildingContextMenuItem.bind( this ); } get menuId() { return 'MyColorContextMenu'; } onBuildingContextMenuItem( menu, status ) { if( status.hasSelected ) { menu.push({ title: 'Override color of selected elements to red', target: () => { const selSet = this.viewer.getSelection(); this.viewer.clearSelection(); // Change color of selected elements to the red const color = new THREE.Vector4( 255 / 255, 0, 0, 1 ); for( let i = 0; i < selSet.length; i++ ) { this.viewer.setThemingColor( selSet[i], color ); } } }); } else { menu.push({ title: 'Clear overridden corlor', target: () => { this.viewer.clearThemingColors(); } }); } } load() { // Add my owned menu items this.viewer.registerContextMenuCallback( this.menuId, this.onBuildingContextMenuItem ); return true; } unload() { // Remove all menu items added from this extension this.viewer.unregisterContextMenuCallback( this.menuId ); return true; } } Autodesk.Viewing.theExtensionManager.registerExtension( 'DemoMenuExtension', MyMenuItemExtension );
2、 只显示自订义项目的右键菜单:post
若是上头的代码与你的需求不符合,你能够考虑编写一自订义的右键菜单,同样的他也不会太困难。如今举个例子来讲明,像如今若是我想让自带右键菜单上除了自带项目外,还会在点击到不一样构件时显示不一样的项目;我须要作的就是经过继承 Autodesk.Viewing.Extensions.ViewerObjectContextMenu
和加入 hitTest
相关的逻辑到自定义右键菜单的 buildMenu
函数,就像下面这样:ui
class MyContextMenu extends Autodesk.Viewing.Extensions.ViewerObjectContextMenu { constructor( viewer ) { super( viewer ); } isWall( dbId ) { //Logics for determining if selected element is wall or not. return new Promise( ( resolve, reject ) => { $.get( '/api/walls/' + dbId, ( response ) => { if( response && response.id != 0 ) { return resolve( true ); } return resolve( false ); } ) .error( ( error ) => reject( error ) ); }); } async buildMenu( event, status ) { // Get defulat menu items from the super class const menu = super.buildMenu( event, status ); // Do hitTest to get dbIds const viewport = this.viewer.container.getBoundingClientRect(); const canvasX = event.clientX - viewport.left; const canvasY = event.clientY - viewport.top; const result = this.viewer.impl.hitTest( canvasX, canvasY, false ); if( !result || !result.dbId ) return menu; let isWall = false; try { isWall = await this.isWall( result.dbId ); } catch ( error ) { isWall = false; } if( status.hasSelected && isWall ) { menu.push({ title: 'Show current surface temperature map', target: () => { $.post( '/api/walls/temperature', ( response ) => { ViewerUtil.showWallTemperatureMap( response.values ); } ); } }); } return menu; } /** * @override */ async show( event ) { const numSelected = this.viewer.getSelectionCount(); const visibility = this.viewer.getSelectionVisibility(); const status = { numSelected: numSelected, hasSelected: ( numSelected > 0 ), hasVisible: visibility.hasVisible, hasHidden: visibility.hasHidden }; const menu = await this.buildMenu( event, status ); this.viewer.runContextMenuCallbacks( menu, status ); if( menu && menu.length > 0 ) { this.contextMenu.show( event, menu ); } } } class MyContextMenuExtension extends Autodesk.Viewing.Extension { constructor( viewer, options ) { super( viewer, options ); } load() { // Use my owned context menu. this.viewer.setContextMenu( new MyContextMenu( this.viewer ) ); return true; } unload() { // Restore default context menu this.viewer.setContextMenu( new Autodesk.Viewing.Extensions.ViewerObjectContextMenu( this.viewer ) ); return true; } } Autodesk.Viewing.theExtensionManager.registerExtension( 'DemoWallMenuExtension', MyContextMenuExtension );
这样子就会在点击到墙构件显示这个项目『Show current surface temperature map』:this
相反的,若是你不想显示菜单上自带的项目,你能够改为继承 Autodesk.Viewing.UI.ObjectContextMenu
。但你点击到墙构件的时候就只会显示『Show current surface temperature map』这个项目,就像下面这个样子:spa
但愿上面的说明对各位使用 Autodesk Forge 的朋友们有些帮助~code