UNPKG

@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
/** * 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);