前陣子有些 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