@vrame/xeokit-sdk
Version:
3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision
468 lines (465 loc) • 4.56 MB
JavaScript
/**
* xeokit-sdk v2.6.88.2
* Commit: d3178e1926774d0d6eed55c1c046913645246cb0
* Built: 2025-08-29T06:26:51.447Z
*/
var _globalThis$loaders3;var _marked=/*#__PURE__*/_regenerator().m(makeStringIterator),_marked2=/*#__PURE__*/_regenerator().m(makeMeshPrimitiveIterator);function _wrapNativeSuper(t){var r="function"==typeof Map?new Map():void 0;return _wrapNativeSuper=function _wrapNativeSuper(t){if(null===t||!_isNativeFunction(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==r){if(r.has(t))return r.get(t);r.set(t,Wrapper);}function Wrapper(){return _construct(t,arguments,_getPrototypeOf(this).constructor);}return Wrapper.prototype=Object.create(t.prototype,{constructor:{value:Wrapper,enumerable:!1,writable:!0,configurable:!0}}),_setPrototypeOf(Wrapper,t);},_wrapNativeSuper(t);}function _construct(t,e,r){if(_isNativeReflectConstruct())return Reflect.construct.apply(null,arguments);var o=[null];o.push.apply(o,e);var p=new(t.bind.apply(t,o))();return r&&_setPrototypeOf(p,r.prototype),p;}function _isNativeFunction(t){try{return-1!==Function.toString.call(t).indexOf("[native code]");}catch(n){return"function"==typeof t;}}function _regenerator(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e,t,r="function"==typeof Symbol?Symbol:{},n=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,n,o,i){var c=n&&n.prototype instanceof Generator?n:Generator,u=Object.create(c.prototype);return _regeneratorDefine2(u,"_invoke",function(r,n,o){var i,c,u,f=0,p=o||[],y=!1,G={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function d(t,r){return i=t,c=0,u=e,G.n=r,a;}};function d(r,n){for(c=r,u=n,t=0;!y&&f&&!o&&t<p.length;t++){var o,i=p[t],d=G.p,l=i[2];r>3?(o=l===n)&&(u=i[(c=i[4])?5:(c=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(c=0,G.v=n,G.n=i[1]):d<l&&(o=r<3||i[0]>n||n>l)&&(i[4]=r,i[5]=n,G.n=l,c=0));}if(o||r>1)return a;throw y=!0,n;}return function(o,p,l){if(f>1)throw TypeError("Generator is already running");for(y&&1===p&&d(p,l),c=p,u=l;(t=c<2?e:u)||!y;){i||(c?c<3?(c>1&&(G.n=-1),d(c,u)):G.n=u:G.v=u);try{if(f=2,i){if(c||(o="next"),t=i[o]){if(!(t=t.call(i,u)))throw TypeError("iterator result is not an object");if(!t.done)return t;u=t.value,c<2&&(c=0);}else 1===c&&(t=i["return"])&&t.call(i),c<2&&(u=TypeError("The iterator does not provide a '"+o+"' method"),c=1);i=e;}else if((t=(y=G.n<0)?u:r.call(n,G))!==a)break;}catch(t){i=e,c=1,u=t;}finally{f=1;}}return{value:t,done:y};};}(r,o,i),!0),u;}var a={};function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}t=Object.getPrototypeOf;var c=[][n]?t(t([][n]())):(_regeneratorDefine2(t={},n,function(){return this;}),t),u=GeneratorFunctionPrototype.prototype=Generator.prototype=Object.create(c);function f(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,GeneratorFunctionPrototype):(e.__proto__=GeneratorFunctionPrototype,_regeneratorDefine2(e,o,"GeneratorFunction")),e.prototype=Object.create(u),e;}return GeneratorFunction.prototype=GeneratorFunctionPrototype,_regeneratorDefine2(u,"constructor",GeneratorFunctionPrototype),_regeneratorDefine2(GeneratorFunctionPrototype,"constructor",GeneratorFunction),GeneratorFunction.displayName="GeneratorFunction",_regeneratorDefine2(GeneratorFunctionPrototype,o,"GeneratorFunction"),_regeneratorDefine2(u),_regeneratorDefine2(u,o,"Generator"),_regeneratorDefine2(u,n,function(){return this;}),_regeneratorDefine2(u,"toString",function(){return"[object Generator]";}),(_regenerator=function _regenerator(){return{w:i,m:f};})();}function _regeneratorDefine2(e,r,n,t){var i=Object.defineProperty;try{i({},"",{});}catch(e){i=0;}_regeneratorDefine2=function _regeneratorDefine(e,r,n,t){function o(r,n){_regeneratorDefine2(e,r,function(e){return this._invoke(r,n,e);});}r?i?i(e,r,{value:n,enumerable:!t,configurable:!t,writable:!t}):e[r]=n:(o("next",0),o("throw",1),o("return",2));},_regeneratorDefine2(e,r,n,t);}function asyncGeneratorStep(n,t,e,r,o,a,c){try{var i=n[a](c),u=i.value;}catch(n){return void e(n);}i.done?t(u):Promise.resolve(u).then(r,o);}function _asyncToGenerator(n){return function(){var t=this,e=arguments;return new Promise(function(r,o){var a=n.apply(t,e);function _next(n){asyncGeneratorStep(a,r,o,_next,_throw,"next",n);}function _throw(n){asyncGeneratorStep(a,r,o,_next,_throw,"throw",n);}_next(void 0);});};}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable;})),t.push.apply(t,o);}return t;}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r));});}return e;}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e;}function _createForOfIteratorHelper(r,e){var t="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(!t){if(Array.isArray(r)||(t=_unsupportedIterableToArray(r))||e&&r&&"number"==typeof r.length){t&&(r=t);var _n7=0,F=function F(){};return{s:F,n:function n(){return _n7>=r.length?{done:!0}:{done:!1,value:r[_n7++]};},e:function e(r){throw r;},f:F};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var o,a=!0,u=!1;return{s:function s(){t=t.call(r);},n:function n(){var r=t.next();return a=r.done,r;},e:function e(r){u=!0,o=r;},f:function f(){try{a||null==t["return"]||t["return"]();}finally{if(u)throw o;}}};}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread();}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r);}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r);}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e));}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t);}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e;}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t;})();}function _superPropGet(t,o,e,r){var p=_get(_getPrototypeOf(1&r?t.prototype:t),o,e);return 2&r&&"function"==typeof p?function(t){return p.apply(e,t);}:p;}function _get(){return _get="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,r){var p=_superPropBase(e,t);if(p){var n=Object.getOwnPropertyDescriptor(p,t);return n.get?n.get.call(arguments.length<3?e:r):n.value;}},_get.apply(null,arguments);}function _superPropBase(t,o){for(;!{}.hasOwnProperty.call(t,o)&&null!==(t=_getPrototypeOf(t)););return t;}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t);},_getPrototypeOf(t);}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e);}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t;},_setPrototypeOf(t,e);}function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0;}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n;}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1;}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r;}finally{try{if(!f&&null!=t["return"]&&(u=t["return"](),Object(u)!==u))return;}finally{if(o)throw n;}}return a;}}function _arrayWithHoles(r){if(Array.isArray(r))return r;}function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o;}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o;},_typeof(o);}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function");}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o);}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e;}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+"";}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return("string"===r?String:Number)(t);}function _awaitAsyncGenerator(e){return new _OverloadYield(e,0);}function _wrapAsyncGenerator(e){return function(){return new AsyncGenerator(e.apply(this,arguments));};}function AsyncGenerator(e){var r,t;function resume(r,t){try{var n=e[r](t),o=n.value,u=o instanceof _OverloadYield;Promise.resolve(u?o.v:o).then(function(t){if(u){var i="return"===r?"return":"next";if(!o.k||t.done)return resume(i,t);t=e[i](t).value;}settle(n.done?"return":"normal",t);},function(e){resume("throw",e);});}catch(e){settle("throw",e);}}function settle(e,n){switch(e){case"return":r.resolve({value:n,done:!0});break;case"throw":r.reject(n);break;default:r.resolve({value:n,done:!1});}(r=r.next)?resume(r.key,r.arg):t=null;}this._invoke=function(e,n){return new Promise(function(o,u){var i={key:e,arg:n,resolve:o,reject:u,next:null};t?t=t.next=i:(r=t=i,resume(e,n));});},"function"!=typeof e["return"]&&(this["return"]=void 0);}AsyncGenerator.prototype["function"==typeof Symbol&&Symbol.asyncIterator||"@@asyncIterator"]=function(){return this;},AsyncGenerator.prototype.next=function(e){return this._invoke("next",e);},AsyncGenerator.prototype["throw"]=function(e){return this._invoke("throw",e);},AsyncGenerator.prototype["return"]=function(e){return this._invoke("return",e);};function _OverloadYield(e,d){this.v=e,this.k=d;}function _asyncIterator(r){var n,t,o,e=2;for("undefined"!=typeof Symbol&&(t=Symbol.asyncIterator,o=Symbol.iterator);e--;){if(t&&null!=(n=r[t]))return n.call(r);if(o&&null!=(n=r[o]))return new AsyncFromSyncIterator(n.call(r));t="@@asyncIterator",o="@@iterator";}throw new TypeError("Object is not async iterable");}function AsyncFromSyncIterator(r){function AsyncFromSyncIteratorContinuation(r){if(Object(r)!==r)return Promise.reject(new TypeError(r+" is not an object."));var n=r.done;return Promise.resolve(r.value).then(function(r){return{value:r,done:n};});}return AsyncFromSyncIterator=function AsyncFromSyncIterator(r){this.s=r,this.n=r.next;},AsyncFromSyncIterator.prototype={s:null,n:null,next:function next(){return AsyncFromSyncIteratorContinuation(this.n.apply(this.s,arguments));},"return":function _return(r){var n=this.s["return"];return void 0===n?Promise.resolve({value:r,done:!0}):AsyncFromSyncIteratorContinuation(n.apply(this.s,arguments));},"throw":function _throw(r){var n=this.s["return"];return void 0===n?Promise.reject(r):AsyncFromSyncIteratorContinuation(n.apply(this.s,arguments));}},new AsyncFromSyncIterator(r);}/** @private */var Map$1=/*#__PURE__*/function(){function Map$1(items,baseId){_classCallCheck(this,Map$1);this.items=items||[];this._lastUniqueId=(baseId||0)+1;}/**
* Usage:
*
* id = myMap.addItem("foo") // ID internally generated
* id = myMap.addItem("foo", "bar") // ID is "foo"
*/return _createClass(Map$1,[{key:"addItem",value:function addItem(){var item;if(arguments.length===2){var id=arguments[0];item=arguments[1];if(this.items[id]){// Won't happen if given ID is string
throw"ID clash: '"+id+"'";}this.items[id]=item;return id;}else{item=arguments[0]||{};while(true){var findId=this._lastUniqueId++;if(!this.items[findId]){this.items[findId]=item;return findId;}}}}},{key:"removeItem",value:function removeItem(id){var item=this.items[id];delete this.items[id];return item;}}]);}();var idMap=new Map$1();/**
* Internal data class that represents the state of a menu or a submenu.
* @private
*/var Menu=/*#__PURE__*/_createClass(function Menu(id){_classCallCheck(this,Menu);this.id=id;this.parentItem=null;// Set to an Item when this Menu is a submenu
this.groups=[];this.menuElement=null;this.shown=false;this.mouseOver=0;});/**
* Internal data class that represents a group of Items in a Menu.
* @private
*/var Group=/*#__PURE__*/_createClass(function Group(){_classCallCheck(this,Group);this.items=[];});/**
* Internal data class that represents the state of a menu item.
* @private
*/var Item=/*#__PURE__*/_createClass(function Item(id,getTitle,doAction,getEnabled,getShown){_classCallCheck(this,Item);this.id=id;this.getTitle=getTitle;this.doAction=doAction;this.getEnabled=getEnabled;this.getShown=getShown;this.itemElement=null;this.subMenu=null;this.enabled=true;});/**
* @desc A customizable HTML context menu.
*
* [<img src="http://xeokit.io/img/docs/ContextMenu/ContextMenu.gif">](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)
*
* * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_TreeViewPlugin_Custom)]
*
* ## Overview
*
* * A pure JavaScript, lightweight context menu
* * Dynamically configure menu items
* * Dynamically enable or disable items
* * Dynamically show or hide items
* * Supports cascading sub-menus
* * Configure custom style with CSS (see examples above)
*
* ## Usage
*
* In the example below we'll create a ````ContextMenu```` that pops up whenever we right-click on an {@link Entity} within
* our {@link Scene}.
*
* First, we'll create the ````ContextMenu````, configuring it with a list of menu items.
*
* Each item has:
*
* * a ````title```` for the item,
* * a ````doAction()```` callback to fire when the item's title is clicked,
* * an optional ````getShown()```` callback that indicates if the item should shown in the menu or not, and
* * an optional ````getEnabled()```` callback that indicates if the item should be shown enabled in the menu or not.
*
* <br>
*
* The ````getShown()```` and ````getEnabled()```` callbacks are invoked whenever the menu is shown.
*
* When an item's ````getShown()```` callback
* returns ````true````, then the item is shown. When it returns ````false````, then the item is hidden. An item without
* a ````getShown()```` callback is always shown.
*
* When an item's ````getEnabled()```` callback returns ````true````, then the item is enabled and clickable (as long as it's also shown). When it
* returns ````false````, then the item is disabled and cannot be clicked. An item without a ````getEnabled()````
* callback is always enabled and clickable.
*
* Note how the ````doAction()````, ````getShown()```` and ````getEnabled()```` callbacks accept a ````context````
* object. That must be set on the ````ContextMenu```` before we're able to we show it. The context object can be anything. In this example,
* we'll use the context object to provide the callbacks with the Entity that we right-clicked.
*
* We'll also initially enable the ````ContextMenu````.
*
* [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_Canvas_Custom)]
*
* ````javascript
* const canvasContextMenu = new ContextMenu({
*
* enabled: true,
*
* items: [
* [
* {
* title: "Hide Object",
* getEnabled: (context) => {
* return context.entity.visible; // Can't hide entity if already hidden
* },
* doAction: function (context) {
* context.entity.visible = false;
* }
* }
* ],
* [
* {
* title: "Select Object",
* getEnabled: (context) => {
* return (!context.entity.selected); // Can't select an entity that's already selected
* },
* doAction: function (context) {
* context.entity.selected = true;
* }
* }
* ],
* [
* {
* title: "X-Ray Object",
* getEnabled: (context) => {
* return (!context.entity.xrayed); // Can't X-ray an entity that's already X-rayed
* },
* doAction: (context) => {
* context.entity.xrayed = true;
* }
* }
* ]
* ]
* });
* ````
*
* Next, we'll make the ````ContextMenu```` appear whenever we right-click on an Entity. Whenever we right-click
* on the canvas, we'll attempt to pick the Entity at those mouse coordinates. If we succeed, we'll feed the
* Entity into ````ContextMenu```` via the context object, then show the ````ContextMenu````.
*
* From there, each ````ContextMenu```` item's ````getEnabled()```` callback will be invoked (if provided), to determine if the item should
* be enabled. If we click an item, its ````doAction()```` callback will be invoked with our context object.
*
* Remember that we must set the context on our ````ContextMenu```` before we show it, otherwise it will log an error to the console,
* and ignore our attempt to show it.
*
* ````javascript*
* viewer.scene.canvas.canvas.oncontextmenu = (e) => { // Right-clicked on the canvas
*
* if (!objectContextMenu.enabled) {
* return;
* }
*
* var hit = viewer.scene.pick({ // Try to pick an Entity at the coordinates
* canvasPos: [e.pageX, e.pageY]
* });
*
* if (hit) { // Picked an Entity
*
* objectContextMenu.context = { // Feed entity to ContextMenu
* entity: hit.entity
* };
*
* objectContextMenu.show(e.pageX, e.pageY); // Show the ContextMenu
* }
*
* e.preventDefault();
* });
* ````
*
* Note how we only show the ````ContextMenu```` if it's enabled. We can use that mechanism to switch between multiple
* ````ContextMenu```` instances depending on what we clicked.
*
* ## Dynamic Item Titles
*
* To make an item dynamically regenerate its title text whenever we show the ````ContextMenu````, provide its title with a
* ````getTitle()```` callback. The callback will fire each time you show ````ContextMenu````, which will dynamically
* set the item title text.
*
* In the example below, we'll create a simple ````ContextMenu```` that allows us to toggle the selection of an object
* via its first item, which changes text depending on whether we are selecting or deselecting the object.
*
* [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_dynamicItemTitles)]
*
* ````javascript
* const canvasContextMenu = new ContextMenu({
*
* enabled: true,
*
* items: [
* [
* {
* getTitle: (context) => {
* return (!context.entity.selected) ? "Select" : "Undo Select";
* },
* doAction: function (context) {
* context.entity.selected = !context.entity.selected;
* }
* },
* {
* title: "Clear Selection",
* getEnabled: function (context) {
* return (context.viewer.scene.numSelectedObjects > 0);
* },
* doAction: function (context) {
* context.viewer.scene.setObjectsSelected(context.viewer.scene.selectedObjectIds, false);
* }
* }
* ]
* ]
* });
* ````
*
* ## Sub-menus
*
* Each menu item can optionally have a sub-menu, which will appear when we hover over the item.
*
* In the example below, we'll create a much simpler ````ContextMenu```` that has only one item, called "Effects", which
* will open a cascading sub-menu whenever we hover over that item.
*
* Note that our "Effects" item has no ````doAction```` callback, because an item with a sub-menu performs no
* action of its own.
*
* [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/index.html#ContextMenu_subMenus)]
*
* ````javascript
* const canvasContextMenu = new ContextMenu({
* items: [ // Top level items
* [
* {
* getTitle: (context) => {
* return "Effects";
* },
*
* items: [ // Sub-menu
* [
* {
* getTitle: (context) => {
* return (!context.entity.visible) ? "Show" : "Hide";
* },
* doAction: function (context) {
* context.entity.visible = !context.entity.visible;
* }
* },
* {
* getTitle: (context) => {
* return (!context.entity.selected) ? "Select" : "Undo Select";
* },
* doAction: function (context) {
* context.entity.selected = !context.entity.selected;
* }
* },
* {
* getTitle: (context) => {
* return (!context.entity.highlighted) ? "Highlight" : "Undo Highlight";
* },
* doAction: function (context) {
* context.entity.highlighted = !context.entity.highlighted;
* }
* }
* ]
* ]
* }
* ]
* ]
* });
* ````
*/var ContextMenu=/*#__PURE__*/function(){/**
* Creates a ````ContextMenu````.
*
* The ````ContextMenu```` will be initially hidden.
*
* @param {Object} [cfg] ````ContextMenu```` configuration.
* @param {Object} [cfg.items] The context menu items. These can also be dynamically set on {@link ContextMenu#items}. See the class documentation for an example.
* @param {Object} [cfg.context] The context, which is passed into the item callbacks. This can also be dynamically set on {@link ContextMenu#context}. This must be set before calling {@link ContextMenu#show}.
* @param {Boolean} [cfg.enabled=true] Whether this ````ContextMenu```` is initially enabled. {@link ContextMenu#show} does nothing while this is ````false````.
* @param {Boolean} [cfg.hideOnMouseDown=true] Whether this ````ContextMenu```` automatically hides whenever we mouse-down or tap anywhere in the page.
* @param {Boolean} [cfg.hideOnAction=true] Whether this ````ContextMenu```` automatically hides after we select a menu item. Se false if we want the menu to remain shown and show any updates to its item titles, after we've selected an item.
* @param {Node | undefined} [cfg.parentNode] Optional reference to an existing DOM Node (e.g. ShadowRoot), to which the menu's HTML element will be appended, defaults to ````document.body````.
*/function ContextMenu(){var _this2=this;var cfg=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};_classCallCheck(this,ContextMenu);this._id=idMap.addItem();this._context=null;this._enabled=false;// True when the ContextMenu is enabled
this._itemsCfg=[];// Items as given as configs
this._rootMenu=null;// The root Menu in the tree
this._menuList=[];// List of Menus
this._menuMap={};// Menus mapped to their IDs
this._itemList=[];// List of Items
this._itemMap={};// Items mapped to their IDs
this._shown=false;// True when the ContextMenu is visible
this._nextId=0;this._parentNode=cfg.parentNode||document.body;this._offsetParent=this._parentNode instanceof ShadowRoot?this._parentNode.host:this._parentNode;/**
* Subscriptions to events fired at this ContextMenu.
* @private
*/this._eventSubs={};if(cfg.hideOnMouseDown!==false){this._parentNode.addEventListener("mousedown",function(event){if(!event.target.classList.contains("xeokit-context-menu-item")){_this2.hide();}});this._parentNode.addEventListener("touchstart",this._canvasTouchStartHandler=function(event){if(!event.target.classList.contains("xeokit-context-menu-item")){_this2.hide();}});}if(cfg.items){this.items=cfg.items;}this._hideOnAction=cfg.hideOnAction!==false;this.context=cfg.context;this.enabled=cfg.enabled!==false;this.hide();}/**
Subscribes to an event fired at this ````ContextMenu````.
@param {String} event The event
@param {Function} callback Callback fired on the event
*/return _createClass(ContextMenu,[{key:"on",value:function on(event,callback){var subs=this._eventSubs[event];if(!subs){subs=[];this._eventSubs[event]=subs;}subs.push(callback);}/**
Fires an event at this ````ContextMenu````.
@param {String} event The event type name
@param {Object} value The event parameters
*/},{key:"fire",value:function fire(event,value){var subs=this._eventSubs[event];if(subs){for(var _i2=0,len=subs.length;_i2<len;_i2++){subs[_i2](value);}}}/**
* Sets the ````ContextMenu```` items.
*
* These can be updated dynamically at any time.
*
* See class documentation for an example.
*
* @type {Object[]}
*/},{key:"items",get:/**
* Gets the ````ContextMenu```` items.
*
* @type {Object[]}
*/function get(){return this._itemsCfg;}/**
* Sets whether this ````ContextMenu```` is enabled.
*
* Hides the menu when disabling.
*
* @type {Boolean}
*/,set:function set(itemsCfg){this._clear();this._itemsCfg=itemsCfg||[];this._parseItems(itemsCfg);this._createUI();}},{key:"enabled",get:/**
* Gets whether this ````ContextMenu```` is enabled.
*
* {@link ContextMenu#show} does nothing while this is ````false````.
*
* @type {Boolean}
*/function get(){return this._enabled;}/**
* Sets the ````ContextMenu```` context.
*
* The context can be any object that you need to be provides to the callbacks configured on {@link ContextMenu#items}.
*
* This must be set before calling {@link ContextMenu#show}.
*
* @type {Object}
*/,set:function set(enabled){enabled=!!enabled;if(enabled===this._enabled){return;}this._enabled=enabled;if(!this._enabled){this.hide();}}},{key:"context",get:/**
* Gets the ````ContextMenu```` context.
*
* @type {Object}
*/function get(){return this._context;}/**
* Shows this ````ContextMenu```` at the given page coordinates.
*
* Does nothing when {@link ContextMenu#enabled} is ````false````.
*
* Logs error to console and does nothing if {@link ContextMenu#context} has not been set.
*
* Fires a "shown" event when shown.
*
* @param {Number} pageX Page X-coordinate.
* @param {Number} pageY Page Y-coordinate.
*/,set:function set(context){this._context=context;}},{key:"show",value:function show(pageX,pageY){if(!this._context){console.error("ContextMenu cannot be shown without a context - set context first");return;}if(!this._enabled){return;}if(this._shown){return;}this._hideAllMenus();this._updateItemsTitles();this._updateItemsEnabledStatus();this._showMenu(this._rootMenu.id,pageX,pageY);this._updateSubMenuInfo();this._shown=true;this.fire("shown",{});}/**
* Gets whether this ````ContextMenu```` is currently shown or not.
*
* @returns {Boolean} Whether this ````ContextMenu```` is shown.
*/},{key:"shown",get:function get(){return this._shown;}/**
* Hides this ````ContextMenu````.
*
* Fires a "hidden" event when hidden.
*/},{key:"hide",value:function hide(){if(!this._enabled){return;}if(!this._shown){return;}this._hideAllMenus();this._shown=false;this.fire("hidden",{});}/**
* Destroys this ````ContextMenu````.
*/},{key:"destroy",value:function destroy(){this._context=null;this._clear();if(this._id!==null){idMap.removeItem(this._id);this._id=null;}}},{key:"_clear",value:function _clear(){// Destroys DOM elements, clears menu data
for(var _i3=0,len=this._menuList.length;_i3<len;_i3++){var menu=this._menuList[_i3];var menuElement=menu.menuElement;menuElement.remove();}this._itemsCfg=[];this._rootMenu=null;this._menuList=[];this._menuMap={};this._itemList=[];this._itemMap={};}},{key:"_parseItems",value:function _parseItems(itemsCfg){var _this3=this;// Parses "items" config into menu data
var _visitItems=function visitItems(itemsCfg){var menuId=_this3._getNextId();var menu=new Menu(menuId);for(var _i4=0,len=itemsCfg.length;_i4<len;_i4++){var itemsGroupCfg=itemsCfg[_i4];var group=new Group();menu.groups.push(group);var _loop=function _loop(){var itemCfg=itemsGroupCfg[j];var subItemsCfg=itemCfg.items;var hasSubItems=subItemsCfg&&subItemsCfg.length>0;var itemId=_this3._getNextId();var getTitle=itemCfg.getTitle||function(){return itemCfg.title||"";};var doAction=itemCfg.doAction||itemCfg.callback||function(){};var getEnabled=itemCfg.getEnabled||function(){return true;};var getShown=itemCfg.getShown||function(){return true;};var item=new Item(itemId,getTitle,doAction,getEnabled,getShown);item.parentMenu=menu;group.items.push(item);if(hasSubItems){var subMenu=_visitItems(subItemsCfg);item.subMenu=subMenu;subMenu.parentItem=item;}_this3._itemList.push(item);_this3._itemMap[item.id]=item;};for(var j=0,lenj=itemsGroupCfg.length;j<lenj;j++){_loop();}}_this3._menuList.push(menu);_this3._menuMap[menu.id]=menu;return menu;};this._rootMenu=_visitItems(itemsCfg);}},{key:"_getNextId",value:function _getNextId(){// Returns a unique ID
return"ContextMenu_"+this._id+"_"+this._nextId++;// Start ID with alpha chars to make a valid DOM element selector
}},{key:"_createUI",value:function _createUI(){var _this4=this;// Builds DOM elements for the entire menu tree
var _visitMenu=function visitMenu(menu){_this4._createMenuUI(menu);var groups=menu.groups;for(var _i5=0,len=groups.length;_i5<len;_i5++){var group=groups[_i5];var groupItems=group.items;for(var j=0,lenj=groupItems.length;j<lenj;j++){var item=groupItems[j];var subMenu=item.subMenu;if(subMenu){_visitMenu(subMenu);}}}};_visitMenu(this._rootMenu);}},{key:"_createMenuUI",value:function _createMenuUI(menu){var _this5=this;// Builds DOM elements for a menu
var groups=menu.groups;var html=[];var menuElement=document.createElement("div");menuElement.classList.add("xeokit-context-menu",menu.id);menuElement.style.zIndex=300000;menuElement.style.position="absolute";html.push('<ul>');if(groups){for(var _i6=0,len=groups.length;_i6<len;_i6++){var group=groups[_i6];var groupIdx=_i6;var groupLen=len;var groupItems=group.items;if(groupItems){for(var j=0,lenj=groupItems.length;j<lenj;j++){var item=groupItems[j];var itemSubMenu=item.subMenu;var actionTitle=item.title||"";if(itemSubMenu){html.push('<li id="'+item.id+'" class="xeokit-context-menu-item xeokit-context-menu-submenu">'+actionTitle+'</li>');if(!(groupIdx===groupLen-1||j<lenj-1)){html.push('<li id="'+item.id+'" class="xeokit-context-menu-item-separator"></li>');}}else{html.push('<li id="'+item.id+'" class="xeokit-context-menu-item">'+actionTitle+'</li>');if(!(groupIdx===groupLen-1||j<lenj-1)){html.push('<li id="'+item.id+'" class="xeokit-context-menu-item-separator"></li>');}}}}}}html.push('</ul>');var htmlString=html.join("");menuElement.innerHTML=htmlString;this._parentNode.appendChild(menuElement);menu.menuElement=menuElement;menuElement.style["border-radius"]=4+"px";menuElement.style.display='none';menuElement.style["z-index"]=300000;menuElement.style.background="white";menuElement.style.border="1px solid black";menuElement.style["box-shadow"]="0 4px 5px 0 gray";menuElement.oncontextmenu=function(e){e.preventDefault();};// Bind event handlers
var self=this;var lastSubMenu=null;if(groups){for(var _i7=0,_len=groups.length;_i7<_len;_i7++){var _group=groups[_i7];var _groupItems=_group.items;if(_groupItems){var _loop2=function _loop2(){var item=_groupItems[_j2];var itemSubMenu=item.subMenu;item.itemElement=_this5._parentNode.querySelector("#".concat(item.id));if(!item.itemElement){console.error("ContextMenu item element not found: "+item.id);return 1;// continue
}item.itemElement.addEventListener("mouseenter",function(event){event.preventDefault();var subMenu=item.subMenu;if(!subMenu){if(lastSubMenu){self._hideMenu(lastSubMenu.id);lastSubMenu=null;}return;}if(lastSubMenu&&lastSubMenu.id!==subMenu.id){self._hideMenu(lastSubMenu.id);lastSubMenu=null;}if(item.enabled===false){return;}var itemElement=item.itemElement;var subMenuElement=subMenu.menuElement;var itemRect=itemElement.getBoundingClientRect();subMenuElement.getBoundingClientRect();var offsetRect=self._offsetParent.getBoundingClientRect();var subMenuWidth=200;// TODO
var showOnRight=itemRect.right+subMenuWidth<offsetRect.right;var showOnLeft=itemRect.left-subMenuWidth>offsetRect.left;if(showOnRight)self._showMenu(subMenu.id,itemRect.right+window.scrollX-5,itemRect.top+window.scrollY-1);else if(showOnLeft)self._showMenu(subMenu.id,itemRect.left-subMenuWidth+window.scrollX,itemRect.top+window.scrollY-1);else{var spaceOnLeft=itemRect.left-offsetRect.left,spaceOnRight=offsetRect.right-itemRect.right;if(spaceOnRight>spaceOnLeft)self._showMenu(subMenu.id,itemRect.right-5-(subMenuWidth-spaceOnRight),itemRect.top+window.scrollY-1);else self._showMenu(subMenu.id,itemRect.left-spaceOnLeft,itemRect.top+window.scrollY-1);}lastSubMenu=subMenu;});if(!itemSubMenu){// Item without sub-menu
// clicking item fires the item's action callback
item.itemElement.addEventListener("click",function(event){event.preventDefault();if(!self._context){return;}if(item.enabled===false){return;}if(item.doAction){item.doAction(self._context);}if(_this5._hideOnAction){self.hide();}else{self._updateItemsTitles();self._updateItemsEnabledStatus();}});item.itemElement.addEventListener("mouseup",function(event){if(event.which!==3){return;}event.preventDefault();if(!self._context){return;}if(item.enabled===false){return;}if(item.doAction){item.doAction(self._context);}if(_this5._hideOnAction){self.hide();}else{self._updateItemsTitles();self._updateItemsEnabledStatus();}});item.itemElement.addEventListener("mouseenter",function(event){event.preventDefault();if(item.enabled===false){return;}if(item.doHover){item.doHover(self._context);}});}};for(var _j2=0,_lenj=_groupItems.length;_j2<_lenj;_j2++){if(_loop2())continue;}}}}}},{key:"_updateItemsTitles",value:function _updateItemsTitles(){// Dynamically updates the title of each Item to the result of Item#getTitle()
if(!this._context){return;}for(var _i8=0,len=this._itemList.length;_i8<len;_i8++){var item=this._itemList[_i8];var itemElement=item.itemElement;if(!itemElement){continue;}var getShown=item.getShown;if(!getShown||!getShown(this._context)){continue;}var title=item.getTitle(this._context);if(item.subMenu){itemElement.innerText=title;}else{itemElement.innerText=title;}}}},{key:"_updateItemsEnabledStatus",value:function _updateItemsEnabledStatus(){// Enables or disables each Item, depending on the result of Item#getEnabled()
if(!this._context){return;}for(var _i9=0,len=this._itemList.length;_i9<len;_i9++){var item=this._itemList[_i9];var itemElement=item.itemElement;if(!itemElement){continue;}var getEnabled=item.getEnabled;if(!getEnabled){continue;}var getShown=item.getShown;if(!getShown){continue;}var shown=getShown(this._context);item.shown=shown;if(!shown){itemElement.style.display="none";continue;}else{itemElement.style.display="";}var enabled=getEnabled(this._context);item.enabled=enabled;if(!enabled){itemElement.classList.add("disabled");}else{itemElement.classList.remove("disabled");}}}},{key:"_updateSubMenuInfo",value:function _updateSubMenuInfo(){if(!this._context)return;var itemElement,itemRect,subMenuElement,initialStyles,showOnLeft,subMenuWidth;this._itemList.forEach(function(item){if(item.subMenu){itemElement=item.itemElement;itemRect=itemElement.getBoundingClientRect();subMenuElement=item.subMenu.menuElement;initialStyles={visibility:subMenuElement.style.visibility,display:subMenuElement.style.display};subMenuElement.style.display="block";subMenuElement.style.visibility="hidden";subMenuWidth=item.subMenu.menuElement.getBoundingClientRect().width;subMenuElement.style.visibility=initialStyles.visibility;subMenuElement.style.display=initialStyles.display;showOnLeft=itemRect.right+subMenuWidth>window.innerWidth;itemElement.setAttribute("data-submenuposition",showOnLeft?"left":"right");}});}},{key:"_showMenu",value:function _showMenu(menuId,pageX,pageY){// Shows the given menu, at the specified page coordinates
var menu=this._menuMap[menuId];if(!menu){console.error("Menu not found: "+menuId);return;}if(menu.shown){return;}var menuElement=menu.menuElement;if(menuElement){this._showMenuElement(menuElement,pageX,pageY);menu.shown=true;}}},{key:"_hideMenu",value:function _hideMenu(menuId){// Hides the given menu
var menu=this._menuMap[menuId];if(!menu){console.error("Menu not found: "+menuId);return;}if(!menu.shown){return;}var menuElement=menu.menuElement;if(menuElement){this._hideMenuElement(menuElement);menu.shown=false;}}},{key:"_hideAllMenus",value:function _hideAllMenus(){for(var _i0=0,len=this._menuList.length;_i0<len;_i0++){var menu=this._menuList[_i0];this._hideMenu(menu.id);}}},{key:"_showMenuElement",value:function _showMenuElement(menuElement,pageX,pageY){// Shows the given menu element, at the specified page coordinates
menuElement.style.display='block';var menuHeight=menuElement.offsetHeight;var menuWidth=menuElement.offsetWidth;var offsetRect=this._offsetParent.getBoundingClientRect();// A regression occurred, that positions the menu horizontally above the client viewport
// at 6188de17ddca5c069b75a7673c1cda1aa1e74d07 when window.innerHeight has been replaced by offsetRect.bottom
// Reported originally at XCD-332
// Reproducible with examples/measurement/distance_createWithMouse_snapping.html
// Dirty hack introduced as XEOK-306, to be improved in the future to a more general solution
var bottomContainerBorder=this._offsetParent===window.document.body&&offsetRect.bottom===0?window.innerHeight:offsetRect.bottom+window.scrollY;var rightContainerBorder=offsetRect.right+window.scrollX;if(pageY+menuHeight>bottomContainerBorder){pageY=bottomContainerBorder-menuHeight;}if(pageX+menuWidth>rightContainerBorder){pageX=rightContainerBorder-menuWidth;}menuElement.style.left=pageX-offsetRect.left-window.scrollX+'px';menuElement.style.top=pageY-offsetRect.top-window.scrollY+'px';}},{key:"_hideMenuElement",value:function _hideMenuElement(menuElement){menuElement.style.display='none';}}]);}();/**
* A PointerLens shows a magnified view of a {@link Viewer}'s canvas, centered at the position of the
* mouse or touch pointer.
*
* This component is used by {@link DistanceMeasurementsControl} and {@link AngleMeasurementsControl}
* to help position the pointer when snap-to-vertex or snap-toedge is enabled.
*
* [[Run an example](https://xeokit.github.io/xeokit-sdk/examples/measurement/#distance_createWithMouse_snapping)]
*
* ````JavaScript
*
* import {Viewer, XKTLoaderPlugin, AngleMeasurementsPlugin, AngleMeasurementsMouseControl, PointerLens} from "../../dist/xeokit-sdk.es.js";
*
* const viewer = new Viewer({
* canvasId: "myCanvas",
* dtxEnabled: true
* });
*
* viewer.camera.eye = [-3.93, 2.85, 27.01];
* viewer.camera.look = [4.40, 3.72, 8.89];
* viewer.camera.up = [-0.01, 0.99, 0.039];
*
* const xktLoader = new XKTLoaderPlugin(viewer);
*
* const sceneModel = xktLoader.load({
* id: "myModel",
* src: "../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt",
* edges: true
* });
*
* const angleMeasurements = new AngleMeasurementsPlugin(viewer);
*
* const angleMeasurementsMouseControl = new AngleMeasurementsMouseControl(angleMeasurements, {
* pointerLens : new PointerLens(viewer, {
* zoomFactor: 2
* })
* })
*
* angleMeasurementsMouseControl.activate();
* ````
*/var PointerLens=/*#__PURE__*/function(){/**
* Constructs a new PointerLens.
* @param viewer The Viewer
* @param [cfg] PointerLens configuration.
* @param [cfg.active=true] Whether PointerLens is active. The PointerLens can only be shown when this is `true` (default).
*/function PointerLens(viewer){var _this6=this;var cfg=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};_classCallCheck(this,PointerLens);this.viewer=viewer;this.scene=this.viewer.scene;this._lensCursorDiv=document.createElement('div');this._lensParams={canvasSize:300,cursorBorder:2,cursorSize:10};this._lensCursorDiv.style.borderRadius="50%";this._lensCursorDiv.style.width=this._lensParams.cursorSize+"px";this._lensCursorDiv.style.height=this._lensParams.cursorSize+"px";this._lensCursorDiv.style.zIndex="100000";this._lensCursorDiv.style.position="absolute";this._lensCursorDiv.style.pointerEvents="none";this._lensContainer=document.createElement('div');this._lensContainerId=cfg.containerId||'xeokit-lens';this._lensContainer.setAttribute("id",this._lensContainerId);this._lensContainer.style.border="1px solid black";this._lensContainer.style.background="white";// this._lensContainer.style.opacity = "0";
this._lensContainer.style.borderRadius="50%";this._lensContainer.style.width=this._lensParams.canvasSize+"px";this._lensContainer.style.height=this._lensParams.canvasSize+"px";this._lensContainer.style.zIndex="15000";this._lensContainer.style.position="absolute";this._lensContainer.style.pointerEvents="none";this._lensContainer.style.visibility="hidden";this._lensCanvas=document.createElement('canvas');this._lensCanvas.id="".concat(this._lensContainerId,"-canvas");// this._lensCanvas.style.background = "darkblue";
this._lensCanvas.style.borderRadius="50%";this._lensCanvas.style.width=this._lensParams.canvasSize+"px";this._lensCanvas.style.height=this._lensParams.canvasSize+"px";this._lensCanvas.style.zIndex="15000";this._lensCanvas.style.pointerEvents="none";document.body.appendChild(this._lensContainer);this._lensContainer.appendChild(this._lensCanvas);this._lensContainer.appendChild(this._lensCursorDiv);this._lensCanvasContext=this._lensCanvas.getContext('2d');this._canvasElement=this.viewer.scene.canvas.canvas;this._canvasPos=null;this._snappedCanvasPos=null;this._lensPosToggle=cfg.lensPosToggle||true;this._lensPosToggleAmount=cfg.lensPosToggleAmount||85;this._lensPosMarginLeft=cfg.lensPosMarginLeft||85;this._lensPosMarginTop=cfg.lensPosMarginTop||25;this._lensContainer.style.marginTop="".concat(this._lensPosMarginTop,"px");this._lensContainer.style.marginLeft="".concat(this._lensPosMarginLeft,"px");this._zoomLevel=cfg.zoomLevel||2;this._active=cfg.active!==false;this._visible=false;this.snapped=false;this._onViewerRendering=this.viewer.scene.on("rendering",function(){if(_this6._active&&_this6._visible){_this6.update();}});}/**
* Updates this PointerLens.
*/return _createClass(PointerLens,[{key:"update",value:function update(){if(!this._active||!this._visible){return;}if(!this._canvasPos){return;}var lensRect=this._lensContainer.getBoundingClientRect();var canvasRect=this._canvasElement.getBoundingClientRect();var pointerOnLens=this._canvasPos[0]<lensRect.right&&this._canvasPos[0]>lensRect.left&&this._canvasPos[1]<lensRect.bottom&&this._canvasPos[1]>lensRect.top;this._lensContainer.style.marginLeft="".concat(this._lensPosMarginLeft,"px");if(pointerOnLens){if(this._lensPosToggle){this._lensContainer.style.marginTop="".concat(canvasRect.bottom-canvasRect.top-this._lensCanvas.height-this._lensPosToggleAmount,"px");}else{this._lensContainer.style.marginTop="".concat(this._lensPosMarginTop,"px");}this._lensPosToggle=!this._lensPosToggle;}this._lensCanvasContext.clearRect(0,0,this._lensCanvas.width,this._lensCanvas.height);var size=Math.max(this._lensCanvas.width,this._lensCanvas.height)/this._zoomLevel;this._lensCanvasContext.drawImage(this._canvasElement,// source canvas
this._canvasPos[0]-size/2,// source x (zoom center)
this._canvasPos[1]-size/2,// source y (zoom center)
size,// source width
size,// source height
0,// destination x
0,// destination y
this._lensCanvas.width,// destination width
this._lensCanvas.height// destination height
);var middle=this._lensParams.canvasSize/2-this._lensParams.cursorSize/2-this._lensParams.cursorBorder;var deltaX=this._snappedCanvasPos?this._snappedCanvasPos[0]-this._canvasPos[0]:0;var deltaY=this._snappedCanvasPos?this._snappedCanvasPos[1]-this._canvasPos[1]:0;this._lensCursorDiv.style.left="".concat(middle+deltaX*this._zoomLevel,"px");this._lensCursorDiv.style.top="".concat(middle+deltaY*this._zoomLevel,"px");}/**
* Sets the zoom factor for the lens.
*
* This is `2` by default.
*
* @param zoomFactor
*/},{key:"zoomFactor",get:/**
* Gets the zoom factor for the lens.
*
* This is `2` by default.
*
* @returns Number
*/function get(){return this._zoomFactor;}/**
* Sets the canvas central position of the lens.
* @param canvasPos
*/,set:function set(zoomFactor){this._zoomFactor=zoomFactor;this.update();}},{key:"canvasPos",get:/**
* Gets the canvas central position of the lens.
* @returns {Number[]}
*/function get(){return this._canvasPos;}/**
* Sets the canvas coordinates of the pointer.
* @param snappedCanvasPos
*/,set:function set(canvasPos){this._canvasPos=canvasPos;this.update();}},{key:"snappedCanvasPos",get:/**
* Gets the canvas coordinates of the snapped pointer.
* @returns {Number[]}
*/function get(){return this._snappedCanvasPos;}/**
* Sets if the cursor has snapped to anything.
* This is set by plugins.
* @param snapped
* @private
*/,set:function set(snappedCanvasPos){this._snappedCanvasPos=snappedCanvasPos;this.update();}},{key:"snapped",get:/**
* Gets if the cursor has snapped to anything.
* This is called by plugins.
* @returns {Boolean}
* @private
*/function get(){return this._snapped;},set:function set(snapped){this._snapped=snapped;var _ref=snapped?["greenyellow","green"]:["pink","red"],_ref2=_slicedToArray(_ref,2),bg=_ref2[0],border=_ref2[1];this._lensCursorDiv.style.background=bg;this._lensCursorDiv.style.border=this._lensParams.cursorBorder+"px solid "+border;}},{key:"_updateActiveVisible",value:function _updateActiveVisible(){this._lensContainer.style.visibility=this._active&&this._visible?"visible":"hidden";this.update();}/**
* Sets if this PointerLens is active.
* @param active
*/},{key:"active",get:/**
* Gets if this PointerLens is active.
* @returns {Boolean}
*/function get(){return this._active;}/**
* Sets if this PointerLens is visible.
* This is set by plugins.
* @param visible
* @private
*/,set:function set(active){this._active=active;this._updateActiveVisible();}},{key:"visible",get:/**
* Gets if this PointerLens is visible.
* This is called by plugins.
* @returns {Boolean}
* @private
*/function get(){return this._visible;}/**
* Destroys this PointerLens.
*/,set:function set(visible){this._visible=visible;this._updateActiveVisible();}},{key:"destroy",value:function destroy(){if(!this._destroyed){this.viewer.scene.off(this._onViewerRendering);this._lensContainer.removeChild(this._lensCanvas);document.body.removeChild(this._lensContainer);