@lumiscaphe/viewer 4.1.15 → 4.1.16
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/CLAUDE.md +174 -0
- package/dist/lib/index.cjs +5 -5
- package/dist/lib/index.js +144 -153
- package/package.json +8 -8
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Lumiscaphe 3D Viewer (@lumiscaphe/viewer) is a TypeScript-based WebGL viewer library for rendering interactive 3D products from WebRender server. It supports multiple viewing modes (static images, VRCube panoramas, VRObject rotation) and integrates with Lumiscaphe's WebRender API (v1 and v2).
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
### Development
|
|
12
|
+
```bash
|
|
13
|
+
npm run dev # Start development server with sample viewer
|
|
14
|
+
npm run preview # Preview built sample application
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Building
|
|
18
|
+
```bash
|
|
19
|
+
npm run build:lib # Build library distribution (ES + CJS)
|
|
20
|
+
npm run build:sample # Build sample application
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Linting
|
|
24
|
+
```bash
|
|
25
|
+
npm run lint # Run ESLint on all TypeScript files in src/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Pre-commit Hook
|
|
29
|
+
The repository uses Husky with a pre-commit hook that runs `npm run lint` automatically before commits.
|
|
30
|
+
|
|
31
|
+
## Architecture
|
|
32
|
+
|
|
33
|
+
### Core Components
|
|
34
|
+
|
|
35
|
+
**Viewer (src/lib/Viewer.ts)**
|
|
36
|
+
- Main entry point and orchestrator
|
|
37
|
+
- Manages canvas instances (Canvas2D, Canvas3D, Video)
|
|
38
|
+
- Handles scene loading, view changes, and user interactions
|
|
39
|
+
- Delegates rendering to Widget implementations based on view mode
|
|
40
|
+
- Uses debouncing for resize and loading operations
|
|
41
|
+
|
|
42
|
+
**Widget System**
|
|
43
|
+
- `Widget` interface defines the contract for all view modes
|
|
44
|
+
- Four concrete implementations:
|
|
45
|
+
- `WidgetImage`: Static image rendering using Canvas2D
|
|
46
|
+
- `WidgetVideo`: Video playback for animations
|
|
47
|
+
- `WidgetVRCube`: Interactive WebGL cube map viewer with camera controls
|
|
48
|
+
- `WidgetVRObject`: Image sequence viewer for product rotation
|
|
49
|
+
- Each widget handles its own interaction model and rendering
|
|
50
|
+
|
|
51
|
+
**Loader (src/lib/Loader.ts)**
|
|
52
|
+
- Abstracts WebRender API communication
|
|
53
|
+
- Supports three API modes: 'static', 'v1', 'v2'
|
|
54
|
+
- Manages progressive loading with priority-based image loading (center-out for VRObject)
|
|
55
|
+
- Handles conversion between v1 camera paths and v2 camera IDs
|
|
56
|
+
- Caches database XML for camera lookups
|
|
57
|
+
|
|
58
|
+
**WebRender Integrations**
|
|
59
|
+
- `WebRenderStatic`: Direct image URLs
|
|
60
|
+
- `WebRenderV1`: Legacy API using camera paths (e.g., "EXTER/1")
|
|
61
|
+
- `WebRenderV2`: Modern REST API using GUIDs and structured requests
|
|
62
|
+
- API requests use POST with JSON body for snapshots, hotspots, and picking
|
|
63
|
+
|
|
64
|
+
### Canvas Architecture
|
|
65
|
+
|
|
66
|
+
**Canvas3D (src/lib/Canvas3D.ts)**
|
|
67
|
+
- WebGL rendering context for VRCube mode
|
|
68
|
+
- Uses twgl.js for WebGL utilities
|
|
69
|
+
- Handles context loss detection
|
|
70
|
+
- Implements preserveDrawingBuffer for snapshot capability
|
|
71
|
+
|
|
72
|
+
**Canvas2D (src/lib/Canvas2D.ts)**
|
|
73
|
+
- 2D rendering for images and VRObject sequences
|
|
74
|
+
- Supports three fit modes: 'cover', 'contain', 'fill'
|
|
75
|
+
|
|
76
|
+
**WidgetVRCube WebGL Pipeline**
|
|
77
|
+
- Uses custom GLSL shaders (WidgetVRCube.frag, WidgetVRCube.vert)
|
|
78
|
+
- Implements cube map texture rendering
|
|
79
|
+
- Features camera interaction with inertia
|
|
80
|
+
- Handles hotspot projection from cube faces to screen space
|
|
81
|
+
- Includes workaround for MacIntel Chrome OpenGL texture size limit (1812x1812)
|
|
82
|
+
|
|
83
|
+
### Scene and View Model
|
|
84
|
+
|
|
85
|
+
**Scene**
|
|
86
|
+
- Array of products with database GUID, configuration strings, and animations
|
|
87
|
+
- Supports decor and accessory products with transformation data
|
|
88
|
+
- Configuration format: slash-separated values (e.g., "Bin.Blue/Cabin.Yellow/Style.Design1")
|
|
89
|
+
|
|
90
|
+
**View**
|
|
91
|
+
- Defines rendering mode: 'image', 'video', 'vrcube', 'vrobject'
|
|
92
|
+
- Camera specification (v1: path string, v2: GUID or camera object with POV)
|
|
93
|
+
- Background modes: 'product', 'transparent', 'gradient'
|
|
94
|
+
- VRObject supports both animation-based and bookmark-set navigation
|
|
95
|
+
|
|
96
|
+
**Snapshot**
|
|
97
|
+
- Internal type combining Scene, View, Parameters, and Encoder
|
|
98
|
+
- Used for all WebRender API requests
|
|
99
|
+
|
|
100
|
+
### Interaction System
|
|
101
|
+
|
|
102
|
+
**InteractiveCamera/InteractivePosition**
|
|
103
|
+
- Implements mouse/touch drag with inertia physics
|
|
104
|
+
- VRCube uses spherical coordinates for camera rotation
|
|
105
|
+
- VRObject uses discrete position indices
|
|
106
|
+
- Debounced interaction callbacks prevent excessive API calls
|
|
107
|
+
|
|
108
|
+
**Hotspots**
|
|
109
|
+
- 3D position markers projected to 2D screen space
|
|
110
|
+
- Supports both tag-based (string) and position-based (Vector3D) definitions
|
|
111
|
+
- Visibility culling based on camera frustum
|
|
112
|
+
- Requires WebRender API v2
|
|
113
|
+
|
|
114
|
+
**Picking**
|
|
115
|
+
- Ray-casting for 3D point selection on product surface
|
|
116
|
+
- Returns point, normal, and material information
|
|
117
|
+
- VRCube implements custom cube face determination and UV mapping
|
|
118
|
+
|
|
119
|
+
## Key Implementation Details
|
|
120
|
+
|
|
121
|
+
### API Version Compatibility
|
|
122
|
+
- Loader automatically uses WebRenderV2 for hotspots and picking even when main API is v1
|
|
123
|
+
- Database caching prevents redundant XML fetches during v1-to-v2 camera path conversion
|
|
124
|
+
- Camera conversion logic in `Loader.convert()` handles both camera IDs and camera group IDs
|
|
125
|
+
|
|
126
|
+
### GLSL Shader Integration
|
|
127
|
+
- Vite plugin 'vite-plugin-glsl' processes .frag and .vert files
|
|
128
|
+
- Custom type declarations in src/lib/types/ for shader imports
|
|
129
|
+
- Shaders are imported as strings and compiled at runtime via twgl.createProgramInfo
|
|
130
|
+
|
|
131
|
+
### ESLint Configuration
|
|
132
|
+
- Uses flat config format (eslint.config.mjs)
|
|
133
|
+
- Enforces explicit function return types but allows expressions
|
|
134
|
+
- Disables @typescript-eslint/no-explicit-any (project uses `any` extensively)
|
|
135
|
+
- Disabled unused-vars checking
|
|
136
|
+
|
|
137
|
+
### Build Configuration
|
|
138
|
+
- Two separate Vite configs:
|
|
139
|
+
- `vite.config.lib.ts`: Library build (ES + CJS) with type declarations
|
|
140
|
+
- `vite.config.sample.ts`: Sample app for development/testing
|
|
141
|
+
- CSS injection via vite-plugin-css-injected-by-js (no separate CSS file)
|
|
142
|
+
- External dependencies: debounce-promise, regression, twgl.js
|
|
143
|
+
- Tree-shaking enabled with moduleSideEffects: false
|
|
144
|
+
|
|
145
|
+
### Resolution and Viewport
|
|
146
|
+
- Auto-resolution (`autores: true`) computes standard resolutions based on viewport
|
|
147
|
+
- `Viewport.getStandardResolution()` rounds to WebRender-friendly dimensions
|
|
148
|
+
- Super-sampling coefficient (1-4) for quality control
|
|
149
|
+
- Separate parameters for render resolution vs canvas display size
|
|
150
|
+
|
|
151
|
+
### Loading Strategy
|
|
152
|
+
- LoadingId pattern prevents race conditions when requests are cancelled
|
|
153
|
+
- Progressive image loading for VRObject starts from current position and spirals outward
|
|
154
|
+
- Video frame extraction uses canvas.toDataURL for animation sequences
|
|
155
|
+
- Debounced onLoadError prevents error spam during rapid view changes
|
|
156
|
+
|
|
157
|
+
## WebRender API Types
|
|
158
|
+
|
|
159
|
+
The `WRAPIv2` namespace (src/lib/WRAPIv2.ts) defines comprehensive TypeScript types for:
|
|
160
|
+
- Scene composition (Product, Scene)
|
|
161
|
+
- Rendering modes (ImageMode, VrCubeMode, VrObjectMode, AnimationMode)
|
|
162
|
+
- Requests (SnapshotRequest, HotspotRequest, PickRequest)
|
|
163
|
+
- Camera specifications (including POV and lens parameters)
|
|
164
|
+
- Encoder configurations (JPEG, PNG, WebP)
|
|
165
|
+
|
|
166
|
+
## Testing Notes
|
|
167
|
+
|
|
168
|
+
This project does not currently have automated tests. When adding features, manual testing should cover:
|
|
169
|
+
- All four view modes with representative scenes
|
|
170
|
+
- API version switching (static, v1, v2)
|
|
171
|
+
- Hotspot visibility and picking accuracy
|
|
172
|
+
- Cross-browser WebGL compatibility (especially Mac Chrome with OpenGL)
|
|
173
|
+
- Touch and mouse interactions with proper inertia
|
|
174
|
+
- Loading cancellation during rapid scene/view changes
|
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"),N=require("regression");function B(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 x=B(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 X{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 Y{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=x.getContext(this.element,{preserveDrawingBuffer:!0}),this.context&&this.context.isContextLost()&&(this.context=void 0),x.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 W{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 J{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 j{constructor(t){this.xmlDoc=t}get id(){var t;return(t=this.xmlDoc.getElementsByTagName("Database")[0])==null?void 0:t.getAttribute("id")}getCameraId(t,e){var i,s;return e?(i=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`))==null?void 0:i.getAttribute("id"):(s=this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`))==null?void 0:s.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){var e;return(e=this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`))==null?void 0:e.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){var n,a;const e=t.scene,i=e.length>1?e.find(o=>o.accessory):null,s=e.length>1?e.find(o=>o.decor):null,r=e.find(o=>o!==i&&o!==s);return{databaseId:r.database,configuration:r==null?void 0:r.configuration,animations:(n=r==null?void 0:r.animations)==null?void 0:n.join("/"),accessoryDatabaseId:i==null?void 0:i.database,decorDatabaseId:s==null?void 0:s.database,decorDeltaAltitude:(a=s==null?void 0:s.translation)==null?void 0:a.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 j(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 j(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 J;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){var s;this.loadingId+=1,this.loaded=0,this.total=0,this.onLoadStart(this.progress);const{loadingId:i}=this;return t.view.animation?((s=t.encoder)==null?void 0:s.format)==="mp4"?this.webrender.video(t).then(r=>this.loadVideoFrames(r,t.view.frames,30,i)):this.webrender.animation(t).then(r=>this.loadImageFrames(r,t.view.loop,e,i)):this.webrender.vrObject(t).then(r=>this.loadImageFrames(r,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){var o;if(!this.webrenderV2||this.webrender instanceof m||!t.view.camera)return t;const e=t.scene.find(d=>!d.decor&&!d.accessory);if(!e)return t;let i=this.databases.find(d=>d.id===e.database);(!i||!i.xmlDoc)&&(i=await this.webrender.database(e.database),this.databases.push(i));const s=(o=t.view.camera)==null?void 0:o.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 d=i.getCameraGroupId(n);return d?{...t,view:{...t.view,cameraGroup:d}}: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 W(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 Z{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 q{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 V{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 Q{constructor(t,e,i){this.x=t,this.y=e,this.time=i}}class H{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 Q(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 _{constructor(t,e,i){this.isStarted=!1,this.pov=t,this.fov=g.degreesToRadians(e),this.orientationMatrix=h.m4.identity(),this.inertia=new H(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 V(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 V(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 K=`precision mediump float;
|
|
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;
|
|
3
3
|
|
|
4
4
|
uniform float u_mix;
|
|
5
5
|
uniform samplerCube u_texture;
|
|
@@ -11,7 +11,7 @@ void main() {
|
|
|
11
11
|
vec4 backColor = textureCube(u_texture_back, direction);
|
|
12
12
|
vec4 color = textureCube(u_texture, direction);
|
|
13
13
|
gl_FragColor = mix(backColor, color, u_mix);
|
|
14
|
-
}`,
|
|
14
|
+
}`,K=`attribute vec4 position;
|
|
15
15
|
|
|
16
16
|
uniform mat4 u_mvpi;
|
|
17
17
|
|
|
@@ -20,6 +20,6 @@ varying vec3 direction;
|
|
|
20
20
|
void main() {
|
|
21
21
|
direction = (u_mvpi * position).xyz;
|
|
22
22
|
gl_Position = position;
|
|
23
|
-
}`;class
|
|
24
|
-
`,`${
|
|
25
|
-
`]),this.quad=x.primitives.createXYQuadBufferInfo(this.gl),this.uniforms={u_mvpi:h.m4.identity(),u_mix:0,u_texture_back:x.createTexture(this.gl,{target:this.gl.TEXTURE_CUBE_MAP,minMag:this.gl.LINEAR,width:1,height:1}),u_texture:x.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,x.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)),O=Math.max(Math.abs(c[0]),Math.abs(c[1]),Math.abs(c[2]));let L="";Math.abs(c[0])===O?L=c[0]>0?"XPOS":"XNEG":Math.abs(c[1])===O?L=c[1]>0?"YPOS":"YNEG":L=c[2]>0?"ZPOS":"ZNEG";let P=0,b=0,M="";switch(L){case"XPOS":P=(-c[2]/Math.abs(c[0])+1)/2,b=(-c[1]/Math.abs(c[0])+1)/2,M="right";break;case"XNEG":P=(c[2]/Math.abs(c[0])+1)/2,b=(-c[1]/Math.abs(c[0])+1)/2,M="left";break;case"YPOS":P=(c[0]/Math.abs(c[1])+1)/2,b=(c[2]/Math.abs(c[1])+1)/2,M="up";break;case"YNEG":P=(c[0]/Math.abs(c[1])+1)/2,b=(-c[2]/Math.abs(c[1])+1)/2,M="down";break;case"ZPOS":P=(c[0]/Math.abs(c[2])+1)/2,b=(-c[1]/Math.abs(c[2])+1)/2,M="front";break;case"ZNEG":P=(-c[0]/Math.abs(c[2])+1)/2,b=(-c[1]/Math.abs(c[2])+1)/2,M="back";break}const T={x:Math.round(P*Math.max(t.parameters.width,t.parameters.height)),y:Math.round(b*Math.max(t.parameters.width,t.parameters.height))};return this.loader.loadVRCubePick(t,T,M)}hotspots(){var s;const t=[];if(this.hotspotsList.length===0)return[];const e=((s=this.hotspotsList[0])==null?void 0:s.length)??0,i=this.modelViewProjectionMatrix;for(let r=0;r<e;r++){const n=this.hotspotsList.findIndex(U=>U[r].visibility!=="OutOfFrustum");if(n===-1)continue;const a={...this.hotspotsList[n][r]},o=a.position2D.x/this.images[0].width,d=a.position2D.y/this.images[0].height;let u=0,p=0,c=0;switch(n){case 0:this.pov.target[2]<0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=1-2*d,c=1;break;case 1:this.pov.target[0]>0&&(a.visibility="OutOfFrustum"),u=1,p=1-2*d,c=1-2*o;break;case 2:this.pov.target[2]>0&&(a.visibility="OutOfFrustum"),u=1-2*o,p=1-2*d,c=-1;break;case 3:this.pov.target[0]<0&&(a.visibility="OutOfFrustum"),u=-1,p=1-2*d,c=2*o-1;break;case 4:this.pov.target[1]<0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=1,c=2*d-1;break;case 5:this.pov.target[1]>0&&(a.visibility="OutOfFrustum"),u=2*o-1,p=-1,c=1-2*d;break}const O=h.v3.normalize([u,p,c]),L=h.m4.transformPoint(i,O),P=this.canvas.element.clientWidth,b=this.canvas.element.clientHeight,M=.5*P*(L[0]+1),T=.5*b*(L[1]+1),D={x:Math.round(M),y:Math.round(b-T)},z=new y(P,b),$=w.contains(z,D)?a.visibility:"OutOfFrustum";t.push({...a,position2D:D,visibility:$})}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),x.setBuffersAndAttributes(this.gl,this.programInfo,this.quad),x.setUniforms(this.programInfo,this.uniforms),x.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 et{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 H(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=N.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 A{constructor(t,e,i,s){this.container=t,this.canvas=e,this.loader=i,this.images=[],this.frames=24,this.hotspotsList=[[]],this.interaction=new et({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 R{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 it{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 X(this.options.fit),this.container.prepend(this.canvas2D.element),this.canvas3D=new Y,this.container.prepend(this.canvas3D.element),this.video=new Z,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 q(t,this.canvas2D,this.loader),this.widgetVideo=new R(t,this.video,this.loader),this.widgetVRObject=new A(t,this.canvas2D,this.loader,this.onVrobjectInteraction),this.canvas3D.context&&(this.widgetVRCube=new G(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!=null&&e.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&(e==null?void 0:e.fromPosition)!==void 0&&this.viewWidget instanceof A&&(this.view.mode,i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e!=null&&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!=null&&e.animation&&(i=i.then(()=>this.loadAnimation(e.animation))),this.view&&(e==null?void 0:e.fromPosition)!==void 0&&this.viewWidget instanceof A&&(i=i.then(()=>this.viewWidget.goto(e.fromPosition))),e!=null&&e.animation&&(i=i.then(()=>this.widgetVideo.play())),i=i.then(()=>{let s=!0;return this.view={...t},this.view&&this.viewWidget instanceof A&&(e==null?void 0: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){var i;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(i=e.view)!=null&&i.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(){var t;switch((t=this.view)==null?void 0:t.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=it;exports.WidgetImage=q;exports.WidgetVRCube=G;exports.WidgetVRObject=A;exports.WidgetVideo=R;
|
|
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
|
+
`,`${_}
|
|
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;
|
package/dist/lib/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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
2
|
import k from "debounce-promise";
|
|
3
|
-
import * as
|
|
4
|
-
import { v3 as h, m4 as
|
|
5
|
-
import
|
|
3
|
+
import * as P from "twgl.js";
|
|
4
|
+
import { v3 as h, m4 as c } from "twgl.js";
|
|
5
|
+
import $ from "regression";
|
|
6
6
|
class b {
|
|
7
7
|
constructor(t, e) {
|
|
8
8
|
this.width = t, this.height = e;
|
|
@@ -33,8 +33,8 @@ class p {
|
|
|
33
33
|
n = e.width, a = e.height;
|
|
34
34
|
break;
|
|
35
35
|
}
|
|
36
|
-
const o = (e.height - a) / 2,
|
|
37
|
-
return new p(o,
|
|
36
|
+
const o = (e.height - a) / 2, l = (e.width - n) / 2;
|
|
37
|
+
return new p(o, l, n, a);
|
|
38
38
|
}
|
|
39
39
|
static project(t, e, i, s) {
|
|
40
40
|
const r = p.fit(t, e, i), n = r.width / t.width, a = r.height / t.height;
|
|
@@ -76,7 +76,7 @@ class p {
|
|
|
76
76
|
return t <= 240 ? 240 : t <= 360 ? 360 : t <= 480 ? 480 : t <= 720 ? 720 : 1080;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
class
|
|
79
|
+
class U {
|
|
80
80
|
constructor(t) {
|
|
81
81
|
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;
|
|
82
82
|
}
|
|
@@ -113,9 +113,9 @@ class N {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
class
|
|
116
|
+
class N {
|
|
117
117
|
constructor() {
|
|
118
|
-
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 =
|
|
118
|
+
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] });
|
|
119
119
|
}
|
|
120
120
|
show() {
|
|
121
121
|
this.element.style.opacity = "1";
|
|
@@ -154,8 +154,8 @@ class w {
|
|
|
154
154
|
}
|
|
155
155
|
static perspectiveWithLeft(t, e, i, s, r, n, a) {
|
|
156
156
|
a = a || new Float32Array(16);
|
|
157
|
-
const o = e + t,
|
|
158
|
-
return a[0] = 2 * r /
|
|
157
|
+
const o = e + t, l = e - t, u = s + i, f = s - i, d = n - r;
|
|
158
|
+
return a[0] = 2 * r / l, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0, a[5] = 2 * r / f, a[6] = 0, a[7] = 0, a[8] = o / l, a[9] = u / f, a[10] = -n / d, a[11] = -1, a[12] = 0, a[13] = 0, a[14] = -n * r / d, a[15] = 0, a;
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
const A = class A {
|
|
@@ -194,7 +194,7 @@ const A = class A {
|
|
|
194
194
|
return h.normalize(h.cross(this.viewVector, this.up));
|
|
195
195
|
}
|
|
196
196
|
get viewMatrix() {
|
|
197
|
-
return
|
|
197
|
+
return c.inverse(c.lookAt(this.eye, this.target, this.up));
|
|
198
198
|
}
|
|
199
199
|
clone() {
|
|
200
200
|
return new A(h.copy(this.target), h.copy(this.eye), h.copy(this.up));
|
|
@@ -202,7 +202,7 @@ const A = class A {
|
|
|
202
202
|
};
|
|
203
203
|
A.default = new A([0, 0, 0], [2, 2, 2], [0, 1, 0]);
|
|
204
204
|
let L = A;
|
|
205
|
-
class
|
|
205
|
+
class B {
|
|
206
206
|
constructor(t) {
|
|
207
207
|
this.target = t.target;
|
|
208
208
|
const e = h.normalize(h.subtract(t.eye, t.target)), i = h.dot(e, [1, 0, 0]), s = h.dot(e, [0, 1, 0]), r = h.dot(e, [0, 0, 1]);
|
|
@@ -213,16 +213,16 @@ class X {
|
|
|
213
213
|
return [i, e, s];
|
|
214
214
|
}
|
|
215
215
|
pointOfView(t) {
|
|
216
|
-
const e =
|
|
216
|
+
const e = c.rotationY(this.longitude), i = c.rotationX(-this.latitude), s = c.rotationZ(0), r = c.multiply(e, c.multiply(i, s));
|
|
217
217
|
let n = [0, 0, -1];
|
|
218
|
-
n =
|
|
218
|
+
n = c.transformPoint(r, n);
|
|
219
219
|
let a = [0, 1, 0];
|
|
220
|
-
a =
|
|
220
|
+
a = c.transformPoint(r, a);
|
|
221
221
|
const o = h.subtract(t, h.mulScalar(n, this.distance));
|
|
222
222
|
return new L(t, o, a);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
|
-
class
|
|
225
|
+
class X {
|
|
226
226
|
constructor() {
|
|
227
227
|
}
|
|
228
228
|
async animation(t) {
|
|
@@ -244,17 +244,15 @@ class Y {
|
|
|
244
244
|
return t.scene;
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
class
|
|
247
|
+
class H {
|
|
248
248
|
constructor(t) {
|
|
249
249
|
this.xmlDoc = t;
|
|
250
250
|
}
|
|
251
251
|
get id() {
|
|
252
|
-
|
|
253
|
-
return (t = this.xmlDoc.getElementsByTagName("Database")[0]) == null ? void 0 : t.getAttribute("id");
|
|
252
|
+
return this.xmlDoc.getElementsByTagName("Database")[0]?.getAttribute("id");
|
|
254
253
|
}
|
|
255
254
|
getCameraId(t, e) {
|
|
256
|
-
|
|
257
|
-
return e ? (i = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)) == null ? void 0 : i.getAttribute("id") : (s = this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)) == null ? void 0 : s.getAttribute("id");
|
|
255
|
+
return e ? this.xmlDoc.querySelector(`RootCameraGroup Group[name="${e}"] Camera[name="${t}"]`)?.getAttribute("id") : this.xmlDoc.querySelector(`RootCameraGroup Camera[name="${t}"]`)?.getAttribute("id");
|
|
258
256
|
}
|
|
259
257
|
getCameraById(t, e) {
|
|
260
258
|
let i;
|
|
@@ -265,8 +263,7 @@ class q {
|
|
|
265
263
|
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;
|
|
266
264
|
}
|
|
267
265
|
getCameraGroupId(t) {
|
|
268
|
-
|
|
269
|
-
return (e = this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)) == null ? void 0 : e.getAttribute("id");
|
|
266
|
+
return this.xmlDoc.querySelector(`RootCameraGroup Group[name="${t}"]`)?.getAttribute("id");
|
|
270
267
|
}
|
|
271
268
|
getCameraGroupById(t) {
|
|
272
269
|
const e = this.xmlDoc.querySelector(`RootCameraGroup Group[id="${t}"]`);
|
|
@@ -318,15 +315,14 @@ const g = class g {
|
|
|
318
315
|
return Object.entries(t).filter(([e, i]) => i != null).map(([e, i]) => `${e}=${i}`).join("&");
|
|
319
316
|
}
|
|
320
317
|
static sceneParameters(t) {
|
|
321
|
-
|
|
322
|
-
const e = t.scene, i = e.length > 1 ? e.find((o) => o.accessory) : null, s = e.length > 1 ? e.find((o) => o.decor) : null, r = e.find((o) => o !== i && o !== s);
|
|
318
|
+
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);
|
|
323
319
|
return {
|
|
324
320
|
databaseId: r.database,
|
|
325
|
-
configuration: r
|
|
326
|
-
animations:
|
|
327
|
-
accessoryDatabaseId: i
|
|
328
|
-
decorDatabaseId: s
|
|
329
|
-
decorDeltaAltitude:
|
|
321
|
+
configuration: r?.configuration,
|
|
322
|
+
animations: r?.animations?.join("/"),
|
|
323
|
+
accessoryDatabaseId: i?.database,
|
|
324
|
+
decorDatabaseId: s?.database,
|
|
325
|
+
decorDeltaAltitude: s?.translation?.y
|
|
330
326
|
};
|
|
331
327
|
}
|
|
332
328
|
static renderParameters(t) {
|
|
@@ -368,7 +364,7 @@ const g = class g {
|
|
|
368
364
|
async database(t) {
|
|
369
365
|
return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
|
|
370
366
|
const i = new DOMParser().parseFromString(e, "application/xml");
|
|
371
|
-
return new
|
|
367
|
+
return new H(i);
|
|
372
368
|
});
|
|
373
369
|
}
|
|
374
370
|
async image(t) {
|
|
@@ -481,7 +477,7 @@ class m {
|
|
|
481
477
|
async database(t) {
|
|
482
478
|
return fetch(`${this.server}/Database?databaseId=${t}`).then((e) => e.text()).then((e) => {
|
|
483
479
|
const i = new DOMParser().parseFromString(e, "application/xml");
|
|
484
|
-
return new
|
|
480
|
+
return new H(i);
|
|
485
481
|
});
|
|
486
482
|
}
|
|
487
483
|
async image(t) {
|
|
@@ -635,7 +631,7 @@ class D {
|
|
|
635
631
|
constructor(t, e, i) {
|
|
636
632
|
switch (e) {
|
|
637
633
|
case "static":
|
|
638
|
-
this.webrender = new
|
|
634
|
+
this.webrender = new X();
|
|
639
635
|
break;
|
|
640
636
|
case "v1":
|
|
641
637
|
this.webrender = new S(t), this.webrenderV2 = new m(t);
|
|
@@ -675,10 +671,9 @@ class D {
|
|
|
675
671
|
}).then((i) => (this.onLoadEnd(this.progress), i));
|
|
676
672
|
}
|
|
677
673
|
async loadVRObjectSnapshot(t, e) {
|
|
678
|
-
var s;
|
|
679
674
|
this.loadingId += 1, this.loaded = 0, this.total = 0, this.onLoadStart(this.progress);
|
|
680
675
|
const { loadingId: i } = this;
|
|
681
|
-
return t.view.animation ?
|
|
676
|
+
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));
|
|
682
677
|
}
|
|
683
678
|
async loadImage(t, e) {
|
|
684
679
|
const i = new Image();
|
|
@@ -704,7 +699,7 @@ class D {
|
|
|
704
699
|
this.total = t.length;
|
|
705
700
|
const r = new Array(t.length), n = i || 0;
|
|
706
701
|
for (let a = 0, o = t.length; a < o; a += 1) {
|
|
707
|
-
const
|
|
702
|
+
const l = Math.ceil(a / 2) * (a % 2 === 0 ? 1 : -1), u = e ? w.mod(n + l, o) : a;
|
|
708
703
|
r[u] = this.loadImage(t[u], s);
|
|
709
704
|
}
|
|
710
705
|
return Promise.all(r).then(() => this.onLoadEnd(this.progress)).catch(() => {
|
|
@@ -732,19 +727,19 @@ class D {
|
|
|
732
727
|
async loadVideoFrame(t, e, i, s, r) {
|
|
733
728
|
let n = 0;
|
|
734
729
|
return new Promise((a, o) => {
|
|
735
|
-
const
|
|
730
|
+
const l = () => {
|
|
736
731
|
if (r !== this.loadingId) return;
|
|
737
732
|
if (n !== s) {
|
|
738
733
|
n += 1;
|
|
739
734
|
return;
|
|
740
735
|
}
|
|
741
|
-
t.removeEventListener("seeked",
|
|
736
|
+
t.removeEventListener("seeked", l);
|
|
742
737
|
const u = document.createElement("canvas");
|
|
743
738
|
u.width = t.videoWidth, u.height = t.videoHeight, u.getContext("2d").drawImage(t, 0, 0);
|
|
744
|
-
const
|
|
745
|
-
|
|
739
|
+
const d = new Image();
|
|
740
|
+
d.src = u.toDataURL(), a(d), this.loaded += 1, this.onLoadProgress(this.progress), s !== i - 1 && (t.currentTime += 1 / e);
|
|
746
741
|
};
|
|
747
|
-
t.addEventListener("seeked",
|
|
742
|
+
t.addEventListener("seeked", l), t.addEventListener(
|
|
748
743
|
"error",
|
|
749
744
|
(u) => {
|
|
750
745
|
r === this.loadingId && o(u);
|
|
@@ -786,20 +781,19 @@ class D {
|
|
|
786
781
|
return this.webrenderV2 ? await this.webrenderV2.imagePick(await this.vrCubeFrameSnapshot(t, i), e) : Promise.reject(new Error("Picking only available with api V2"));
|
|
787
782
|
}
|
|
788
783
|
async convert(t) {
|
|
789
|
-
var o;
|
|
790
784
|
if (!this.webrenderV2 || this.webrender instanceof m || !t.view.camera)
|
|
791
785
|
return t;
|
|
792
|
-
const e = t.scene.find((
|
|
786
|
+
const e = t.scene.find((o) => !o.decor && !o.accessory);
|
|
793
787
|
if (!e)
|
|
794
788
|
return t;
|
|
795
|
-
let i = this.databases.find((
|
|
789
|
+
let i = this.databases.find((o) => o.id === e.database);
|
|
796
790
|
(!i || !i.xmlDoc) && (i = await this.webrender.database(e.database), this.databases.push(i));
|
|
797
|
-
const s =
|
|
791
|
+
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);
|
|
798
792
|
if (a)
|
|
799
793
|
return { ...t, view: { ...t.view, camera: a } };
|
|
800
794
|
{
|
|
801
|
-
const
|
|
802
|
-
return
|
|
795
|
+
const o = i.getCameraGroupId(n);
|
|
796
|
+
return o ? { ...t, view: { ...t.view, cameraGroup: o } } : t;
|
|
803
797
|
}
|
|
804
798
|
}
|
|
805
799
|
async vrObjectFrameSnapshot(t, e, i) {
|
|
@@ -825,9 +819,9 @@ class D {
|
|
|
825
819
|
const n = r.getCameraById(t.view.camera);
|
|
826
820
|
if (!n)
|
|
827
821
|
return t;
|
|
828
|
-
const a = new
|
|
822
|
+
const a = new B(n.pointOfView), o = 2 * Math.PI / i;
|
|
829
823
|
a.longitude += e * o % (2 * Math.PI);
|
|
830
|
-
const
|
|
824
|
+
const l = a.pointOfView(n.pointOfView.target);
|
|
831
825
|
return {
|
|
832
826
|
...t,
|
|
833
827
|
view: {
|
|
@@ -836,19 +830,19 @@ class D {
|
|
|
836
830
|
id: n.id,
|
|
837
831
|
pov: {
|
|
838
832
|
target: {
|
|
839
|
-
x:
|
|
840
|
-
y:
|
|
841
|
-
z:
|
|
833
|
+
x: l.target[0],
|
|
834
|
+
y: l.target[1],
|
|
835
|
+
z: l.target[2]
|
|
842
836
|
},
|
|
843
837
|
eye: {
|
|
844
|
-
x:
|
|
845
|
-
y:
|
|
846
|
-
z:
|
|
838
|
+
x: l.eye[0],
|
|
839
|
+
y: l.eye[1],
|
|
840
|
+
z: l.eye[2]
|
|
847
841
|
},
|
|
848
842
|
up: {
|
|
849
|
-
x:
|
|
850
|
-
y:
|
|
851
|
-
z:
|
|
843
|
+
x: l.up[0],
|
|
844
|
+
y: l.up[1],
|
|
845
|
+
z: l.up[2]
|
|
852
846
|
}
|
|
853
847
|
}
|
|
854
848
|
}
|
|
@@ -874,8 +868,8 @@ class D {
|
|
|
874
868
|
return t;
|
|
875
869
|
let r;
|
|
876
870
|
if (this.webrender instanceof S) {
|
|
877
|
-
const o = t.view.camera.split("/"),
|
|
878
|
-
r = s.getCameraId(u,
|
|
871
|
+
const o = t.view.camera.split("/"), l = o.length === 2 ? o[0] : void 0, u = o.length === 2 ? o[1] : o[0];
|
|
872
|
+
r = s.getCameraId(u, l);
|
|
879
873
|
} else this.webrender instanceof m && (r = t.view.camera);
|
|
880
874
|
if (!r)
|
|
881
875
|
return t;
|
|
@@ -937,7 +931,7 @@ class D {
|
|
|
937
931
|
return e.protocol === "http:" || e.protocol === "https:";
|
|
938
932
|
}
|
|
939
933
|
}
|
|
940
|
-
class
|
|
934
|
+
class Y {
|
|
941
935
|
constructor() {
|
|
942
936
|
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");
|
|
943
937
|
}
|
|
@@ -952,7 +946,7 @@ class J {
|
|
|
952
946
|
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);
|
|
953
947
|
}
|
|
954
948
|
}
|
|
955
|
-
class
|
|
949
|
+
class J {
|
|
956
950
|
constructor(t, e, i) {
|
|
957
951
|
this.container = t, this.canvas = e, this.loader = i, this.hotspotList = [];
|
|
958
952
|
}
|
|
@@ -1023,7 +1017,7 @@ class y {
|
|
|
1023
1017
|
return new I(e.screenX, e.screenY);
|
|
1024
1018
|
}
|
|
1025
1019
|
}
|
|
1026
|
-
class
|
|
1020
|
+
class V {
|
|
1027
1021
|
constructor(...t) {
|
|
1028
1022
|
t.length === 3 ? ({ 0: this.u, 1: this.v, 2: this.o } = t, this.w = h.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]);
|
|
1029
1023
|
}
|
|
@@ -1032,15 +1026,15 @@ class j {
|
|
|
1032
1026
|
return [...t, ...e, ...i, ...s];
|
|
1033
1027
|
}
|
|
1034
1028
|
get globalToLocalMatrix() {
|
|
1035
|
-
return
|
|
1029
|
+
return c.inverse(this.localToGlobalMatrix);
|
|
1036
1030
|
}
|
|
1037
1031
|
}
|
|
1038
|
-
class
|
|
1032
|
+
class Z {
|
|
1039
1033
|
constructor(t, e, i) {
|
|
1040
1034
|
this.x = t, this.y = e, this.time = i;
|
|
1041
1035
|
}
|
|
1042
1036
|
}
|
|
1043
|
-
class
|
|
1037
|
+
class q {
|
|
1044
1038
|
constructor(t) {
|
|
1045
1039
|
this.points = [], this.onMotion = t, this.lastPoint = new I(0, 0), this.velocity = new I(0, 0), this.loop = this.loop.bind(this);
|
|
1046
1040
|
}
|
|
@@ -1049,7 +1043,7 @@ class G {
|
|
|
1049
1043
|
}
|
|
1050
1044
|
track(t) {
|
|
1051
1045
|
const e = Date.now();
|
|
1052
|
-
this.points = this.points.filter((i) => e - i.time <= 100), this.points.push(new
|
|
1046
|
+
this.points = this.points.filter((i) => e - i.time <= 100), this.points.push(new Z(t.x, t.y, e)), this.lastPoint = t;
|
|
1053
1047
|
}
|
|
1054
1048
|
start() {
|
|
1055
1049
|
if (this.points.length === 0)
|
|
@@ -1068,17 +1062,17 @@ class G {
|
|
|
1068
1062
|
this.lastPoint.x += this.velocity.x, this.lastPoint.y += this.velocity.y, this.velocity.x *= 0.9, this.velocity.y *= 0.9, this.onMotion(this.lastPoint.clone()), this.animationFrameId = requestAnimationFrame(this.loop);
|
|
1069
1063
|
}
|
|
1070
1064
|
}
|
|
1071
|
-
class
|
|
1065
|
+
class Q {
|
|
1072
1066
|
constructor(t, e, i) {
|
|
1073
|
-
this.isStarted = !1, this.pov = t, this.fov = w.degreesToRadians(e), this.orientationMatrix =
|
|
1067
|
+
this.isStarted = !1, this.pov = t, this.fov = w.degreesToRadians(e), this.orientationMatrix = c.identity(), this.inertia = new q(this.motion.bind(this)), this.onMotion = i, this.initPov = this.pov, this.initFov = this.fov, this.initOrientation = w.degreesToRadians(window.orientation) || 0, this.startPov = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), this.startSize = { width: 0, height: 0 }, this.previousPoint = new I(0, 0);
|
|
1074
1068
|
}
|
|
1075
1069
|
destroy() {
|
|
1076
1070
|
this.inertia.destroy();
|
|
1077
1071
|
}
|
|
1078
1072
|
get orientedPov() {
|
|
1079
|
-
const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new
|
|
1080
|
-
|
|
1081
|
-
const s =
|
|
1073
|
+
const t = h.normalize(h.cross(this.pov.up, this.pov.target)), e = new V(t, [0, 1, 0], this.pov.eye), i = c.identity();
|
|
1074
|
+
c.multiply(i, e.localToGlobalMatrix, i), c.multiply(i, this.orientationMatrix, i), c.multiply(i, e.globalToLocalMatrix, i);
|
|
1075
|
+
const s = c.transformDirection(i, this.pov.target), r = this.pov.eye, n = c.transformDirection(i, this.pov.up);
|
|
1082
1076
|
return new L(s, r, n);
|
|
1083
1077
|
}
|
|
1084
1078
|
reset() {
|
|
@@ -1092,20 +1086,20 @@ class W {
|
|
|
1092
1086
|
const e = {
|
|
1093
1087
|
x: t.x - this.previousPoint.x,
|
|
1094
1088
|
y: t.y - this.previousPoint.y
|
|
1095
|
-
}, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r =
|
|
1096
|
-
|
|
1097
|
-
const
|
|
1098
|
-
h.cross(u, [0, 0, 1])[0] >= 0 && (this.pov.target =
|
|
1089
|
+
}, i = w.accelerate(e.x, 1.3) / this.startSize.width * 0.2 * Math.PI * 1.5, s = w.accelerate(e.y, 1.3) / this.startSize.height * 0.2 * Math.PI, r = c.multiply(c.rotationY(i), c.rotationX(-s)), n = h.normalize(h.cross(this.pov.up, this.pov.target)), a = new V(n, [0, 1, 0], this.pov.eye), o = c.identity();
|
|
1090
|
+
c.multiply(o, a.localToGlobalMatrix, o), c.multiply(o, r, o), c.multiply(o, a.globalToLocalMatrix, o);
|
|
1091
|
+
const l = c.transformPoint(o, this.pov.target), u = c.transformDirection(o, this.pov.up);
|
|
1092
|
+
h.cross(u, [0, 0, 1])[0] >= 0 && (this.pov.target = l, this.pov.up = u), this.previousPoint = t, this.onMotion();
|
|
1099
1093
|
}
|
|
1100
1094
|
end(t, e) {
|
|
1101
1095
|
this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
|
|
1102
1096
|
}
|
|
1103
1097
|
orientation(t, e, i) {
|
|
1104
|
-
const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), n = w.degreesToRadians(-e), a = w.degreesToRadians(-i), o =
|
|
1105
|
-
|
|
1098
|
+
const s = w.degreesToRadians(window.orientation) || 0, r = w.degreesToRadians(t), n = w.degreesToRadians(-e), a = w.degreesToRadians(-i), o = c.rotationX(w.degreesToRadians(90));
|
|
1099
|
+
c.rotateZ(o, this.initOrientation, o), c.rotateZ(o, r, o), c.rotateX(o, n, o), c.rotateY(o, a, o), c.rotateZ(o, -s, o), this.orientationMatrix = o, this.onMotion();
|
|
1106
1100
|
}
|
|
1107
1101
|
}
|
|
1108
|
-
var
|
|
1102
|
+
var W = `precision mediump float;
|
|
1109
1103
|
|
|
1110
1104
|
uniform float u_mix;
|
|
1111
1105
|
uniform samplerCube u_texture;
|
|
@@ -1117,7 +1111,7 @@ void main() {
|
|
|
1117
1111
|
vec4 backColor = textureCube(u_texture_back, direction);
|
|
1118
1112
|
vec4 color = textureCube(u_texture, direction);
|
|
1119
1113
|
gl_FragColor = mix(backColor, color, u_mix);
|
|
1120
|
-
}`,
|
|
1114
|
+
}`, _ = `attribute vec4 position;
|
|
1121
1115
|
|
|
1122
1116
|
uniform mat4 u_mvpi;
|
|
1123
1117
|
|
|
@@ -1127,27 +1121,27 @@ void main() {
|
|
|
1127
1121
|
direction = (u_mvpi * position).xyz;
|
|
1128
1122
|
gl_Position = position;
|
|
1129
1123
|
}`;
|
|
1130
|
-
class
|
|
1124
|
+
class K {
|
|
1131
1125
|
constructor(t, e, i, s) {
|
|
1132
1126
|
this.container = t, this.canvas = e, this.loader = i, this.images = [], this.hotspotsList = [[]];
|
|
1133
|
-
const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), n = 60, a =
|
|
1134
|
-
|
|
1127
|
+
const r = new L([0, 0, 1], [0, 0, 0], [0, 1, 0]), n = 60, a = c.rotationX(w.degreesToRadians(15));
|
|
1128
|
+
c.transformDirection(a, r.target, r.target), c.transformDirection(a, r.up, r.up), this.interaction = new Q(r, n, () => {
|
|
1135
1129
|
this.animationFrameId = requestAnimationFrame(this.render), this.onInteraction({
|
|
1136
1130
|
pov: this.interaction.pov.clone(),
|
|
1137
1131
|
fov: this.interaction.fov
|
|
1138
1132
|
});
|
|
1139
|
-
}), this.onInteraction = s, this.gl = this.canvas.context, this.programInfo =
|
|
1140
|
-
`, `${
|
|
1141
|
-
`]), this.quad =
|
|
1142
|
-
u_mvpi:
|
|
1133
|
+
}), this.onInteraction = s, this.gl = this.canvas.context, this.programInfo = P.createProgramInfo(this.gl, [`${_}
|
|
1134
|
+
`, `${W}
|
|
1135
|
+
`]), this.quad = P.primitives.createXYQuadBufferInfo(this.gl), this.uniforms = {
|
|
1136
|
+
u_mvpi: c.identity(),
|
|
1143
1137
|
u_mix: 0,
|
|
1144
|
-
u_texture_back:
|
|
1138
|
+
u_texture_back: P.createTexture(this.gl, {
|
|
1145
1139
|
target: this.gl.TEXTURE_CUBE_MAP,
|
|
1146
1140
|
minMag: this.gl.LINEAR,
|
|
1147
1141
|
width: 1,
|
|
1148
1142
|
height: 1
|
|
1149
1143
|
}),
|
|
1150
|
-
u_texture:
|
|
1144
|
+
u_texture: P.createTexture(this.gl, {
|
|
1151
1145
|
target: this.gl.TEXTURE_CUBE_MAP,
|
|
1152
1146
|
minMag: this.gl.LINEAR,
|
|
1153
1147
|
width: 1,
|
|
@@ -1185,7 +1179,7 @@ class tt {
|
|
|
1185
1179
|
const n = JSON.stringify(t);
|
|
1186
1180
|
n === this.snapshotHash ? r = r.then(() => (this.animationFrameId = requestAnimationFrame(this.render), Promise.resolve())) : (this.images = [], this.animationFrameId = requestAnimationFrame(this.render), r = r.then(
|
|
1187
1181
|
() => this.loader.loadVRCubeSnapshot(t).then((o) => {
|
|
1188
|
-
this.images = o,
|
|
1182
|
+
this.images = o, P.createTexture(
|
|
1189
1183
|
this.gl,
|
|
1190
1184
|
{
|
|
1191
1185
|
target: this.gl.TEXTURE_CUBE_MAP,
|
|
@@ -1202,8 +1196,8 @@ class tt {
|
|
|
1202
1196
|
],
|
|
1203
1197
|
src: o
|
|
1204
1198
|
},
|
|
1205
|
-
(
|
|
1206
|
-
|
|
1199
|
+
(l, u) => {
|
|
1200
|
+
l || (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));
|
|
1207
1201
|
}
|
|
1208
1202
|
);
|
|
1209
1203
|
})
|
|
@@ -1216,73 +1210,72 @@ class tt {
|
|
|
1216
1210
|
) : this.hotspotsList = [[]]), this.hotspotsHash = a, this.snapshotHash = n, r;
|
|
1217
1211
|
}
|
|
1218
1212
|
async pick(t, e) {
|
|
1219
|
-
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,
|
|
1213
|
+
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, l = [a, o, 0], u = this.modelViewProjectionMatrix, f = c.inverse(u), d = h.normalize(c.transformPoint(f, l)), T = Math.max(Math.abs(d[0]), Math.abs(d[1]), Math.abs(d[2]));
|
|
1220
1214
|
let F = "";
|
|
1221
|
-
Math.abs(
|
|
1222
|
-
let
|
|
1215
|
+
Math.abs(d[0]) === T ? F = d[0] > 0 ? "XPOS" : "XNEG" : Math.abs(d[1]) === T ? F = d[1] > 0 ? "YPOS" : "YNEG" : F = d[2] > 0 ? "ZPOS" : "ZNEG";
|
|
1216
|
+
let x = 0, M = 0, E = "";
|
|
1223
1217
|
switch (F) {
|
|
1224
1218
|
case "XPOS":
|
|
1225
|
-
|
|
1219
|
+
x = (-d[2] / Math.abs(d[0]) + 1) / 2, M = (-d[1] / Math.abs(d[0]) + 1) / 2, E = "right";
|
|
1226
1220
|
break;
|
|
1227
1221
|
case "XNEG":
|
|
1228
|
-
|
|
1222
|
+
x = (d[2] / Math.abs(d[0]) + 1) / 2, M = (-d[1] / Math.abs(d[0]) + 1) / 2, E = "left";
|
|
1229
1223
|
break;
|
|
1230
1224
|
case "YPOS":
|
|
1231
|
-
|
|
1225
|
+
x = (d[0] / Math.abs(d[1]) + 1) / 2, M = (d[2] / Math.abs(d[1]) + 1) / 2, E = "up";
|
|
1232
1226
|
break;
|
|
1233
1227
|
case "YNEG":
|
|
1234
|
-
|
|
1228
|
+
x = (d[0] / Math.abs(d[1]) + 1) / 2, M = (-d[2] / Math.abs(d[1]) + 1) / 2, E = "down";
|
|
1235
1229
|
break;
|
|
1236
1230
|
case "ZPOS":
|
|
1237
|
-
|
|
1231
|
+
x = (d[0] / Math.abs(d[2]) + 1) / 2, M = (-d[1] / Math.abs(d[2]) + 1) / 2, E = "front";
|
|
1238
1232
|
break;
|
|
1239
1233
|
case "ZNEG":
|
|
1240
|
-
|
|
1234
|
+
x = (-d[0] / Math.abs(d[2]) + 1) / 2, M = (-d[1] / Math.abs(d[2]) + 1) / 2, E = "back";
|
|
1241
1235
|
break;
|
|
1242
1236
|
}
|
|
1243
|
-
const
|
|
1244
|
-
x: Math.round(
|
|
1245
|
-
y: Math.round(
|
|
1237
|
+
const C = {
|
|
1238
|
+
x: Math.round(x * Math.max(t.parameters.width, t.parameters.height)),
|
|
1239
|
+
y: Math.round(M * Math.max(t.parameters.width, t.parameters.height))
|
|
1246
1240
|
};
|
|
1247
|
-
return this.loader.loadVRCubePick(t,
|
|
1241
|
+
return this.loader.loadVRCubePick(t, C, E);
|
|
1248
1242
|
}
|
|
1249
1243
|
hotspots() {
|
|
1250
|
-
var s;
|
|
1251
1244
|
const t = [];
|
|
1252
1245
|
if (this.hotspotsList.length === 0)
|
|
1253
1246
|
return [];
|
|
1254
|
-
const e =
|
|
1255
|
-
for (let
|
|
1256
|
-
const
|
|
1257
|
-
if (
|
|
1247
|
+
const e = this.hotspotsList[0]?.length ?? 0, i = this.modelViewProjectionMatrix;
|
|
1248
|
+
for (let s = 0; s < e; s++) {
|
|
1249
|
+
const r = this.hotspotsList.findIndex((R) => R[s].visibility !== "OutOfFrustum");
|
|
1250
|
+
if (r === -1)
|
|
1258
1251
|
continue;
|
|
1259
|
-
const
|
|
1260
|
-
let
|
|
1261
|
-
switch (
|
|
1252
|
+
const n = { ...this.hotspotsList[r][s] }, a = n.position2D.x / this.images[0].width, o = n.position2D.y / this.images[0].height;
|
|
1253
|
+
let l = 0, u = 0, f = 0;
|
|
1254
|
+
switch (r) {
|
|
1262
1255
|
case 0:
|
|
1263
|
-
this.pov.target[2] < 0 && (
|
|
1256
|
+
this.pov.target[2] < 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = 1 - 2 * o, f = 1;
|
|
1264
1257
|
break;
|
|
1265
1258
|
case 1:
|
|
1266
|
-
this.pov.target[0] > 0 && (
|
|
1259
|
+
this.pov.target[0] > 0 && (n.visibility = "OutOfFrustum"), l = 1, u = 1 - 2 * o, f = 1 - 2 * a;
|
|
1267
1260
|
break;
|
|
1268
1261
|
case 2:
|
|
1269
|
-
this.pov.target[2] > 0 && (
|
|
1262
|
+
this.pov.target[2] > 0 && (n.visibility = "OutOfFrustum"), l = 1 - 2 * a, u = 1 - 2 * o, f = -1;
|
|
1270
1263
|
break;
|
|
1271
1264
|
case 3:
|
|
1272
|
-
this.pov.target[0] < 0 && (
|
|
1265
|
+
this.pov.target[0] < 0 && (n.visibility = "OutOfFrustum"), l = -1, u = 1 - 2 * o, f = 2 * a - 1;
|
|
1273
1266
|
break;
|
|
1274
1267
|
case 4:
|
|
1275
|
-
this.pov.target[1] < 0 && (
|
|
1268
|
+
this.pov.target[1] < 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = 1, f = 2 * o - 1;
|
|
1276
1269
|
break;
|
|
1277
1270
|
case 5:
|
|
1278
|
-
this.pov.target[1] > 0 && (
|
|
1271
|
+
this.pov.target[1] > 0 && (n.visibility = "OutOfFrustum"), l = 2 * a - 1, u = -1, f = 1 - 2 * o;
|
|
1279
1272
|
break;
|
|
1280
1273
|
}
|
|
1281
|
-
const
|
|
1282
|
-
x: Math.round(
|
|
1283
|
-
y: Math.round(x -
|
|
1284
|
-
},
|
|
1285
|
-
t.push({ ...
|
|
1274
|
+
const d = h.normalize([l, u, f]), T = c.transformPoint(i, d), F = this.canvas.element.clientWidth, x = this.canvas.element.clientHeight, M = 0.5 * F * (T[0] + 1), E = 0.5 * x * (T[1] + 1), C = {
|
|
1275
|
+
x: Math.round(M),
|
|
1276
|
+
y: Math.round(x - E)
|
|
1277
|
+
}, G = new b(F, x), z = p.contains(G, C) ? n.visibility : "OutOfFrustum";
|
|
1278
|
+
t.push({ ...n, position2D: C, visibility: z });
|
|
1286
1279
|
}
|
|
1287
1280
|
return t;
|
|
1288
1281
|
}
|
|
@@ -1290,11 +1283,11 @@ class tt {
|
|
|
1290
1283
|
return this.canvas.element.toDataURL(t, e);
|
|
1291
1284
|
}
|
|
1292
1285
|
get modelViewProjectionMatrix() {
|
|
1293
|
-
const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i), n =
|
|
1294
|
-
return
|
|
1286
|
+
const t = this.canvas.element.clientWidth, e = this.canvas.element.clientHeight, i = t > e ? t / e : e / t, s = p.getStandardAspectRatio(t, e), r = this.interaction.fov * (s / i), n = c.setAxis(c.identity(), [-1, 0, 0], 0), a = t > e ? w.perspectiveWithFovY(r, t / e, 0.5, 100) : w.perspectiveWithFovX(r, t / e, 0.5, 100), o = this.interaction.orientedPov, l = c.inverse(c.lookAt(o.eye, o.target, o.up));
|
|
1287
|
+
return c.multiply(c.multiply(a, l), n);
|
|
1295
1288
|
}
|
|
1296
1289
|
render() {
|
|
1297
|
-
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi =
|
|
1290
|
+
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), this.uniforms.u_mvpi = c.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 + 0.05, 1), this.animationFrameId = requestAnimationFrame(this.render));
|
|
1298
1291
|
}
|
|
1299
1292
|
onMouseDown(t) {
|
|
1300
1293
|
this.container.classList.add("ls-viewer-container-vrcube-grabbing"), this.interaction.start(y.pointFromMouseEvent(t), {
|
|
@@ -1327,9 +1320,9 @@ class tt {
|
|
|
1327
1320
|
this.interaction.orientation(t.alpha, t.beta, t.gamma);
|
|
1328
1321
|
}
|
|
1329
1322
|
}
|
|
1330
|
-
class
|
|
1323
|
+
class tt {
|
|
1331
1324
|
constructor(t, e, i, s, r) {
|
|
1332
|
-
this.isStarted = !1, this.position = t, this.frames = e, this.rows = i, this.loop = s, this.onMotion = r, this.inertia = new
|
|
1325
|
+
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 I(0, 0), this.startSize = { width: 0, height: 0 }, this.lastPoints = [], this.lastPointsNumber = 20;
|
|
1333
1326
|
}
|
|
1334
1327
|
destroy() {
|
|
1335
1328
|
this.inertia.destroy();
|
|
@@ -1351,7 +1344,7 @@ class et {
|
|
|
1351
1344
|
}
|
|
1352
1345
|
motion(t) {
|
|
1353
1346
|
this.isStarted && this.inertia.track(t), this.lastPoints.push({ x: t.x, y: t.y }), this.lastPoints.splice(0, this.lastPoints.length - this.lastPointsNumber);
|
|
1354
|
-
const e =
|
|
1347
|
+
const e = $.linear(this.lastPoints.map((s) => [s.x, s.y])), i = 25;
|
|
1355
1348
|
if (Math.abs(e.equation[0]) < 1) {
|
|
1356
1349
|
const s = w.accelerate(t.x - this.startPoint.x, 1.3) / this.startSize.width * (this.frames / 4);
|
|
1357
1350
|
let r = this.startPosition.x - Math.round(s);
|
|
@@ -1370,9 +1363,9 @@ class et {
|
|
|
1370
1363
|
this.isStarted = !1, e && (this.inertia.track(t), this.inertia.start());
|
|
1371
1364
|
}
|
|
1372
1365
|
}
|
|
1373
|
-
class
|
|
1366
|
+
class O {
|
|
1374
1367
|
constructor(t, e, i, s) {
|
|
1375
|
-
this.container = t, this.canvas = e, this.loader = i, this.images = [], this.frames = 24, this.hotspotsList = [[]], this.interaction = new
|
|
1368
|
+
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, () => {
|
|
1376
1369
|
this.canvas.draw(this.image, !0, 0.5), this.onInteraction({
|
|
1377
1370
|
position: this.interaction.positionIndex
|
|
1378
1371
|
});
|
|
@@ -1416,10 +1409,10 @@ class C {
|
|
|
1416
1409
|
const n = JSON.stringify(t);
|
|
1417
1410
|
n === this.snapshotHash && this.image ? r = r.then(() => this.canvas.draw(this.image, s, 0.05)) : (this.images = [], r = r.then(
|
|
1418
1411
|
() => this.loader.loadVRObjectSnapshot(t, this.interaction.positionIndex).then((o) => {
|
|
1419
|
-
const
|
|
1420
|
-
return this.images = new Array(
|
|
1421
|
-
u.then((
|
|
1422
|
-
this.images[f] =
|
|
1412
|
+
const l = o.length;
|
|
1413
|
+
return this.images = new Array(l), this.interaction.frames = t.view.frames ?? t.view.panFrames ?? this.frames, this.interaction.rows = l / this.interaction.frames, this.interaction.loop = !!t.view.loop, i && this.interaction.reset(), o.forEach((u, f) => {
|
|
1414
|
+
u.then((d) => {
|
|
1415
|
+
this.images[f] = d, d === this.image && this.canvas.draw(this.image, s, 0.05);
|
|
1423
1416
|
}).catch(() => {
|
|
1424
1417
|
});
|
|
1425
1418
|
}), o[this.interaction.positionIndex].then(() => Promise.resolve());
|
|
@@ -1472,7 +1465,7 @@ class C {
|
|
|
1472
1465
|
onDeviceOrientation(t) {
|
|
1473
1466
|
}
|
|
1474
1467
|
}
|
|
1475
|
-
class
|
|
1468
|
+
class et {
|
|
1476
1469
|
constructor(t, e, i) {
|
|
1477
1470
|
this.container = t, this.loader = i, this.video = e;
|
|
1478
1471
|
}
|
|
@@ -1556,7 +1549,7 @@ class nt {
|
|
|
1556
1549
|
onHotspotsChange: () => {
|
|
1557
1550
|
},
|
|
1558
1551
|
...e.events
|
|
1559
|
-
}, 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
|
|
1552
|
+
}, 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 U(this.options.fit), this.container.prepend(this.canvas2D.element), this.canvas3D = new N(), this.container.prepend(this.canvas3D.element), this.video = new Y(), this.container.prepend(this.video.element), this.loader = new D(this.options.server, this.options.api, this), this.resolution = new b(0, 0), this.parameters = {
|
|
1560
1553
|
width: 0,
|
|
1561
1554
|
height: 0,
|
|
1562
1555
|
antialiasing: !1,
|
|
@@ -1564,14 +1557,14 @@ class nt {
|
|
|
1564
1557
|
}, this.encoder = {
|
|
1565
1558
|
format: "jpeg",
|
|
1566
1559
|
quality: 80
|
|
1567
|
-
}, this.hotspots = [], this.widgetImage = new
|
|
1560
|
+
}, this.hotspots = [], this.widgetImage = new J(t, this.canvas2D, this.loader), this.widgetVideo = new et(t, this.video, this.loader), this.widgetVRObject = new O(t, this.canvas2D, this.loader, this.onVrobjectInteraction), this.canvas3D.context && (this.widgetVRCube = new K(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);
|
|
1568
1561
|
}
|
|
1569
1562
|
destroy() {
|
|
1570
1563
|
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;
|
|
1571
1564
|
}
|
|
1572
1565
|
async load(t, e) {
|
|
1573
1566
|
let i = Promise.resolve();
|
|
1574
|
-
return e
|
|
1567
|
+
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) => {
|
|
1575
1568
|
this.onLoadError(s);
|
|
1576
1569
|
}), i;
|
|
1577
1570
|
}
|
|
@@ -1594,9 +1587,9 @@ class nt {
|
|
|
1594
1587
|
}
|
|
1595
1588
|
async setView(t, e) {
|
|
1596
1589
|
let i = Promise.resolve();
|
|
1597
|
-
return e
|
|
1590
|
+
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(() => {
|
|
1598
1591
|
let s = !0;
|
|
1599
|
-
return this.view = { ...t }, this.view && this.viewWidget instanceof
|
|
1592
|
+
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));
|
|
1600
1593
|
}), i.catch((s) => {
|
|
1601
1594
|
this.onLoadError(s);
|
|
1602
1595
|
}), i;
|
|
@@ -1608,7 +1601,6 @@ class nt {
|
|
|
1608
1601
|
Object.assign(this.widgetVRObject, t);
|
|
1609
1602
|
}
|
|
1610
1603
|
async loadAnimation(t) {
|
|
1611
|
-
var i;
|
|
1612
1604
|
const e = {
|
|
1613
1605
|
scene: this.scene,
|
|
1614
1606
|
view: {
|
|
@@ -1623,7 +1615,7 @@ class nt {
|
|
|
1623
1615
|
format: "mp4"
|
|
1624
1616
|
}
|
|
1625
1617
|
};
|
|
1626
|
-
return
|
|
1618
|
+
return e.view?.background || (e.view.background = "product"), this.widgetVideo.load(e).then(() => Promise.resolve());
|
|
1627
1619
|
}
|
|
1628
1620
|
async playAnimation(t) {
|
|
1629
1621
|
return this.loadAnimation(t).then(() => this.widgetVideo.play()).catch((e) => {
|
|
@@ -1672,8 +1664,7 @@ class nt {
|
|
|
1672
1664
|
});
|
|
1673
1665
|
}
|
|
1674
1666
|
get viewWidget() {
|
|
1675
|
-
|
|
1676
|
-
switch ((t = this.view) == null ? void 0 : t.mode) {
|
|
1667
|
+
switch (this.view?.mode) {
|
|
1677
1668
|
case "image":
|
|
1678
1669
|
return this.widgetImage;
|
|
1679
1670
|
case "video":
|
|
@@ -1747,7 +1738,7 @@ class nt {
|
|
|
1747
1738
|
this.container.classList.remove("ls-viewer-container-loading"), this.options.events.onLoadError(...t);
|
|
1748
1739
|
}
|
|
1749
1740
|
}
|
|
1750
|
-
var
|
|
1741
|
+
var j;
|
|
1751
1742
|
((v) => {
|
|
1752
1743
|
((t) => {
|
|
1753
1744
|
t.Visible = "Visible", t.Occluded = "Occluded", t.Clipped = "Clipped", t.OutOfFrustum = "OutOfFrustum";
|
|
@@ -1760,12 +1751,12 @@ var H;
|
|
|
1760
1751
|
})(v.SunUseCaseMode || (v.SunUseCaseMode = {})), ((t) => {
|
|
1761
1752
|
t.ShowOnly = "showOnly", t.HideOnly = "hideOnly";
|
|
1762
1753
|
})(v.SurfacesFilterMode || (v.SurfacesFilterMode = {}));
|
|
1763
|
-
})(
|
|
1754
|
+
})(j || (j = {}));
|
|
1764
1755
|
export {
|
|
1765
1756
|
nt as Viewer,
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1757
|
+
j as WRAPIv2,
|
|
1758
|
+
J as WidgetImage,
|
|
1759
|
+
K as WidgetVRCube,
|
|
1760
|
+
O as WidgetVRObject,
|
|
1761
|
+
et as WidgetVideo
|
|
1771
1762
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumiscaphe/viewer",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.16",
|
|
4
4
|
"description": "Lumiscaphe 3D Viewer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/lib/index.cjs",
|
|
@@ -18,20 +18,20 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"debounce-promise": "~3.1.0",
|
|
20
20
|
"regression": "~2.0.0",
|
|
21
|
-
"twgl.js": "~
|
|
21
|
+
"twgl.js": "~7.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/debounce-promise": "~3.1.3",
|
|
25
|
-
"@types/node": "~
|
|
25
|
+
"@types/node": "~24.0.0",
|
|
26
26
|
"@types/regression": "~2.0.0",
|
|
27
|
-
"eslint": "~9.
|
|
27
|
+
"eslint": "~9.39.0",
|
|
28
28
|
"husky": "~9.1.0",
|
|
29
|
-
"typescript": "~5.
|
|
30
|
-
"typescript-eslint": "~8.
|
|
31
|
-
"vite": "~
|
|
29
|
+
"typescript": "~5.9.0",
|
|
30
|
+
"typescript-eslint": "~8.52.0",
|
|
31
|
+
"vite": "~7.3.0",
|
|
32
32
|
"vite-plugin-css-injected-by-js": "~3.5.0",
|
|
33
33
|
"vite-plugin-dts": "~4.5.0",
|
|
34
34
|
"vite-plugin-eslint": "~1.8.0",
|
|
35
|
-
"vite-plugin-glsl": "~1.
|
|
35
|
+
"vite-plugin-glsl": "~1.5.0"
|
|
36
36
|
}
|
|
37
37
|
}
|