Extensions
In this tutorial we’ll be creating a viewer extension called MyAwesomeExtension
.
We will also add 2 HTML buttons to interact with the added extension. These 2 buttons will be placed below and outside the Viewer canvas.
One of the buttons will be used to lock the camera. Users will not be able to orbit (rotate), pan, or zoom. The second button will be used to unlock the camera, re-enabling mouse and touch interactions.
Before You Begin
Instantiate a ViewingApplication before moving ahead; it provides a solid starting point.
Step 1: Include extension file
Extensions need to be defined after all core classes for The Viewer have been defined.
For this tutorial, create file my-awesome-extension.js
and include it in the HTML.
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/2.*/three.min.js"></script>
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/2.*/viewer3D.min.js"></script>
<script src="my-awesome-extension.js"></script>
Step 2: Write the extension code
An extension consists of the following interface points:
- Inherits from
Autodesk.Viewing.Extension
. - Defines method
load()
that returns aboolean
. - Defines method
unload()
that also returns aboolean
. - Registers itself with a unique
string id
.
// Content for 'my-awesome-extension.js'
function MyAwesomeExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
MyAwesomeExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
MyAwesomeExtension.prototype.constructor = MyAwesomeExtension;
MyAwesomeExtension.prototype.load = function() {
alert('MyAwesomeExtension is loaded!');
return true;
};
MyAwesomeExtension.prototype.unload = function() {
alert('MyAwesomeExtension is now unloaded!');
return true;
};
Autodesk.Viewing.theExtensionManager.registerExtension('MyAwesomeExtension', MyAwesomeExtension);
An extension will successfully get loaded into The Viewer’s lifecycle only if load()
returns true
.
Likewise, an extension will get successfully unloaded if unload()
returns true
.
Notice that the string 'MyAwesomeExtension'
used in registerExtension()
doesn’t need to match the
function name declaration.
You’ll notice that by refreshing the HTML page the extension does not get loaded.
Step 3: Load the extension
We’ll need to instruct the ViewingApplication
to load our extension:
var config3d = {
extensions: ['MyAwesomeExtension']
};
viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config3d);
Refresh the HTML page and you will now see the alert()
message found in our extension’s load()
method.
Step 6: Cleanup on unload
It’s good practice to remove added event listeners to DOM elements when the extension is unloaded. Perform all cleanup operations in the unload method.
MyAwesomeExtension.prototype.lockViewport = function() {
this.viewer.setNavigationLock(true);
};
MyAwesomeExtension.prototype.unlockViewport = function() {
this.viewer.setNavigationLock(false);
};
MyAwesomeExtension.prototype.load = function() {
// alert('MyAwesomeExtension is loaded!');
this.onLockBinded = this.lockViewport.bind(this);
this.onUnlockBinded = this.unlockViewport.bind(this);
var lockBtn = document.getElementById('MyAwesomeLockButton');
lockBtn.addEventListener('click', this.onLockBinded);
var unlockBtn = document.getElementById('MyAwesomeUnlockButton');
unlockBtn.addEventListener('click', this.onUnlockBinded);
return true;
};
MyAwesomeExtension.prototype.unload = function() {
// alert('MyAwesomeExtension is now unloaded!');
var lockBtn = document.getElementById('MyAwesomeLockButton');
lockBtn.removeEventListener('click', this.onLockBinded);
var unlockBtn = document.getElementById('MyAwesomeUnlockButton');
unlockBtn.removeEventListener('click', this.onUnlockBinded);
this.onLockBinded = null;
this.onUnlockBinded = null;
return true;
};
Step 7: Extension Manual Testing
To fully test that the extension is working as expected, developers can manually force the extension to be loaded and unloaded.
From the browser’s console type the following to check whether your extension is loaded or not.
At this point, the extension should be loaded and the function call should return true
:
NOP_VIEWER.isExtensionLoaded('MyAwesomeExtension');
Notice that we are using global variable NOP_VIEWER
defined by the Viewer.
Now type the following to unload
the extension:
NOP_VIEWER.unloadExtension('MyAwesomeExtension');
If all goes as expected, the added buttons should no longer work. Click on them to validate.
You can then load the extension again by calling
NOP_VIEWER.loadExtension('MyAwesomeExtension');
Now the added buttons will again work as expected.
What’s next?
You may find out that having the buttons still present when unloading the extension is less than ideal. Having the buttons added to the HTML when the extension loads and then having them removed when the extension unloads is left as an exercise to the reader.