Spaces:
Running
Running
Update index_sans_gif.js
Browse files- index_sans_gif.js +24 -52
index_sans_gif.js
CHANGED
@@ -30,14 +30,12 @@
|
|
30 |
var plyUrl = config.ply_url;
|
31 |
|
32 |
// Optional parameters for zoom and rotation limits.
|
33 |
-
// Defaults: zoom from 0 to 20; rotation from 0 to 360.
|
34 |
var minZoom = parseFloat(config.minZoom || "0");
|
35 |
var maxZoom = parseFloat(config.maxZoom || "20");
|
36 |
var minAngle = parseFloat(config.minAngle || "0");
|
37 |
var maxAngle = parseFloat(config.maxAngle || "360");
|
38 |
|
39 |
// Determine the aspect ratio.
|
40 |
-
// Default aspect: 1:1 (i.e. 100% padding-bottom)
|
41 |
var aspectPercent = "100%";
|
42 |
if (config.aspect) {
|
43 |
if (config.aspect.indexOf(":") !== -1) {
|
@@ -54,7 +52,6 @@
|
|
54 |
}
|
55 |
}
|
56 |
} else {
|
57 |
-
// If no aspect parameter is provided, compute the aspect ratio from the parent element.
|
58 |
var parentContainer = scriptTag.parentNode;
|
59 |
var containerWidth = parentContainer.offsetWidth;
|
60 |
var containerHeight = parentContainer.offsetHeight;
|
@@ -63,10 +60,9 @@
|
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
// Detect if the device is iOS.
|
67 |
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
68 |
|
69 |
-
// Inject CSS styles into the document head
|
70 |
var styleEl = document.createElement('style');
|
71 |
styleEl.textContent = `
|
72 |
/* Widget container styling */
|
@@ -88,7 +84,6 @@
|
|
88 |
}
|
89 |
/* Viewer Container styling */
|
90 |
#viewer-container-${instanceId} {
|
91 |
-
/* Display the viewer by default */
|
92 |
display: block;
|
93 |
position: absolute;
|
94 |
top: 0;
|
@@ -105,7 +100,7 @@
|
|
105 |
height: 100%;
|
106 |
display: block;
|
107 |
}
|
108 |
-
/* Progress dialog styling
|
109 |
#progress-dialog-${instanceId} {
|
110 |
position: absolute;
|
111 |
top: 50%;
|
@@ -147,8 +142,6 @@
|
|
147 |
align-items: center;
|
148 |
justify-content: center;
|
149 |
}
|
150 |
-
/* Positions: fullscreen at top-right, help (instructions) below fullscreen,
|
151 |
-
and reset camera below help */
|
152 |
#fullscreen-toggle-${instanceId} {
|
153 |
top: 17px;
|
154 |
right: 15px;
|
@@ -164,18 +157,16 @@
|
|
164 |
line-height: 1;
|
165 |
padding: 0;
|
166 |
}
|
167 |
-
/* Adjust the ⟲ icon position within the reset camera button */
|
168 |
.reset-icon {
|
169 |
display: inline-block;
|
170 |
}
|
171 |
`;
|
172 |
document.head.appendChild(styleEl);
|
173 |
|
174 |
-
// Create the widget container
|
175 |
var widgetContainer = document.createElement('div');
|
176 |
widgetContainer.id = 'ply-widget-container-' + instanceId;
|
177 |
widgetContainer.innerHTML = `
|
178 |
-
<!-- Viewer Container (displayed directly) -->
|
179 |
<div id="viewer-container-${instanceId}">
|
180 |
<canvas id="canvas-${instanceId}"></canvas>
|
181 |
<div id="progress-dialog-${instanceId}">
|
@@ -195,7 +186,7 @@
|
|
195 |
`;
|
196 |
scriptTag.parentNode.appendChild(widgetContainer);
|
197 |
|
198 |
-
// Grab element references
|
199 |
var viewerContainer = document.getElementById('viewer-container-' + instanceId);
|
200 |
var fullscreenToggle = document.getElementById('fullscreen-toggle-' + instanceId);
|
201 |
var helpToggle = document.getElementById('help-toggle-' + instanceId);
|
@@ -206,40 +197,21 @@
|
|
206 |
var progressIndicator = document.getElementById('progress-indicator-' + instanceId);
|
207 |
|
208 |
// --- Button Event Handlers ---
|
209 |
-
|
210 |
fullscreenToggle.addEventListener('click', function() {
|
211 |
if (isIOS) {
|
212 |
-
|
213 |
-
widgetContainer.classList.add('fake-fullscreen');
|
214 |
-
} else {
|
215 |
-
widgetContainer.classList.remove('fake-fullscreen');
|
216 |
-
}
|
217 |
fullscreenToggle.textContent = widgetContainer.classList.contains('fake-fullscreen') ? '⇲' : '⇱';
|
218 |
} else {
|
219 |
if (!document.fullscreenElement) {
|
220 |
-
|
221 |
-
widgetContainer.requestFullscreen();
|
222 |
-
} else if (widgetContainer.webkitRequestFullscreen) {
|
223 |
-
widgetContainer.webkitRequestFullscreen();
|
224 |
-
} else if (widgetContainer.mozRequestFullScreen) {
|
225 |
-
widgetContainer.mozRequestFullScreen();
|
226 |
-
} else if (widgetContainer.msRequestFullscreen) {
|
227 |
-
widgetContainer.msRequestFullscreen();
|
228 |
-
}
|
229 |
} else {
|
230 |
-
|
231 |
-
document.exitFullscreen();
|
232 |
-
}
|
233 |
}
|
234 |
}
|
235 |
});
|
236 |
|
237 |
document.addEventListener('fullscreenchange', function() {
|
238 |
-
|
239 |
-
fullscreenToggle.textContent = '⇲';
|
240 |
-
} else {
|
241 |
-
fullscreenToggle.textContent = '⇱';
|
242 |
-
}
|
243 |
});
|
244 |
|
245 |
helpToggle.addEventListener('click', function(e) {
|
@@ -247,13 +219,17 @@
|
|
247 |
menuContent.style.display = (menuContent.style.display === 'block') ? 'none' : 'block';
|
248 |
});
|
249 |
|
|
|
250 |
resetCameraBtn.addEventListener('click', function() {
|
251 |
console.log("Reset camera button clicked.");
|
252 |
-
if (cameraInstance
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
cameraInstance.
|
|
|
|
|
|
|
257 |
}
|
258 |
if (controlsInstance && typeof controlsInstance.update === 'function') {
|
259 |
controlsInstance.update();
|
@@ -267,21 +243,17 @@
|
|
267 |
progressDialog.style.display = 'block';
|
268 |
const renderer = new SPLAT.WebGLRenderer(canvas);
|
269 |
const scene = new SPLAT.Scene();
|
|
|
|
|
270 |
const camera = new SPLAT.Camera();
|
|
|
|
|
|
|
271 |
const controls = new SPLAT.OrbitControls(camera, canvas);
|
272 |
-
|
273 |
-
// Set the initial camera position from the config.
|
274 |
-
if (config.cameraPosition &&
|
275 |
-
Array.isArray(config.cameraPosition) &&
|
276 |
-
config.cameraPosition.length === 3) {
|
277 |
-
// Since camera.position.set is not available, assign each coordinate.
|
278 |
-
camera.position.x = config.cameraPosition[0];
|
279 |
-
camera.position.y = config.cameraPosition[1];
|
280 |
-
camera.position.z = config.cameraPosition[2];
|
281 |
-
}
|
282 |
-
|
283 |
cameraInstance = camera;
|
284 |
controlsInstance = controls;
|
|
|
285 |
initialCameraPosition = camera.position.clone();
|
286 |
initialCameraRotation = camera.rotation.clone();
|
287 |
|
|
|
30 |
var plyUrl = config.ply_url;
|
31 |
|
32 |
// Optional parameters for zoom and rotation limits.
|
|
|
33 |
var minZoom = parseFloat(config.minZoom || "0");
|
34 |
var maxZoom = parseFloat(config.maxZoom || "20");
|
35 |
var minAngle = parseFloat(config.minAngle || "0");
|
36 |
var maxAngle = parseFloat(config.maxAngle || "360");
|
37 |
|
38 |
// Determine the aspect ratio.
|
|
|
39 |
var aspectPercent = "100%";
|
40 |
if (config.aspect) {
|
41 |
if (config.aspect.indexOf(":") !== -1) {
|
|
|
52 |
}
|
53 |
}
|
54 |
} else {
|
|
|
55 |
var parentContainer = scriptTag.parentNode;
|
56 |
var containerWidth = parentContainer.offsetWidth;
|
57 |
var containerHeight = parentContainer.offsetHeight;
|
|
|
60 |
}
|
61 |
}
|
62 |
|
|
|
63 |
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
64 |
|
65 |
+
// Inject CSS styles into the document head.
|
66 |
var styleEl = document.createElement('style');
|
67 |
styleEl.textContent = `
|
68 |
/* Widget container styling */
|
|
|
84 |
}
|
85 |
/* Viewer Container styling */
|
86 |
#viewer-container-${instanceId} {
|
|
|
87 |
display: block;
|
88 |
position: absolute;
|
89 |
top: 0;
|
|
|
100 |
height: 100%;
|
101 |
display: block;
|
102 |
}
|
103 |
+
/* Progress dialog styling */
|
104 |
#progress-dialog-${instanceId} {
|
105 |
position: absolute;
|
106 |
top: 50%;
|
|
|
142 |
align-items: center;
|
143 |
justify-content: center;
|
144 |
}
|
|
|
|
|
145 |
#fullscreen-toggle-${instanceId} {
|
146 |
top: 17px;
|
147 |
right: 15px;
|
|
|
157 |
line-height: 1;
|
158 |
padding: 0;
|
159 |
}
|
|
|
160 |
.reset-icon {
|
161 |
display: inline-block;
|
162 |
}
|
163 |
`;
|
164 |
document.head.appendChild(styleEl);
|
165 |
|
166 |
+
// Create the widget container.
|
167 |
var widgetContainer = document.createElement('div');
|
168 |
widgetContainer.id = 'ply-widget-container-' + instanceId;
|
169 |
widgetContainer.innerHTML = `
|
|
|
170 |
<div id="viewer-container-${instanceId}">
|
171 |
<canvas id="canvas-${instanceId}"></canvas>
|
172 |
<div id="progress-dialog-${instanceId}">
|
|
|
186 |
`;
|
187 |
scriptTag.parentNode.appendChild(widgetContainer);
|
188 |
|
189 |
+
// Grab element references.
|
190 |
var viewerContainer = document.getElementById('viewer-container-' + instanceId);
|
191 |
var fullscreenToggle = document.getElementById('fullscreen-toggle-' + instanceId);
|
192 |
var helpToggle = document.getElementById('help-toggle-' + instanceId);
|
|
|
197 |
var progressIndicator = document.getElementById('progress-indicator-' + instanceId);
|
198 |
|
199 |
// --- Button Event Handlers ---
|
|
|
200 |
fullscreenToggle.addEventListener('click', function() {
|
201 |
if (isIOS) {
|
202 |
+
widgetContainer.classList.toggle('fake-fullscreen');
|
|
|
|
|
|
|
|
|
203 |
fullscreenToggle.textContent = widgetContainer.classList.contains('fake-fullscreen') ? '⇲' : '⇱';
|
204 |
} else {
|
205 |
if (!document.fullscreenElement) {
|
206 |
+
widgetContainer.requestFullscreen ? widgetContainer.requestFullscreen() : null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
} else {
|
208 |
+
document.exitFullscreen ? document.exitFullscreen() : null;
|
|
|
|
|
209 |
}
|
210 |
}
|
211 |
});
|
212 |
|
213 |
document.addEventListener('fullscreenchange', function() {
|
214 |
+
fullscreenToggle.textContent = (document.fullscreenElement === widgetContainer) ? '⇲' : '⇱';
|
|
|
|
|
|
|
|
|
215 |
});
|
216 |
|
217 |
helpToggle.addEventListener('click', function(e) {
|
|
|
219 |
menuContent.style.display = (menuContent.style.display === 'block') ? 'none' : 'block';
|
220 |
});
|
221 |
|
222 |
+
// Update the reset button to use the JSON cameraPosition.
|
223 |
resetCameraBtn.addEventListener('click', function() {
|
224 |
console.log("Reset camera button clicked.");
|
225 |
+
if (cameraInstance) {
|
226 |
+
if (config.cameraPosition &&
|
227 |
+
Array.isArray(config.cameraPosition) &&
|
228 |
+
config.cameraPosition.length === 3) {
|
229 |
+
cameraInstance.position.x = config.cameraPosition[0];
|
230 |
+
cameraInstance.position.y = config.cameraPosition[1];
|
231 |
+
cameraInstance.position.z = config.cameraPosition[2];
|
232 |
+
if (typeof cameraInstance.update === 'function') cameraInstance.update();
|
233 |
}
|
234 |
if (controlsInstance && typeof controlsInstance.update === 'function') {
|
235 |
controlsInstance.update();
|
|
|
243 |
progressDialog.style.display = 'block';
|
244 |
const renderer = new SPLAT.WebGLRenderer(canvas);
|
245 |
const scene = new SPLAT.Scene();
|
246 |
+
|
247 |
+
// Create the camera with default initialization.
|
248 |
const camera = new SPLAT.Camera();
|
249 |
+
// Do NOT set the camera's position from JSON here.
|
250 |
+
|
251 |
+
// Create OrbitControls after the camera is created.
|
252 |
const controls = new SPLAT.OrbitControls(camera, canvas);
|
253 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
cameraInstance = camera;
|
255 |
controlsInstance = controls;
|
256 |
+
// Capture the camera's default initial values.
|
257 |
initialCameraPosition = camera.position.clone();
|
258 |
initialCameraRotation = camera.rotation.clone();
|
259 |
|