Spaces:
Running
Running
Update js_scripts/index.js
Browse files- js_scripts/index.js +78 -27
js_scripts/index.js
CHANGED
|
@@ -58,6 +58,8 @@ const currentScriptTag = document.currentScript;
|
|
| 58 |
let cameraEntity = null;
|
| 59 |
let app = null;
|
| 60 |
let modelEntity = null;
|
|
|
|
|
|
|
| 61 |
|
| 62 |
// Generate a unique identifier for this widget instance.
|
| 63 |
const instanceId = Math.random().toString(36).substr(2, 8);
|
|
@@ -225,7 +227,29 @@ const currentScriptTag = document.currentScript;
|
|
| 225 |
});
|
| 226 |
}
|
| 227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
closeBtn.addEventListener('click', function() {
|
|
|
|
| 229 |
if (document.fullscreenElement === widgetContainer) {
|
| 230 |
if (document.exitFullscreen) {
|
| 231 |
document.exitFullscreen();
|
|
@@ -234,8 +258,12 @@ const currentScriptTag = document.currentScript;
|
|
| 234 |
if (widgetContainer.classList.contains('fake-fullscreen')) {
|
| 235 |
widgetContainer.classList.remove('fake-fullscreen');
|
| 236 |
fullscreenToggle.textContent = '⇱';
|
| 237 |
-
resetCamera();
|
| 238 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
viewerContainer.style.display = 'none';
|
| 240 |
gifPreview.style.display = 'block';
|
| 241 |
});
|
|
@@ -380,38 +408,55 @@ const currentScriptTag = document.currentScript;
|
|
| 380 |
});
|
| 381 |
|
| 382 |
// --- Prevent app from hijacking all wheel events ---
|
| 383 |
-
|
| 384 |
-
//
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
}
|
|
|
|
| 389 |
|
| 390 |
-
//
|
| 391 |
-
event
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
const sensitivity = cameraEntity.script.orbitCameraInputMouse ?
|
| 397 |
-
cameraEntity.script.orbitCameraInputMouse.distanceSensitivity || 0.4 : 0.4;
|
| 398 |
-
|
| 399 |
-
if (camera.projection === pc.PROJECTION_PERSPECTIVE) {
|
| 400 |
-
orbitCamera.distance -= event.deltaY * 0.01 * sensitivity * (orbitCamera.distance * 0.1);
|
| 401 |
-
} else {
|
| 402 |
-
orbitCamera.orthoHeight -= event.deltaY * 0.01 * sensitivity * (orbitCamera.orthoHeight * 0.1);
|
| 403 |
}
|
| 404 |
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
|
| 413 |
// --- Initialize the 3D PLY Viewer using PlayCanvas ---
|
| 414 |
async function initializeViewer() {
|
|
|
|
|
|
|
|
|
|
| 415 |
progressDialog.style.display = 'block';
|
| 416 |
|
| 417 |
// Initialize PlayCanvas
|
|
@@ -575,7 +620,7 @@ const currentScriptTag = document.currentScript;
|
|
| 575 |
|
| 576 |
// Initialize the orbit controller
|
| 577 |
setTimeout(() => {
|
| 578 |
-
if (cameraEntity.script.orbitCamera) {
|
| 579 |
// Calculate distance from camera to model
|
| 580 |
const modelPos = modelEntity.getPosition();
|
| 581 |
const camPos = cameraEntity.getPosition();
|
|
@@ -595,8 +640,14 @@ const currentScriptTag = document.currentScript;
|
|
| 595 |
// Initial resize to match container
|
| 596 |
resize();
|
| 597 |
|
|
|
|
|
|
|
|
|
|
| 598 |
// Hide progress dialog when everything is set up
|
| 599 |
progressDialog.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
| 600 |
});
|
| 601 |
|
| 602 |
} catch (error) {
|
|
|
|
| 58 |
let cameraEntity = null;
|
| 59 |
let app = null;
|
| 60 |
let modelEntity = null;
|
| 61 |
+
let viewerInitialized = false;
|
| 62 |
+
let wheelHandlers = [];
|
| 63 |
|
| 64 |
// Generate a unique identifier for this widget instance.
|
| 65 |
const instanceId = Math.random().toString(36).substr(2, 8);
|
|
|
|
| 227 |
});
|
| 228 |
}
|
| 229 |
|
| 230 |
+
// Function to clean up the viewer
|
| 231 |
+
function cleanupViewer() {
|
| 232 |
+
// Remove wheel event listeners
|
| 233 |
+
for (const handler of wheelHandlers) {
|
| 234 |
+
const [element, func] = handler;
|
| 235 |
+
element.removeEventListener('wheel', func, { passive: false });
|
| 236 |
+
}
|
| 237 |
+
wheelHandlers = [];
|
| 238 |
+
|
| 239 |
+
// Destroy PlayCanvas app if it exists
|
| 240 |
+
if (app) {
|
| 241 |
+
app.destroy();
|
| 242 |
+
app = null;
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
// Reset entities
|
| 246 |
+
cameraEntity = null;
|
| 247 |
+
modelEntity = null;
|
| 248 |
+
viewerInitialized = false;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
closeBtn.addEventListener('click', function() {
|
| 252 |
+
// Handle fullscreen exit
|
| 253 |
if (document.fullscreenElement === widgetContainer) {
|
| 254 |
if (document.exitFullscreen) {
|
| 255 |
document.exitFullscreen();
|
|
|
|
| 258 |
if (widgetContainer.classList.contains('fake-fullscreen')) {
|
| 259 |
widgetContainer.classList.remove('fake-fullscreen');
|
| 260 |
fullscreenToggle.textContent = '⇱';
|
|
|
|
| 261 |
}
|
| 262 |
+
|
| 263 |
+
// Clean up the viewer
|
| 264 |
+
cleanupViewer();
|
| 265 |
+
|
| 266 |
+
// Hide viewer and show GIF
|
| 267 |
viewerContainer.style.display = 'none';
|
| 268 |
gifPreview.style.display = 'block';
|
| 269 |
});
|
|
|
|
| 408 |
});
|
| 409 |
|
| 410 |
// --- Prevent app from hijacking all wheel events ---
|
| 411 |
+
function setupWheelHandlers() {
|
| 412 |
+
// First remove any existing handlers
|
| 413 |
+
for (const handler of wheelHandlers) {
|
| 414 |
+
const [element, func] = handler;
|
| 415 |
+
element.removeEventListener('wheel', func, { passive: false });
|
| 416 |
}
|
| 417 |
+
wheelHandlers = [];
|
| 418 |
|
| 419 |
+
// Create new wheel handler
|
| 420 |
+
const handleWheel = function(event) {
|
| 421 |
+
// Check if mouse is over the viewer
|
| 422 |
+
if (!isMouseOverViewer) {
|
| 423 |
+
// Allow normal page scrolling
|
| 424 |
+
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
}
|
| 426 |
|
| 427 |
+
// Otherwise apply zooming, but prevent default only for viewer area
|
| 428 |
+
event.stopPropagation();
|
| 429 |
+
|
| 430 |
+
if (cameraEntity && cameraEntity.script && cameraEntity.script.orbitCamera) {
|
| 431 |
+
const camera = cameraEntity.camera;
|
| 432 |
+
const orbitCamera = cameraEntity.script.orbitCamera;
|
| 433 |
+
const sensitivity = cameraEntity.script.orbitCameraInputMouse ?
|
| 434 |
+
cameraEntity.script.orbitCameraInputMouse.distanceSensitivity || 0.4 : 0.4;
|
| 435 |
+
|
| 436 |
+
if (camera.projection === pc.PROJECTION_PERSPECTIVE) {
|
| 437 |
+
orbitCamera.distance -= event.deltaY * 0.01 * sensitivity * (orbitCamera.distance * 0.1);
|
| 438 |
+
} else {
|
| 439 |
+
orbitCamera.orthoHeight -= event.deltaY * 0.01 * sensitivity * (orbitCamera.orthoHeight * 0.1);
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
event.preventDefault();
|
| 443 |
+
}
|
| 444 |
+
};
|
| 445 |
+
|
| 446 |
+
// Add wheel handlers and store references for cleanup
|
| 447 |
+
viewerContainer.addEventListener('wheel', handleWheel, { passive: false });
|
| 448 |
+
canvas.addEventListener('wheel', handleWheel, { passive: false });
|
| 449 |
+
|
| 450 |
+
// Store handlers for later cleanup
|
| 451 |
+
wheelHandlers.push([viewerContainer, handleWheel]);
|
| 452 |
+
wheelHandlers.push([canvas, handleWheel]);
|
| 453 |
+
}
|
| 454 |
|
| 455 |
// --- Initialize the 3D PLY Viewer using PlayCanvas ---
|
| 456 |
async function initializeViewer() {
|
| 457 |
+
// Skip initialization if already initialized
|
| 458 |
+
if (viewerInitialized) return;
|
| 459 |
+
|
| 460 |
progressDialog.style.display = 'block';
|
| 461 |
|
| 462 |
// Initialize PlayCanvas
|
|
|
|
| 620 |
|
| 621 |
// Initialize the orbit controller
|
| 622 |
setTimeout(() => {
|
| 623 |
+
if (cameraEntity && cameraEntity.script && cameraEntity.script.orbitCamera) {
|
| 624 |
// Calculate distance from camera to model
|
| 625 |
const modelPos = modelEntity.getPosition();
|
| 626 |
const camPos = cameraEntity.getPosition();
|
|
|
|
| 640 |
// Initial resize to match container
|
| 641 |
resize();
|
| 642 |
|
| 643 |
+
// Set up wheel handlers
|
| 644 |
+
setupWheelHandlers();
|
| 645 |
+
|
| 646 |
// Hide progress dialog when everything is set up
|
| 647 |
progressDialog.style.display = 'none';
|
| 648 |
+
|
| 649 |
+
// Mark viewer as initialized
|
| 650 |
+
viewerInitialized = true;
|
| 651 |
});
|
| 652 |
|
| 653 |
} catch (error) {
|