@lumiscaphe/viewer 4.1.16 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.cjs +2 -2
- package/dist/lib/index.d.ts +52 -12
- package/dist/lib/index.js +204 -203
- package/package.json +5 -4
package/dist/lib/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(".ls-viewer-container{display:block;position:relative;overflow:hidden;-webkit-user-select:none;user-select:none;width:100%;height:100%}.ls-viewer-container-image,.ls-viewer-container-video{cursor:default;pointer-events:none}.ls-viewer-container-vrcube{cursor:pointer;cursor:grab}.ls-viewer-container-vrcube-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-vrobject{cursor:move;cursor:grab}.ls-viewer-container-vrobject-grabbing{cursor:move;cursor:grabbing}.ls-viewer-container-loading{cursor:progress}.ls-viewer-canvas{position:absolute;opacity:0;transition:opacity .5s}.ls-viewer-video{position:absolute}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
|
|
2
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("debounce-promise"),h=require("twgl.js"),U=require("regression");function N(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const P=N(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,d=(e.width-n)/2;return new w(o,d,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=240?240:t<=360?360:t<=480?480:t<=720?720:1080}}class B{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class X{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=P.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),P.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,d=e-t,u=s+i,p=s-i,c=n-r;return a[0]=2*r/d,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/d,a[9]=u/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class Y{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class W{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class V{constructor(t){this.xmlDoc=t}get id(){return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id")}getCameraId(t,e){return e?this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id"):this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){const e=t.scene,i=e.length>1?e.find(n=>n.accessory):null,s=e.length>1?e.find(n=>n.decor):null,r=e.find(n=>n!==i&&n!==s);return{databaseId:r.database,configuration:r?.configuration,animations:r?.animations?.join("/"),accessoryDatabaseId:i?.database,decorDatabaseId:s?.database,decorDeltaAltitude:s?.translation?.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class k{constructor(t,e,i){switch(e){case"static":this.webrender=new W;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?t.encoder?.format==="mp4"?this.webrender.video(t).then(s=>this.loadVideoFrames(s,t.view.frames,30,i)):this.webrender.animation(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i)):this.webrender.vrObject(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!k.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const d=Math.ceil(a/2)*(a%2===0?1:-1),u=e?g.mod(n+d,o):a;r[u]=this.loadImage(t[u],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const d=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",d);const u=document.createElement("canvas");u.width=t.videoWidth,u.height=t.videoHeight,u.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=u.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",d),t.addEventListener("error",u=>{r===this.loadingId&&o(u)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(o=>!o.decor&&!o.accessory);if(!e)return t;let i=this.databases.find(o=>o.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=t.view.camera?.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const o=i.getCameraGroupId(n);return o?{...t,view:{...t.view,cameraGroup:o}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m)if(t.view.camera){const n=r.getCameraById(t.view.camera);if(!n)return t;const a=new Y(n.pointOfView),o=2*Math.PI/i;a.longitude+=e*o%(2*Math.PI);const d=a.pointOfView(n.pointOfView.target);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const n=r.getCameraGroupById(t.view.cameraGroup);if(!n)return t;const a=n.cameras[e];return a?{...t,view:{...t.view,camera:a.id}}:t}else return t;else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),d=o.length===2?o[0]:void 0,u=o.length===2?o[1]:o[0];r=s.getCameraId(u,d)}else this.webrender instanceof m&&(r=t.view.camera);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class J{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class j{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class D{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Z{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class q{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Z(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class Q{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new q(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new D(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new D(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const d=h.m4.transformPoint(o,this.pov.target),u=h.m4.transformDirection(o,this.pov.up);h.v3.cross(u,[0,0,1])[0]>=0&&(this.pov.target=d,this.pov.up=u),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var _=`precision mediump float;
|
|
2
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("debounce-promise"),h=require("twgl.js"),U=require("regression");function N(l){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const e in l)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(l,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>l[e]})}}return t.default=l,Object.freeze(t)}const P=N(h);class y{constructor(t,e){this.width=t,this.height=e}get aspect(){return this.width/this.height}}class w{constructor(t,e,i,s){this.top=t,this.left=e,this.width=i,this.height=s}static contains(t,e){return e.x>=0&&e.x<t.width&&e.y>=0&&e.y<t.height}static fit(t,e,i){const s=t.aspect,r=e.aspect;let n=0,a=0;switch(i){case"contain":n=r<s?e.width:e.height*s,a=r<s?e.width/s:e.height;break;case"cover":default:n=r<s?e.height*s:e.width,a=r<s?e.height:e.width/s;break;case"fill":n=e.width,a=e.height;break}const o=(e.height-a)/2,u=(e.width-n)/2;return new w(o,u,n,a)}static project(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round(r.left+s.x*n),y:Math.round(r.top+s.y*a)}}static unproject(t,e,i,s){const r=w.fit(t,e,i),n=r.width/t.width,a=r.height/t.height;return{x:Math.round((s.x-r.left)/n),y:Math.round((s.y-r.top)/a)}}static getStandardAspectRatio(t,e){if(t===0||e===0)return 0;const i=t/e;if(t<e){const n=Math.abs(.75-i),a=Math.abs(9/16-i);return n<a?3/4:9/16}const s=Math.abs(4/3-i),r=Math.abs(16/9-i);return s<r?4/3:16/9}static getStandardResolution(t,e){if(t===0||e===0)return new y(0,0);const i=w.getStandardAspectRatio(t,e);if(t<e){const r=w.getStandardQuality(Math.max(e*i,t));return new y(Math.round(r),Math.round(r/i))}const s=w.getStandardQuality(Math.max(t/i,e));return new y(Math.round(s*i),Math.round(s))}static getStandardQuality(t){return t<=720?720:1080}}class B{constructor(t){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=this.element.getContext("2d"),this.backCanvas=document.createElement("canvas"),this.backContext=this.backCanvas.getContext("2d"),this.fit=t,this.pixelRatio=1}destroy(){this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0)}show(t){t?this.element.style.display="block":this.element.style.opacity="1"}hide(t){t?this.element.style.display="none":this.element.style.opacity="0"}get resolution(){return new y(this.element.width/this.pixelRatio,this.element.height/this.pixelRatio)}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`,this.backCanvas.width=t*i,this.backCanvas.height=e*i,this.pixelRatio=i}draw(t,e,i){if(!t)return;this.requestAnimationId&&(cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0);const s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);e?(this.backContext.drawImage(this.element,0,0),this.context.globalAlpha=0,this.fadeLoop(t,i||0)):(this.context.globalAlpha=1,this.context.drawImage(t,s.left,s.top,s.width,s.height)),this.image=t}fadeLoop(t,e){if(this.context.globalAlpha>=1){cancelAnimationFrame(this.requestAnimationId),this.requestAnimationId=void 0;return}const i=Math.min(this.context.globalAlpha+e,1),s=w.fit(new y(t.width,t.height),new y(this.element.width,this.element.height),this.fit);this.context.clearRect(0,0,this.element.width,this.element.height),this.context.globalAlpha=1,this.context.drawImage(this.backCanvas,0,0),this.context.globalAlpha=i,this.context.drawImage(t,s.left,s.top,s.width,s.height),this.requestAnimationId=requestAnimationFrame(()=>{this.fadeLoop(t,e)})}}class X{constructor(){this.element=document.createElement("canvas"),this.element.classList.add("ls-viewer-canvas"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.context=P.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),P.setDefaults({textureColor:[1,1,1,1]})}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i){this.element.width=t*i,this.element.height=e*i,this.element.style.width=`${t}px`,this.element.style.height=`${e}px`}}class g{static accelerate(t,e){const i=e||1.5;return Math.abs(t)**i*(t>0?1:-1)}static clamp(t,e,i){return Math.max(Math.min(t,i),e)}static degreesToRadians(t){return t*(Math.PI/180)}static radiansToDegrees(t){return t*(180/Math.PI)}static mod(t,e){return t-e*Math.floor(t/e)}static perspectiveWithFovX(t,e,i,s,r){const n=Math.tan(t/2),a=n/e;return this.perspectiveWithLeft(-n,n,-a,a,i,s,r)}static perspectiveWithFovY(t,e,i,s,r){const n=i*Math.tan(t/2),a=n*e;return this.perspectiveWithLeft(-a,a,-n,n,i,s,r)}static perspectiveWithLeft(t,e,i,s,r,n,a){a=a||new Float32Array(16);const o=e+t,u=e-t,d=s+i,p=s-i,c=n-r;return a[0]=2*r/u,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=2*r/p,a[6]=0,a[7]=0,a[8]=o/u,a[9]=d/p,a[10]=-n/c,a[11]=-1,a[12]=0,a[13]=0,a[14]=-n*r/c,a[15]=0,a}}const F=class F{static initCubeFace(t,e,i){let s=[0,0,0];const r=h.v3.subtract(e,t),n=h.v3.mulScalar([0,1,0],h.v3.length(r)),a=h.v3.mulScalar(h.v3.normalize(h.v3.cross(r,n)),h.v3.length(r)),o=h.v3.mulScalar(h.v3.normalize(h.v3.cross(n,a)),h.v3.length(r));switch(i){case"front":e=h.v3.add(t,o),s=h.v3.normalize(n);break;case"right":e=h.v3.add(t,a),s=h.v3.normalize(n);break;case"back":e=h.v3.subtract(t,o),s=h.v3.normalize(n);break;case"left":e=h.v3.subtract(t,a),s=h.v3.normalize(n);break;case"up":e=h.v3.add(t,n),s=h.v3.normalize(h.v3.mulScalar(o,-1));break;case"down":e=h.v3.subtract(t,n),s=h.v3.normalize(o);break}return new F(e,t,s)}constructor(t,e,i){this.target=h.v3.copy(t),this.eye=h.v3.copy(e),this.up=h.v3.copy(i)}get viewVector(){return h.v3.subtract(this.target,this.eye)}get rightVector(){return h.v3.normalize(h.v3.cross(this.viewVector,this.up))}get viewMatrix(){return h.m4.inverse(h.m4.lookAt(this.eye,this.target,this.up))}clone(){return new F(h.v3.copy(this.target),h.v3.copy(this.eye),h.v3.copy(this.up))}};F.default=new F([0,0,0],[2,2,2],[0,1,0]);let I=F;class Y{constructor(t){this.target=t.target;const e=h.v3.normalize(h.v3.subtract(t.eye,t.target)),i=h.v3.dot(e,[1,0,0]),s=h.v3.dot(e,[0,1,0]),r=h.v3.dot(e,[0,0,1]);this.longitude=Math.atan2(i,r),this.latitude=Math.atan2(s,Math.sqrt(i*i+r*r)),h.v3.dot(t.up,[0,1,0])<0&&(this.longitude=Math.PI+this.longitude,this.latitude=Math.PI-this.latitude),this.distance=h.v3.length(h.v3.subtract(t.target,t.eye))}get vector(){const t=Math.cos(this.latitude)*this.distance,e=Math.sin(this.latitude)*this.distance,i=Math.cos(this.longitude)*t,s=Math.sin(this.longitude)*t;return[i,e,s]}pointOfView(t){const e=h.m4.rotationY(this.longitude),i=h.m4.rotationX(-this.latitude),s=h.m4.rotationZ(0),r=h.m4.multiply(e,h.m4.multiply(i,s));let n=[0,0,-1];n=h.m4.transformPoint(r,n);let a=[0,1,0];a=h.m4.transformPoint(r,a);const o=h.v3.subtract(t,h.v3.mulScalar(n,this.distance));return new I(t,o,a)}}class W{constructor(){}async animation(t){return t.scene}async database(t){throw new Error("Unavailable")}async image(t){return t.scene}async video(t){return t.scene}async vrCube(t){return t.scene}async vrObject(t){return t.scene}}class V{constructor(t){this.xmlDoc=t}get id(){return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id")}getCameraId(t,e){return e?this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id"):this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id")}getCameraById(t,e){let i;return t&&e?i=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${e}"] Camera[id="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[id="${t}"]`),i?this.mapElementToCamera(i):null}getCameraByName(t,e){let i;return e&&t?i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`):i=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`),i?this.mapElementToCamera(i):null}getCameraGroupId(t){return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id")}getCameraGroupById(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);return e?this.mapElementToCameraGroup(e):null}getCameraGroupByName(t){const e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`);return e?this.mapElementToCameraGroup(e):null}mapElementToCamera(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),pointOfView:new I([parseFloat(t.querySelector("PointOfView Target").getAttribute("x")),parseFloat(t.querySelector("PointOfView Target").getAttribute("y")),parseFloat(t.querySelector("PointOfView Target").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Eye").getAttribute("x")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("y")),parseFloat(t.querySelector("PointOfView Eye").getAttribute("z"))],[parseFloat(t.querySelector("PointOfView Up").getAttribute("x")),parseFloat(t.querySelector("PointOfView Up").getAttribute("y")),parseFloat(t.querySelector("PointOfView Up").getAttribute("z"))])}}mapElementToCameraGroup(t){return{id:t.getAttribute("id"),name:t.getAttribute("name"),cameras:[...t.querySelectorAll("Camera")].map(e=>this.mapElementToCamera(e))}}}const v=class v{constructor(t){this.server=t}static buildQuery(t){return Object.entries(t).filter(([e,i])=>i!=null).map(([e,i])=>`${e}=${i}`).join("&")}static sceneParameters(t){const e=t.scene,i=e.length>1?e.find(n=>n.accessory):null,s=e.length>1?e.find(n=>n.decor):null,r=e.find(n=>n!==i&&n!==s);return{databaseId:r.database,configuration:r?.configuration,animations:r?.animations?.join("/"),accessoryDatabaseId:i?.database,decorDatabaseId:s?.database,decorDeltaAltitude:s?.translation?.y}}static renderParameters(t){const{parameters:e,view:i}=t;return{background:i.background,width:e.width,height:e.height,softwareAntialiasing:e.antialiasing,superSampling:e.superSampling}}static encoderParameters(t){const{encoder:e}=t;return{imageFormat:e.format,imageQuality:e.quality}}static async fetch(t){return fetch(t).then(e=>e.text()).then(e=>{const s=e.replace(/&/g,"&").match(this.xmlRegex);return s?s.map(r=>r.replace(this.xmlRegex,"$1")):Promise.reject()})}async animation(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],frames:t.view.frames,loop:!!t.view.loop,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromAnimation?${i}`)}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImageFromBookmark?${i}`)}async video(t){const e={...v.sceneParameters(t),animation:t.view.animation,bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],duration:t.view.duration,frames:t.view.frames,loop:!!t.view.loop,reverse:!!t.view.reverse,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return Promise.resolve(`${this.server}/ImagesFromAnimation?${i}`)}async vrCube(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera.split("/")[0],bookmark:t.view.camera.split("/")[1],...v.renderParameters(t),...v.encoderParameters(t)};e.width=Math.max(e.width,e.height),e.height=Math.max(e.width,e.height);const i=v.buildQuery(e);return v.fetch(`${this.server}/CubeFromBookmark?${i}`)}async vrObject(t){const e={...v.sceneParameters(t),bookmarkSet:t.view.camera,...v.renderParameters(t),...v.encoderParameters(t)},i=v.buildQuery(e);return v.fetch(`${this.server}/ImagesFromBookmarkSet?${i}`)}};v.xmlRegex=/directUrl="([^"]*)"/g;let S=v;class m{constructor(t){this.server=t}static scene(t){return t.scene.map(e=>{const{accessory:i,decor:s,...r}=e;return r})}static renderParameters(t){return{...t.parameters,superSampling:t.parameters.superSampling.toString()}}static encoder(t){switch(t.encoder.format){case"jpeg":return{jpeg:{quality:t.encoder.quality}};case"png":return{png:{compression:t.encoder.compression}};case"webp":return{webp:{quality:t.encoder.quality}}}return{jpeg:{quality:80}}}static async fetchFrame(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.url)}static async fetchFrameArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i.map(s=>s.url))}static async fetchHotspots(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchHotspotsArray(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json())}static async fetchPick(t,e){return fetch(t,{method:"POST",body:JSON.stringify(e)}).then(i=>i.json()).then(i=>i[0])}async database(t){return fetch(`${this.server}/Database?databaseId=${t}`).then(e=>e.text()).then(e=>{const i=new DOMParser().parseFromString(e,"application/xml");return new V(i)})}async image(t){const e={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrame(`${this.server}/Snapshot`,e)}async vrCube(t){const e={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return e.renderParameters.width=Math.max(e.renderParameters.width,e.renderParameters.height),e.renderParameters.height=Math.max(e.renderParameters.width,e.renderParameters.height),m.fetchFrameArray(`${this.server}/Snapshot`,e)}async vrObject(t){let e;t.view.cameraGroup?e={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?e={vrObject:{camera:t.view.camera,frames:t.view.frames}}:e={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const i={scene:m.scene(t),mode:e,renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,i)}async animation(t){const e={scene:m.scene(t),mode:{animation:{id:t.view.animation,camera:t.view.camera,fps:t.view.fps}},renderParameters:m.renderParameters(t),encoder:m.encoder(t)};return m.fetchFrameArray(`${this.server}/Snapshot`,e)}async imageHotspots(t,e){const i={scene:m.scene(t),mode:{image:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspots(`${this.server}/Hotspot`,i)}async imagePick(t,e){const i={scene:m.scene(t),camera:t.view.camera,renderParameters:m.renderParameters(t),positions:[e]};return await m.fetchPick(`${this.server}/Pick`,i)}async vrCubeHotspots(t,e){const i={scene:m.scene(t),mode:{vrCube:{camera:t.view.camera}},renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return i.renderParameters.width=Math.max(i.renderParameters.width,i.renderParameters.height),i.renderParameters.height=Math.max(i.renderParameters.width,i.renderParameters.height),await m.fetchHotspotsArray(`${this.server}/Hotspot`,i)}async vrObjectHotspots(t,e){let i;t.view.cameraGroup?i={images:{cameraGroup:t.view.cameraGroup}}:t.view.frames?i={vrObject:{camera:t.view.camera,frames:t.view.frames}}:i={vrObject:{camera:t.view.camera,panFrames:t.view.panFrames||1,panFrom:t.view.panFrom||0,panTo:t.view.panTo||0,panLoop:t.view.panLoop||!1,tiltFrames:t.view.tiltFrames||1,tiltFrom:t.view.tiltFrom||0,tiltTo:t.view.tiltTo||0,tiltLoop:t.view.tiltLoop||!1}};const s={scene:m.scene(t),mode:i,renderParameters:m.renderParameters(t),...this.hotspotsBody(e)};return await m.fetchHotspotsArray(`${this.server}/Hotspot`,s)}hotspotsBody(t){return{positions:t.every(e=>typeof e!="string")?t:void 0,tags:t.every(e=>typeof e=="string")?t:void 0}}}class C{constructor(t,e,i){switch(e){case"static":this.webrender=new W;break;case"v1":this.webrender=new S(t),this.webrenderV2=new m(t);break;case"v2":this.webrender=new m(t),this.webrenderV2=new m(t);break;default:this.webrender=new S(t),this.webrenderV2=new m(t);break}this.delegate=i,this.loadingId=0,this.loaded=0,this.total=0,this.databases=[],this.onLoadStart=i&&i.onLoadStart?i.onLoadStart:()=>{},this.onLoadProgress=i&&i.onLoadProgress?i.onLoadProgress:()=>{},this.onLoadEnd=i&&i.onLoadEnd?i.onLoadEnd:()=>{}}get progress(){return this.total?this.loaded/this.total:0}async loadImageSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.image(t).then(i=>this.loadImage(i,e)).then(i=>(this.onLoadEnd(this.progress),i))}async loadVideoSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=1,this.onLoadStart(this.progress);const{loadingId:i}=this;return this.webrender.video(e).then(s=>this.loadVideo(t,s,!!e.view.loop,i)).then(()=>(this.onLoadEnd(this.progress),t))}async loadVRCubeSnapshot(t){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:e}=this;return this.webrender.vrCube(t).then(i=>{this.total=i.length;const s=i.map(r=>this.loadImage(r,e));return Promise.all(s)}).then(i=>(this.onLoadEnd(this.progress),i))}async loadVRObjectSnapshot(t,e){this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?t.encoder?.format==="mp4"?this.webrender.video(t).then(s=>this.loadVideoFrames(s,t.view.frames,30,i)):this.webrender.animation(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i)):this.webrender.vrObject(t).then(s=>this.loadImageFrames(s,t.view.loop,e,i))}async loadImage(t,e){const i=new Image;i.crossOrigin=location.protocol==="file:"&&!C.isValidHttpUrl(t)?null:"anonymous";const s=new Promise((r,n)=>{i.addEventListener("load",()=>{e===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),r(i))},{once:!0}),i.addEventListener("error",a=>{e===this.loadingId&&n(`${a.type} : ${t}`)},{once:!0})});return i.src=t,s}loadImageFrames(t,e,i,s){this.total=t.length;const r=new Array(t.length),n=i||0;for(let a=0,o=t.length;a<o;a+=1){const u=Math.ceil(a/2)*(a%2===0?1:-1),d=e?g.mod(n+u,o):a;r[d]=this.loadImage(t[d],s)}return Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadVideo(t,e,i,s){t.loop=i;const r=new Promise((n,a)=>{t.addEventListener("canplaythrough",()=>{s===this.loadingId&&(this.loaded+=1,this.onLoadProgress(this.progress),n())},{once:!0}),t.addEventListener("error",o=>{s===this.loadingId&&a(`${o.type} : ${e}`)},{once:!0})});return t.src=e,t.load(),r}async loadVideoFrame(t,e,i,s,r){let n=0;return new Promise((a,o)=>{const u=()=>{if(r!==this.loadingId)return;if(n!==s){n+=1;return}t.removeEventListener("seeked",u);const d=document.createElement("canvas");d.width=t.videoWidth,d.height=t.videoHeight,d.getContext("2d").drawImage(t,0,0);const c=new Image;c.src=d.toDataURL(),a(c),this.loaded+=1,this.onLoadProgress(this.progress),s!==i-1&&(t.currentTime+=1/e)};t.addEventListener("seeked",u),t.addEventListener("error",d=>{r===this.loadingId&&o(d)},{once:!0})})}loadVideoFrames(t,e,i,s){this.total=e;const r=new Array(e),n=document.createElement("video");for(let a=0,o=e;a<o;a+=1)r[a]=this.loadVideoFrame(n,i,e,a,s);return n.addEventListener("canplaythrough",()=>{s===this.loadingId&&(n.currentTime=1/i/2)},{once:!0}),n.src=t,n.load(),Promise.all(r).then(()=>this.onLoadEnd(this.progress)).catch(()=>{}),r}async loadImageHotspots(t,e){return this.webrenderV2?await this.webrenderV2.imageHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRCubeHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrCubeHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadVRObjectHotspots(t,e){return this.webrenderV2?await this.webrenderV2.vrObjectHotspots(await this.convert(t),e):Promise.reject(new Error("Hotspots only available with api V2"))}async loadImagePick(t,e){return this.webrenderV2?await this.webrenderV2.imagePick(await this.convert(t),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRObjectPick(t,e,i,s){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrObjectFrameSnapshot(t,i,s),e):Promise.reject(new Error("Picking only available with api V2"))}async loadVRCubePick(t,e,i){return this.webrenderV2?await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t,i),e):Promise.reject(new Error("Picking only available with api V2"))}async convert(t){if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(o=>!o.decor&&!o.accessory);if(!e)return t;let i=this.databases.find(o=>o.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=t.view.camera.split("/"),r=s.length===2?s[0]:void 0,n=s.length===2?s[1]:s[0],a=i.getCameraId(n,r);if(a)return{...t,view:{...t.view,camera:a}};{const o=i.getCameraGroupId(n);return o?{...t,view:{...t.view,cameraGroup:o}}:t}}async vrObjectFrameSnapshot(t,e,i){if(!this.webrenderV2)return t;const s=t.scene.find(n=>!n.decor&&!n.accessory);if(!s)return t;let r=this.databases.find(n=>n.id===s.database);if(r||(r=await this.webrender.database(s.database),this.databases.push(r)),this.webrender instanceof S){if(!t.view.camera)return t;const n=r.getCameraGroupId(t.view.camera);if(!n)return t;const a=r.getCameraGroupById(n);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else if(this.webrender instanceof m){const n=typeof t.view.camera=="string"?t.view.camera:t.view.camera?.id;if(n){const a=r.getCameraById(n);if(!a)return t;const o=new Y(a.pointOfView),u=2*Math.PI/i;o.longitude+=e*u%(2*Math.PI);const d=o.pointOfView(a.pointOfView.target);return{...t,view:{...t.view,camera:{id:a.id,pov:{target:{x:d.target[0],y:d.target[1],z:d.target[2]},eye:{x:d.eye[0],y:d.eye[1],z:d.eye[2]},up:{x:d.up[0],y:d.up[1],z:d.up[2]}}}}}}else if(t.view.cameraGroup){const a=r.getCameraGroupById(t.view.cameraGroup);if(!a)return t;const o=a.cameras[e];return o?{...t,view:{...t.view,camera:o.id}}:t}else return t}else return t}async vrCubeFrameSnapshot(t,e){const i=t.scene.find(o=>!o.decor&&!o.accessory);if(!i)return t;let s=this.databases.find(o=>o.id===i.database);if(s||(s=await this.webrender.database(i.database),this.databases.push(s)),!t.view.camera)return t;let r;if(this.webrender instanceof S){const o=t.view.camera.split("/"),u=o.length===2?o[0]:void 0,d=o.length===2?o[1]:o[0];r=s.getCameraId(d,u)}else this.webrender instanceof m&&(r=typeof t.view.camera=="string"?t.view.camera:t.view.camera.id);if(!r)return t;const n=s.getCameraById(r);if(!n)return t;const a=I.initCubeFace(n.pointOfView.eye,n.pointOfView.target,e);return{...t,view:{...t.view,camera:{id:n.id,pov:{target:{x:a.target[0],y:a.target[1],z:a.target[2]},eye:{x:a.eye[0],y:a.eye[1],z:a.eye[2]},up:{x:a.up[0],y:a.up[1],z:a.up[2]}},lens:{fov:90}}},parameters:{...t.parameters,width:Math.max(t.parameters.width,t.parameters.height),height:Math.max(t.parameters.width,t.parameters.height)}}}onLoadStart(t){this.delegate&&this.delegate.onLoadStart(t)}onLoadProgress(t){this.delegate&&this.delegate.onLoadProgress(t)}onLoadEnd(t){this.delegate&&this.delegate.onLoadEnd(t)}static isValidHttpUrl(t){let e;try{e=new URL(t)}catch{return!1}return e.protocol==="http:"||e.protocol==="https:"}}class J{constructor(){this.element=document.createElement("video"),this.element.classList.add("ls-viewer-video"),this.element.style.opacity="0",this.element.width=0,this.element.height=0,this.element.setAttribute("muted",""),this.element.setAttribute("playsinline",""),this.element.setAttribute("preload","auto")}show(){this.element.style.opacity="1"}hide(){this.element.style.opacity="0"}resize(t,e,i,s){const r=w.fit(i,new y(t,e),s);this.element.style.top=`${r.top}px`,this.element.style.left=`${r.left}px`,this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,(i.width!==this.element.width||i.height!==this.element.height)&&(this.element.width=i.width,this.element.height=i.height)}}class j{constructor(t,e,i){this.container=t,this.canvas=e,this.loader=i,this.hotspotList=[]}destroy(){}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-image")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-image")}async load(t,e,i,s){let r=Promise.resolve();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):r=r.then(()=>this.loader.loadImageSnapshot(t).then(o=>{this.canvas.draw(o,s,.05),this.image=o}));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadImageHotspots(t,e).then(o=>{this.hotspotList=o})):this.hotspotList=[]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadImagePick(t,s)}hotspots(t){return this.hotspotList.map(e=>({...e,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,e.position2D)})).map(e=>({...e,visibility:w.contains(this.canvas.resolution,e.position2D)?e.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class E{constructor(t,e){this.x=t,this.y=e}clone(){return new E(this.x,this.y)}}class f{static pointFromMouseEvent(t){return new E(t.screenX,t.screenY)}static pointFromTouchEvent(t){const e=t.targetTouches[0]||t.changedTouches[0];return new E(e.screenX,e.screenY)}}class D{constructor(...t){t.length===3?({0:this.u,1:this.v,2:this.o}=t,this.w=h.v3.cross(this.u,this.v)):t.length===4?{0:this.u,1:this.v,2:this.w,3:this.o}=t:(this.u=[1,0,0],this.v=[0,1,0],this.w=[0,0,1],this.o=[0,0,0])}get localToGlobalMatrix(){const t=[this.u[0],this.u[1],this.u[2],0],e=[this.v[0],this.v[1],this.v[2],0],i=[this.w[0],this.w[1],this.w[2],0],s=[this.o[0],this.o[1],this.o[2],1];return[...t,...e,...i,...s]}get globalToLocalMatrix(){return h.m4.inverse(this.localToGlobalMatrix)}}class Z{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class q{constructor(t){this.points=[],this.onMotion=t,this.lastPoint=new E(0,0),this.velocity=new E(0,0),this.loop=this.loop.bind(this)}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}track(t){const e=Date.now();this.points=this.points.filter(i=>e-i.time<=100),this.points.push(new Z(t.x,t.y,e)),this.lastPoint=t}start(){if(this.points.length===0)return;const t=this.points[0],e=this.points[this.points.length-1],i=e.x-t.x,s=e.y-t.y,r=e.time-t.time;this.velocity=new E(r===0?0:i/(r/15),r===0?0:s/(r/15)),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.animationFrameId=requestAnimationFrame(this.loop)}stop(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0),this.points=[]}loop(){if(Math.abs(this.velocity.x)<1&&Math.abs(this.velocity.y)<1){this.animationFrameId=void 0,this.points=[];return}this.lastPoint.x+=this.velocity.x,this.lastPoint.y+=this.velocity.y,this.velocity.x*=.9,this.velocity.y*=.9,this.onMotion(this.lastPoint.clone()),this.animationFrameId=requestAnimationFrame(this.loop)}}class Q{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new q(this.motion.bind(this)),this.onMotion=i,this.initPov=this.pov,this.initFov=this.fov,this.initOrientation=g.degreesToRadians(window.orientation)||0,this.startPov=new I([0,0,1],[0,0,0],[0,1,0]),this.startSize={width:0,height:0},this.previousPoint=new E(0,0)}destroy(){this.inertia.destroy()}get orientedPov(){const t=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),e=new D(t,[0,1,0],this.pov.eye),i=h.m4.identity();h.m4.multiply(i,e.localToGlobalMatrix,i),h.m4.multiply(i,this.orientationMatrix,i),h.m4.multiply(i,e.globalToLocalMatrix,i);const s=h.m4.transformDirection(i,this.pov.target),r=this.pov.eye,n=h.m4.transformDirection(i,this.pov.up);return new I(s,r,n)}reset(){this.pov=this.initPov.clone(),this.fov=this.initFov}start(t,e){this.isStarted=!0,this.startPov=this.pov,this.startSize=e,this.previousPoint=t,this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t);const e={x:t.x-this.previousPoint.x,y:t.y-this.previousPoint.y},i=g.accelerate(e.x,1.3)/this.startSize.width*.2*Math.PI*1.5,s=g.accelerate(e.y,1.3)/this.startSize.height*.2*Math.PI,r=h.m4.multiply(h.m4.rotationY(i),h.m4.rotationX(-s)),n=h.v3.normalize(h.v3.cross(this.pov.up,this.pov.target)),a=new D(n,[0,1,0],this.pov.eye),o=h.m4.identity();h.m4.multiply(o,a.localToGlobalMatrix,o),h.m4.multiply(o,r,o),h.m4.multiply(o,a.globalToLocalMatrix,o);const u=h.m4.transformPoint(o,this.pov.target),d=h.m4.transformDirection(o,this.pov.up);h.v3.cross(d,[0,0,1])[0]>=0&&(this.pov.target=u,this.pov.up=d),this.previousPoint=t,this.onMotion()}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}orientation(t,e,i){const s=g.degreesToRadians(window.orientation)||0,r=g.degreesToRadians(t),n=g.degreesToRadians(-e),a=g.degreesToRadians(-i),o=h.m4.rotationX(g.degreesToRadians(90));h.m4.rotateZ(o,this.initOrientation,o),h.m4.rotateZ(o,r,o),h.m4.rotateX(o,n,o),h.m4.rotateY(o,a,o),h.m4.rotateZ(o,-s,o),this.orientationMatrix=o,this.onMotion()}}var _=`precision mediump float;
|
|
3
3
|
|
|
4
4
|
uniform float u_mix;
|
|
5
5
|
uniform samplerCube u_texture;
|
|
@@ -22,4 +22,4 @@ void main() {
|
|
|
22
22
|
gl_Position = position;
|
|
23
23
|
}`;class H{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.hotspotsList=[[]];const r=new I([0,0,1],[0,0,0],[0,1,0]),n=60,a=h.m4.rotationX(g.degreesToRadians(15));h.m4.transformDirection(a,r.target,r.target),h.m4.transformDirection(a,r.up,r.up),this.interaction=new Q(r,n,()=>{this.animationFrameId=requestAnimationFrame(this.render),this.onInteraction({pov:this.interaction.pov.clone(),fov:this.interaction.fov})}),this.onInteraction=s,this.gl=this.canvas.context,this.programInfo=P.createProgramInfo(this.gl,[`${K}
|
|
24
24
|
`,`${_}
|
|
25
|
-
`]),this.quad=P.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(d,u)=>{d||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=u,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,d=[a,o,0],u=this.modelViewProjectionMatrix,p=h.m4.inverse(u),c=h.v3.normalize(h.m4.transformPoint(p,d)),A=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===A?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===A?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let b=0,x=0,M="";switch(L){case"XPOS":b=(-c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":b=(c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":b=(c[0]/Math.abs(c[1])+1)/2,x=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":b=(c[0]/Math.abs(c[1])+1)/2,x=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":b=(c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":b=(-c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(b*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(x*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){const t=[];if(this.hotspotsList.length===0)return[];const e=this.hotspotsList[0]?.length??0,i=this.modelViewProjectionMatrix;for(let s=0;s<e;s++){const r=this.hotspotsList.findIndex($=>$[s].visibility!=="OutOfFrustum");if(r===-1)continue;const n={...this.hotspotsList[r][s]},a=n.position2D.x/this.images[0].width,o=n.position2D.y/this.images[0].height;let d=0,u=0,p=0;switch(r){case 0:this.pov.target[2]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1-2*o,p=1;break;case 1:this.pov.target[0]>0&&(n.visibility="OutOfFrustum"),d=1,u=1-2*o,p=1-2*a;break;case 2:this.pov.target[2]>0&&(n.visibility="OutOfFrustum"),d=1-2*a,u=1-2*o,p=-1;break;case 3:this.pov.target[0]<0&&(n.visibility="OutOfFrustum"),d=-1,u=1-2*o,p=2*a-1;break;case 4:this.pov.target[1]<0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=1,p=2*o-1;break;case 5:this.pov.target[1]>0&&(n.visibility="OutOfFrustum"),d=2*a-1,u=-1,p=1-2*o;break}const c=h.v3.normalize([d,u,p]),A=h.m4.transformPoint(i,c),L=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,x=.5*L*(A[0]+1),M=.5*b*(A[1]+1),T={x:Math.round(x),y:Math.round(b-M)},R=new y(L,b),z=w.contains(R,T)?n.visibility:"OutOfFrustum";t.push({...n,position2D:T,visibility:z})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,d=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,d),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),P.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),P.setUniforms(this.programInfo,this.uniforms),P.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class tt{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new q(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=U.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class O{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new tt({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const d=o.length;return this.images=new Array(d),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=d/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((u,p)=>{u.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class G{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class et{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=C(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new B(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new X,this.container.prepend(this.canvas3D.element),this.video=new J,this.container.prepend(this.video.element),this.loader=new k(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new j(t,this.canvas2D,this.loader),this.widgetVideo=new G(t,this.video,this.loader),this.widgetVRObject=new O(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new H(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=C(this.loadWidget,10),this.onResize=C(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof O&&e?.toPosition!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return e.view?.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){switch(this.view?.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=et;exports.WidgetImage=j;exports.WidgetVRCube=H;exports.WidgetVRObject=O;exports.WidgetVideo=G;
|
|
25
|
+
`]),this.quad=P.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1})},this.render=this.render.bind(this)}destroy(){this.interaction.destroy(),this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(),this.container.classList.add("ls-viewer-container-vrcube")}hide(){this.canvas.hide(),this.container.classList.remove("ls-viewer-container-vrcube")}get pov(){return this.interaction.pov}set pov(t){this.interaction.pov.eye.every((e,i)=>e===t.eye[i])&&this.interaction.pov.target.every((e,i)=>e===t.target[i])&&this.interaction.pov.up.every((e,i)=>e===t.up[i])||(this.interaction.pov=t.clone(),this.animationFrameId=requestAnimationFrame(this.render))}get fov(){return g.radiansToDegrees(this.interaction.fov)}set fov(t){this.interaction.fov!==t&&(this.interaction.fov=g.degreesToRadians(t),this.animationFrameId=requestAnimationFrame(this.render))}async load(t,e,i,s){let r=Promise.resolve();{const o=this.gl.getExtension("WEBGL_debug_renderer_info");o&&navigator.platform==="MacIntel"&&navigator.userAgent.includes("Chrome")&&this.gl.getParameter(o.UNMASKED_RENDERER_WEBGL).includes("OpenGL")&&(t.parameters.width=Math.min(t.parameters.width,1812),t.parameters.height=Math.min(t.parameters.height,1812))}const n=JSON.stringify(t);n===this.snapshotHash?r=r.then(()=>(this.animationFrameId=requestAnimationFrame(this.render),Promise.resolve())):(this.images=[],this.animationFrameId=requestAnimationFrame(this.render),r=r.then(()=>this.loader.loadVRCubeSnapshot(t).then(o=>{this.images=o,P.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,min:this.gl.LINEAR_MIPMAP_LINEAR,minMag:this.gl.LINEAR,cubeFaceOrder:[this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,this.gl.TEXTURE_CUBE_MAP_POSITIVE_X,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],src:o},(u,d)=>{u||(i&&this.interaction.reset(),this.uniforms.u_mix=s?0:1,this.uniforms.u_texture_back=this.uniforms.u_texture,this.uniforms.u_texture=d,this.animationFrameId=requestAnimationFrame(this.render))})})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRCubeHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=this.canvas.element.clientWidth,s=this.canvas.element.clientHeight,r=e.x,n=s-e.y,a=2*r/i-1,o=2*n/s-1,u=[a,o,0],d=this.modelViewProjectionMatrix,p=h.m4.inverse(d),c=h.v3.normalize(h.m4.transformPoint(p,u)),A=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===A?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===A?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let b=0,x=0,M="";switch(L){case"XPOS":b=(-c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":b=(c[2]/Math.abs(c[0])+1)/2,x=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":b=(c[0]/Math.abs(c[1])+1)/2,x=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":b=(c[0]/Math.abs(c[1])+1)/2,x=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":b=(c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":b=(-c[0]/Math.abs(c[2])+1)/2,x=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(b*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(x*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){const t=[];if(this.hotspotsList.length===0)return[];const e=this.hotspotsList[0]?.length??0,i=this.modelViewProjectionMatrix;for(let s=0;s<e;s++){const r=this.hotspotsList.findIndex($=>$[s].visibility!=="OutOfFrustum");if(r===-1)continue;const n={...this.hotspotsList[r][s]},a=n.position2D.x/this.images[0].width,o=n.position2D.y/this.images[0].height;let u=0,d=0,p=0;switch(r){case 0:this.pov.target[2]<0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=1-2*o,p=1;break;case 1:this.pov.target[0]>0&&(n.visibility="OutOfFrustum"),u=1,d=1-2*o,p=1-2*a;break;case 2:this.pov.target[2]>0&&(n.visibility="OutOfFrustum"),u=1-2*a,d=1-2*o,p=-1;break;case 3:this.pov.target[0]<0&&(n.visibility="OutOfFrustum"),u=-1,d=1-2*o,p=2*a-1;break;case 4:this.pov.target[1]<0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=1,p=2*o-1;break;case 5:this.pov.target[1]>0&&(n.visibility="OutOfFrustum"),u=2*a-1,d=-1,p=1-2*o;break}const c=h.v3.normalize([u,d,p]),A=h.m4.transformPoint(i,c),L=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,x=.5*L*(A[0]+1),M=.5*b*(A[1]+1),T={x:Math.round(x),y:Math.round(b-M)},R=new y(L,b),z=w.contains(R,T)?n.visibility:"OutOfFrustum";t.push({...n,position2D:T,visibility:z})}return t}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}get modelViewProjectionMatrix(){const t=this.canvas.element.clientWidth,e=this.canvas.element.clientHeight,i=t>e?t/e:e/t,s=w.getStandardAspectRatio(t,e),r=this.interaction.fov*(s/i),n=h.m4.setAxis(h.m4.identity(),[-1,0,0],0),a=t>e?g.perspectiveWithFovY(r,t/e,.5,100):g.perspectiveWithFovX(r,t/e,.5,100),o=this.interaction.orientedPov,u=h.m4.inverse(h.m4.lookAt(o.eye,o.target,o.up));return h.m4.multiply(h.m4.multiply(a,u),n)}render(){this.gl.viewport(0,0,this.gl.canvas.width,this.gl.canvas.height),this.uniforms.u_mvpi=h.m4.inverse(this.modelViewProjectionMatrix),this.gl.useProgram(this.programInfo.program),P.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),P.setUniforms(this.programInfo,this.uniforms),P.drawBufferInfo(this.gl,this.quad),this.uniforms.u_mix<1&&(this.uniforms.u_mix=Math.min(this.uniforms.u_mix+.05,1),this.animationFrameId=requestAnimationFrame(this.render))}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrcube-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.gl.canvas.width,height:this.gl.canvas.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrcube-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){this.interaction.orientation(t.alpha,t.beta,t.gamma)}}class tt{constructor(t,e,i,s,r){this.isStarted=!1,this.position=t,this.frames=e,this.rows=i,this.loop=s,this.onMotion=r,this.inertia=new q(this.motion.bind(this)),this.initPosition={...this.position},this.startPosition={x:0,y:0},this.startPoint=new E(0,0),this.startSize={width:0,height:0},this.lastPoints=[],this.lastPointsNumber=20}destroy(){this.inertia.destroy()}reset(){this.position={...this.initPosition}}get positionIndex(){return this.frames*this.position.y+this.position.x}set positionIndex(t){if(this.positionIndex===t)return;const e=this.loop?g.mod(t,this.frames*this.rows):Math.max(0,Math.min(t,this.frames*this.rows));this.position.x=g.mod(e,this.frames),this.position.y=Math.floor(e/this.frames)}start(t,e){this.isStarted=!0,this.startPosition={...this.position},this.startPoint=t,this.startSize=e,this.lastPoints=[],this.inertia.stop()}motion(t){this.isStarted&&this.inertia.track(t),this.lastPoints.push({x:t.x,y:t.y}),this.lastPoints.splice(0,this.lastPoints.length-this.lastPointsNumber);const e=U.linear(this.lastPoints.map(s=>[s.x,s.y])),i=25;if(Math.abs(e.equation[0])<1){const s=g.accelerate(t.x-this.startPoint.x,1.3)/this.startSize.width*(this.frames/4);let r=this.startPosition.x-Math.round(s);r=this.loop?g.mod(r,this.frames):Math.max(0,Math.min(r,this.frames-1)),r!==this.position.x&&(this.position.x=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.x));Math.max(...this.lastPoints.map(o=>o.x))-n>i&&(this.startPoint.y=t.y,this.startPosition.y=this.position.y)}else{const s=g.accelerate(t.y-this.startPoint.y,1.7)/this.startSize.height*(this.rows/4);let r=this.startPosition.y+Math.round(s);r=Math.max(0,Math.min(r,this.rows-1)),r!==this.position.y&&(this.position.y=r,this.onMotion());const n=Math.min(...this.lastPoints.map(o=>o.y));Math.max(...this.lastPoints.map(o=>o.y))-n>i&&(this.startPoint.x=t.x,this.startPosition.x=this.position.x)}}end(t,e){this.isStarted=!1,e&&(this.inertia.track(t),this.inertia.start())}}class O{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new tt({x:0,y:0},1,1,!1,()=>{this.canvas.draw(this.image,!0,.5),this.onInteraction({position:this.interaction.positionIndex})}),this.onInteraction=s}destroy(){this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=void 0)}show(){this.canvas.show(!1),this.container.classList.add("ls-viewer-container-vrobject")}hide(){this.canvas.hide(!1),this.container.classList.remove("ls-viewer-container-vrobject")}async goto(t){return new Promise(e=>{let i=this.interaction.positionIndex;const s=()=>{if(this.interaction.positionIndex===t)e();else{let r=i>t?-1:1;this.interaction.loop&&this.interaction.frames-i+t<Math.abs(t-i)&&(r*=-1),i+=.5*r,this.position=Math.floor(i),this.animationFrameId=requestAnimationFrame(s)}};this.animationFrameId=requestAnimationFrame(s)})}get position(){return this.interaction.positionIndex}set position(t){this.interaction.positionIndex=t,this.canvas.draw(this.image,!0,.5)}get image(){return this.images[this.interaction.positionIndex]}async load(t,e,i,s){let r=Promise.resolve();i&&this.interaction.reset();const n=JSON.stringify(t);n===this.snapshotHash&&this.image?r=r.then(()=>this.canvas.draw(this.image,s,.05)):(this.images=[],r=r.then(()=>this.loader.loadVRObjectSnapshot(t,this.interaction.positionIndex).then(o=>{const u=o.length;return this.images=new Array(u),this.interaction.frames=t.view.frames??t.view.panFrames??this.frames,this.interaction.rows=u/this.interaction.frames,this.interaction.loop=!!t.view.loop,i&&this.interaction.reset(),o.forEach((d,p)=>{d.then(c=>{this.images[p]=c,c===this.image&&this.canvas.draw(this.image,s,.05)}).catch(()=>{})}),o[this.interaction.positionIndex].then(()=>Promise.resolve())})));const a=JSON.stringify(e);return(n!==this.snapshotHash||a!==this.hotspotsHash)&&(e.length?r=r.then(()=>this.loader.loadVRObjectHotspots(t,e).then(o=>{this.hotspotsList=o})):this.hotspotsList=[[]]),this.hotspotsHash=a,this.snapshotHash=n,r}async pick(t,e){const i=new y(t.parameters.width,t.parameters.height),s=w.unproject(i,this.canvas.resolution,this.canvas.fit,e);return this.loader.loadVRObjectPick(t,s,this.position,this.frames)}hotspots(t){return(this.hotspotsList[this.interaction.positionIndex]||[]).map(i=>({...i,position2D:w.project(t,this.canvas.resolution,this.canvas.fit,i.position2D)})).map(i=>({...i,visibility:w.contains(this.canvas.resolution,i.position2D)?i.visibility:"OutOfFrustum"}))}snapshot(t,e){return this.canvas.element.toDataURL(t,e)}onMouseDown(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromMouseEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onMouseMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromMouseEvent(t)),t.preventDefault())}onMouseUp(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!0))}onMouseEnter(t){this.interaction.isStarted&&t.buttons===0&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromMouseEvent(t),!1))}onTouchStart(t){this.container.classList.add("ls-viewer-container-vrobject-grabbing"),this.interaction.start(f.pointFromTouchEvent(t),{width:this.canvas.element.width,height:this.canvas.element.height})}onTouchMove(t){this.interaction.isStarted&&(this.interaction.motion(f.pointFromTouchEvent(t)),t.preventDefault())}onTouchEnd(t){this.interaction.isStarted&&(this.container.classList.remove("ls-viewer-container-vrobject-grabbing"),this.interaction.end(f.pointFromTouchEvent(t),!0))}onDeviceOrientation(t){}}class G{constructor(t,e,i){this.container=t,this.loader=i,this.video=e}destroy(){}show(){this.video.show(),this.container.classList.add("ls-viewer-container-video")}hide(){this.video.hide(),this.container.classList.remove("ls-viewer-container-video")}async load(t){const e=JSON.stringify(t);return e===this.hash?(this.video.element.load(),Promise.resolve()):(this.hash=e,this.loader.loadVideoSnapshot(this.video.element,t))}async pick(t,e){return Promise.reject()}hotspots(t){return[]}snapshot(t,e){return"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="}async play(){return new Promise((t,e)=>{this.video.element.addEventListener("ended",()=>{t()},{once:!0}),this.video.element.play().catch(e),this.show()})}onMouseDown(t){}onMouseMove(t){}onMouseUp(t){}onMouseEnter(t){}onTouchStart(t){}onTouchMove(t){}onTouchEnd(t){}onDeviceOrientation(t){}}class et{constructor(t,e){this.checkResize=this.checkResize.bind(this),this.onDeviceOrientation=this.onDeviceOrientation.bind(this),this.onResize=this.onResize.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseEnter=this.onMouseEnter.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this),this.onLoadStart=this.onLoadStart.bind(this),this.onLoadProgress=this.onLoadProgress.bind(this),this.onLoadEnd=this.onLoadEnd.bind(this),this.onLoadError=this.onLoadError.bind(this),this.onHotspotsChange=this.onHotspotsChange.bind(this),this.onVrcubeInteraction=this.onVrcubeInteraction.bind(this),this.onVrobjectInteraction=this.onVrobjectInteraction.bind(this),this.options={server:"localhost",api:"v1",autores:!0,fit:"cover",image:{},video:{},vrcube:{},vrobject:{},events:{},...e},this.options.events={onLoadStart:()=>{},onLoadProgress:()=>{},onLoadEnd:()=>{},onLoadError:()=>{},onInteraction:()=>{},onVrcubeInteraction:()=>{},onVrobjectInteraction:()=>{},onHotspotsChange:()=>{},...e.events},this.options.events.onLoadError=k(this.options.events.onLoadError,10),this.container=t,this.container.classList.add("ls-viewer-container"),this.containerWidth=0,this.containerHeight=0,this.canvas2D=new B(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new X,this.container.prepend(this.canvas3D.element),this.video=new J,this.container.prepend(this.video.element),this.loader=new C(this.options.server,this.options.api,this),this.resolution=new y(0,0),this.parameters={width:0,height:0,antialiasing:!1,superSampling:2},this.encoder={format:"jpeg",quality:80},this.hotspots=[],this.widgetImage=new j(t,this.canvas2D,this.loader),this.widgetVideo=new G(t,this.video,this.loader),this.widgetVRObject=new O(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new H(t,this.canvas3D,this.loader,this.onVrcubeInteraction)),this.widget=this.widgetImage,this.isDestroyed=!1,this.container.addEventListener("mousedown",this.onMouseDown),this.container.addEventListener("mouseenter",this.onMouseEnter),this.container.addEventListener("touchstart",this.onTouchStart),document.addEventListener("mousemove",this.onMouseMove,{passive:!1}),document.addEventListener("mouseup",this.onMouseUp),document.addEventListener("touchmove",this.onTouchMove,{passive:!1}),document.addEventListener("touchend",this.onTouchEnd),this.loadWidget=k(this.loadWidget,10),this.onResize=k(this.onResize,250),requestAnimationFrame(this.checkResize)}destroy(){this.canvas2D.destroy(),this.container.removeEventListener("mousedown",this.onMouseDown),this.container.removeEventListener("mouseenter",this.onMouseEnter),this.container.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("mousemove",this.onMouseMove),document.removeEventListener("mouseup",this.onMouseUp),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd),this.isDestroyed=!0}async load(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>(this.scene=Array.isArray(t)?[...t]:[t],this.loadWidget(!1,!(e&&e.animation)))),i.catch(s=>{this.onLoadError(s)}),i}async setEncoder(t){this.encoder={...t};let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setParameters(t){t.width&&t.height&&(this.resolution=new y(t.width,t.height)),this.parameters={...t},this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height;let e=Promise.resolve();return e=e.then(()=>this.loadWidget(!1,!0)),e.catch(i=>{this.onLoadError(i)}),e}setHotspots(t){this.hotspots=t,this.loadWidget(!1,!1)}async setView(t,e){let i=Promise.resolve();return e?.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&e?.fromPosition!==void 0&&this.viewWidget instanceof O&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e?.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof O&&e?.toPosition!==void 0&&(s=!1,this.viewWidget.position=e.toPosition),this.loadWidget(s,!(e&&e.animation))}),i.catch(s=>{this.onLoadError(s)}),i}setVrcube(t){this.widgetVRCube&&Object.assign(this.widgetVRCube,t)}setVrobject(t){Object.assign(this.widgetVRObject,t)}async loadAnimation(t){const e={scene:this.scene,view:{animation:t.name,camera:t.camera,duration:t.duration,loop:t.loop,reverse:t.reverse},parameters:this.parameters,encoder:{format:"mp4"}};return e.view?.background||(e.view.background="product"),this.widgetVideo.load(e).then(()=>Promise.resolve())}async playAnimation(t){return this.loadAnimation(t).then(()=>this.widgetVideo.play()).catch(e=>{this.onLoadError(e)})}stopAnimation(){this.widgetVideo.hide()}async pick(t){if(!this.scene)throw new Error("No scene set");if(!this.view)throw new Error("No view set");if(!this.view.camera&&!this.view.cameraGroup)throw new Error("No camera set");const e={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return await this.viewWidget.pick(e,t)}async pickHotspot(t){const e=await this.pick(t),i=Object.values(e.point),s=h.v3.normalize(Object.values(e.normal)),r=h.v3.add(i,h.v3.mulScalar(s,.01));return e.point={x:r[0],y:r[1],z:r[2]},e}snapshot(t,e){return this.viewWidget.snapshot(t,e)}async loadWidget(t,e){if(!this.scene||!this.view||!this.parameters.width||!this.parameters.height)return Promise.resolve();const i=this.viewWidget;if(!i)return Promise.reject(new Error("Unknown view mode"));const s={scene:this.scene,view:this.view,parameters:this.parameters,encoder:this.encoder};return s.view.background||(s.view.background="product"),i.load(s,this.hotspots,t,e).then(()=>{this.widget.hide(),this.widget=i,this.widget.show(),this.widgetVideo.hide(),this.onHotspotsChange()})}get viewWidget(){switch(this.view?.mode){case"image":return this.widgetImage;case"video":return this.widgetVideo;case"vrcube":return this.widgetVRCube??this.widgetImage;case"vrobject":return this.widgetVRObject;default:return this.widgetImage}}checkResize(){if(this.isDestroyed)return;const t=this.container.clientWidth,e=this.container.clientHeight;(t!==this.containerWidth||e!==this.containerHeight)&&(this.containerWidth=t,this.containerHeight=e,this.onResize()),this.isDestroyed||requestAnimationFrame(this.checkResize)}onMouseDown(t){this.widget.onMouseDown(t)}onMouseEnter(t){this.widget.onMouseEnter(t)}onMouseMove(t){this.widget.onMouseMove(t)}onMouseUp(t){this.widget.onMouseUp(t)}onTouchStart(t){this.widget.onTouchStart(t)}onTouchMove(t){this.widget.onTouchMove(t)}onTouchEnd(t){this.widget.onTouchEnd(t)}onDeviceOrientation(t){this.widget.onDeviceOrientation(t)}onResize(){const t=this.container.clientWidth,e=this.container.clientHeight;this.options.autores&&(this.resolution=w.getStandardResolution(t*window.devicePixelRatio,e*window.devicePixelRatio),this.parameters.width=this.resolution.width,this.parameters.height=this.resolution.height),this.canvas2D.resize(t,e,window.devicePixelRatio),this.canvas3D.resize(t,e,window.devicePixelRatio),this.video.resize(t,e,this.resolution,this.options.fit),this.loadWidget(!1,!1).then(()=>{this.onHotspotsChange()}).catch(i=>{this.onLoadError(i)})}onVrcubeInteraction(...t){this.onHotspotsChange(),this.options.events.onInteraction(...t),this.options.events.onVrcubeInteraction(...t)}onVrobjectInteraction(t){this.onHotspotsChange(),this.options.events.onInteraction(t.position),this.options.events.onVrobjectInteraction(t.position)}onHotspotsChange(){const t=this.widget.hotspots(this.resolution);t.length&&this.options.events.onHotspotsChange(t)}onLoadStart(...t){this.container.classList.add("ls-viewer-container-loading"),this.options.events.onLoadStart(...t)}onLoadProgress(...t){this.options.events.onLoadProgress(...t)}onLoadEnd(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadEnd(...t)}onLoadError(...t){this.container.classList.remove("ls-viewer-container-loading"),this.options.events.onLoadError(...t)}}exports.WRAPIv2=void 0;(l=>{(t=>{t.Visible="Visible",t.Occluded="Occluded",t.Clipped="Clipped",t.OutOfFrustum="OutOfFrustum"})(l.HotspotVisibility||(l.HotspotVisibility={})),(t=>{t.VeryLow="veryLow",t.Low="low",t.Medium="medium",t.Fine="fine",t.Ultra="ultra"})(l.SunShadowQualityMode||(l.SunShadowQualityMode={})),(t=>{t.None="none",t.Weak="weak",t.Normal="normal",t.Fine="fine",t.UltraFine="ultraFine",t.Max="max"})(l.SunShadowSmoothnessMode||(l.SunShadowSmoothnessMode={})),(t=>{t.Manual="manual",t.TimeAndLoc="timeAndLoc",t.ExtractedFromEnv="extractedFromEnv"})(l.SunUseCaseMode||(l.SunUseCaseMode={})),(t=>{t.ShowOnly="showOnly",t.HideOnly="hideOnly"})(l.SurfacesFilterMode||(l.SurfacesFilterMode={}))})(exports.WRAPIv2||(exports.WRAPIv2={}));exports.Viewer=et;exports.WidgetImage=j;exports.WidgetVRCube=H;exports.WidgetVRObject=O;exports.WidgetVideo=G;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -169,12 +169,12 @@ declare class Video {
|
|
|
169
169
|
|
|
170
170
|
export declare interface View {
|
|
171
171
|
mode: string;
|
|
172
|
-
camera?: string |
|
|
172
|
+
camera?: string | WRAPIv2.CameraObj;
|
|
173
173
|
background?: string;
|
|
174
174
|
animation?: string;
|
|
175
175
|
frames?: number;
|
|
176
176
|
loop?: boolean;
|
|
177
|
-
cameraGroup?:
|
|
177
|
+
cameraGroup?: string;
|
|
178
178
|
panFrom?: number;
|
|
179
179
|
panTo?: number;
|
|
180
180
|
panFrames?: number;
|
|
@@ -522,6 +522,7 @@ export declare namespace WRAPIv2 {
|
|
|
522
522
|
export type AnimationArray = Animation[];
|
|
523
523
|
export type Camera = Guid | CameraObj;
|
|
524
524
|
export type CameraGroup = Guid;
|
|
525
|
+
export type ClippingPlaneArray = ClippingPlane[];
|
|
525
526
|
export type Color = string;
|
|
526
527
|
export type ColoredBackground = {
|
|
527
528
|
color: Color;
|
|
@@ -529,6 +530,7 @@ export declare namespace WRAPIv2 {
|
|
|
529
530
|
startColor: Color;
|
|
530
531
|
endColor: Color;
|
|
531
532
|
};
|
|
533
|
+
export type CullfacePolicy = 'always' | 'never' | 'product' | 'surface';
|
|
532
534
|
export type Guid = string;
|
|
533
535
|
export type LabelArray = (Label | ImageLabel | TextLabel)[];
|
|
534
536
|
export type LabelTransformArray = LabelTransform[];
|
|
@@ -559,6 +561,20 @@ export declare namespace WRAPIv2 {
|
|
|
559
561
|
pov?: Pov;
|
|
560
562
|
sensor?: Guid | Sensor;
|
|
561
563
|
}
|
|
564
|
+
export interface ClippingPlane {
|
|
565
|
+
enabled?: boolean;
|
|
566
|
+
position?: Vector3D;
|
|
567
|
+
normal?: Vector3D;
|
|
568
|
+
sliceEnabled?: boolean;
|
|
569
|
+
sliceColor?: Color;
|
|
570
|
+
sliceThickness?: number;
|
|
571
|
+
}
|
|
572
|
+
export interface ClippingPlanes {
|
|
573
|
+
enabled?: boolean;
|
|
574
|
+
cullfacePolicy?: CullfacePolicy;
|
|
575
|
+
excludedSurfacesTags?: string[];
|
|
576
|
+
planes?: ClippingPlaneArray;
|
|
577
|
+
}
|
|
562
578
|
export interface DepthPolicy {
|
|
563
579
|
mode?: DepthPolicyMode;
|
|
564
580
|
zMin?: number;
|
|
@@ -581,7 +597,7 @@ export declare namespace WRAPIv2 {
|
|
|
581
597
|
};
|
|
582
598
|
}
|
|
583
599
|
export interface Label {
|
|
584
|
-
type?:
|
|
600
|
+
type?: '' | 'image' | 'text';
|
|
585
601
|
surface?: string;
|
|
586
602
|
tag?: string;
|
|
587
603
|
id?: Guid;
|
|
@@ -598,8 +614,11 @@ export declare namespace WRAPIv2 {
|
|
|
598
614
|
type: 'text';
|
|
599
615
|
text: string;
|
|
600
616
|
fontFamily: string;
|
|
617
|
+
fontStyle?: string;
|
|
601
618
|
fontSize: number;
|
|
619
|
+
letterSpacing?: number;
|
|
602
620
|
color?: Color;
|
|
621
|
+
opacity?: number;
|
|
603
622
|
textAlign?: 'left' | 'start' | 'center' | 'right' | 'end';
|
|
604
623
|
}
|
|
605
624
|
export interface LabelTransform {
|
|
@@ -643,7 +662,6 @@ export declare namespace WRAPIv2 {
|
|
|
643
662
|
name: string;
|
|
644
663
|
diffuseColor?: Color;
|
|
645
664
|
diffuseColorIntensity?: number;
|
|
646
|
-
diffuseColorMap?: string;
|
|
647
665
|
specularRoughness?: number;
|
|
648
666
|
}
|
|
649
667
|
export interface Pov {
|
|
@@ -667,6 +685,8 @@ export declare namespace WRAPIv2 {
|
|
|
667
685
|
materialMultiLayers?: MaterialMultiLayerArray;
|
|
668
686
|
materialSeams?: MaterialSeamArray;
|
|
669
687
|
materialStandards?: MaterialStandardArray;
|
|
688
|
+
matteCulling?: boolean;
|
|
689
|
+
matteCullingDistance?: number;
|
|
670
690
|
partitions?: RenderPartitions;
|
|
671
691
|
surfaces?: SurfaceArray;
|
|
672
692
|
surfacesFilter?: SurfacesFilter;
|
|
@@ -679,9 +699,11 @@ export declare namespace WRAPIv2 {
|
|
|
679
699
|
export interface RenderParameters {
|
|
680
700
|
width?: number;
|
|
681
701
|
height?: number;
|
|
702
|
+
dpi?: number;
|
|
682
703
|
mode?: RenderMode;
|
|
683
704
|
antialiasing?: boolean;
|
|
684
705
|
background?: boolean;
|
|
706
|
+
clippingPlanes?: ClippingPlanes;
|
|
685
707
|
compositing?: boolean;
|
|
686
708
|
enhancedTransparency?: boolean;
|
|
687
709
|
grid?: boolean;
|
|
@@ -694,6 +716,7 @@ export declare namespace WRAPIv2 {
|
|
|
694
716
|
product?: boolean;
|
|
695
717
|
referential?: boolean;
|
|
696
718
|
superSampling?: '1' | '2' | '3' | '4';
|
|
719
|
+
superSamplingFilter?: 'legacy' | 'box' | 'tent' | 'hermite' | 'catmullrom' | 'mitchell' | 'bspline';
|
|
697
720
|
screenSpaceReflections?: boolean;
|
|
698
721
|
screenSpaceReflectionsGrazingAngleFadeoff?: number;
|
|
699
722
|
screenSpaceReflectionsQualityFactor?: number;
|
|
@@ -723,13 +746,13 @@ export declare namespace WRAPIv2 {
|
|
|
723
746
|
overlay?: Guid;
|
|
724
747
|
}
|
|
725
748
|
export interface SSAOParameters {
|
|
726
|
-
enabled
|
|
727
|
-
lightmaps
|
|
728
|
-
transparentSurfaces
|
|
729
|
-
radius
|
|
730
|
-
intensity
|
|
731
|
-
bias
|
|
732
|
-
steps
|
|
749
|
+
enabled?: boolean;
|
|
750
|
+
lightmaps?: boolean;
|
|
751
|
+
transparentSurfaces?: boolean;
|
|
752
|
+
radius?: number;
|
|
753
|
+
intensity?: number;
|
|
754
|
+
bias?: number;
|
|
755
|
+
steps?: number;
|
|
733
756
|
}
|
|
734
757
|
export interface SunAuthoringData {
|
|
735
758
|
enabled?: boolean;
|
|
@@ -745,11 +768,27 @@ export declare namespace WRAPIv2 {
|
|
|
745
768
|
northOrientation?: number;
|
|
746
769
|
useCase?: SunUseCaseMode;
|
|
747
770
|
manualData?: SunManualData;
|
|
771
|
+
timeAndLocData?: SunTimeAndLocData;
|
|
748
772
|
}
|
|
749
773
|
export interface SunManualData {
|
|
750
774
|
azimuth: number;
|
|
751
775
|
altitude: number;
|
|
752
776
|
}
|
|
777
|
+
export interface SunTimeAndLocData {
|
|
778
|
+
year: number;
|
|
779
|
+
month: number;
|
|
780
|
+
day: number;
|
|
781
|
+
hour: number;
|
|
782
|
+
minute: number;
|
|
783
|
+
second: number;
|
|
784
|
+
timezoneItem: number;
|
|
785
|
+
timezone: number;
|
|
786
|
+
dayLightSaving: boolean;
|
|
787
|
+
dayLightSavingMin: number;
|
|
788
|
+
cityItem: number;
|
|
789
|
+
latitude: number;
|
|
790
|
+
longitude: number;
|
|
791
|
+
}
|
|
753
792
|
export enum SunShadowQualityMode {
|
|
754
793
|
VeryLow = "veryLow",
|
|
755
794
|
Low = "low",
|
|
@@ -767,6 +806,7 @@ export declare namespace WRAPIv2 {
|
|
|
767
806
|
}
|
|
768
807
|
export enum SunUseCaseMode {
|
|
769
808
|
Manual = "manual",
|
|
809
|
+
TimeAndLoc = "timeAndLoc",
|
|
770
810
|
ExtractedFromEnv = "extractedFromEnv"
|
|
771
811
|
}
|
|
772
812
|
export interface Surface {
|
|
@@ -824,7 +864,7 @@ export declare namespace WRAPIv2 {
|
|
|
824
864
|
};
|
|
825
865
|
}
|
|
826
866
|
export interface WebpEncoder {
|
|
827
|
-
webp
|
|
867
|
+
webp: {
|
|
828
868
|
quality?: number;
|
|
829
869
|
};
|
|
830
870
|
}
|