Spaces:
Running
Running
Update interface.js
Browse files- interface.js +33 -14
interface.js
CHANGED
|
@@ -27,12 +27,9 @@ const currentScriptTag = document.currentScript;
|
|
| 27 |
const response = await fetch(configUrl);
|
| 28 |
config = await response.json();
|
| 29 |
} catch (error) {
|
| 30 |
-
// Silent fail, but log in dev environments
|
| 31 |
-
// console.error("Error loading config file:", error);
|
| 32 |
return;
|
| 33 |
}
|
| 34 |
} else {
|
| 35 |
-
// console.error("No config file provided. Please set a data-config attribute on the <script> tag.");
|
| 36 |
return;
|
| 37 |
}
|
| 38 |
|
|
@@ -72,7 +69,7 @@ const currentScriptTag = document.currentScript;
|
|
| 72 |
}
|
| 73 |
}
|
| 74 |
|
| 75 |
-
// 5. Create the widget container
|
| 76 |
const widgetContainer = document.createElement('div');
|
| 77 |
widgetContainer.id = 'ply-widget-container-' + instanceId;
|
| 78 |
widgetContainer.classList.add('ply-widget-container');
|
|
@@ -80,12 +77,10 @@ const currentScriptTag = document.currentScript;
|
|
| 80 |
widgetContainer.style.paddingBottom = aspectPercent;
|
| 81 |
widgetContainer.setAttribute('data-original-aspect', aspectPercent);
|
| 82 |
|
| 83 |
-
// Conditionally include the “tooltips-toggle” button only if config.tooltips_url is defined
|
| 84 |
const tooltipsButtonHTML = config.tooltips_url
|
| 85 |
? `<button id="tooltips-toggle-${instanceId}" class="widget-button tooltips-toggle">⦿</button>`
|
| 86 |
: '';
|
| 87 |
|
| 88 |
-
// Add the 3D-viewer HTML + tooltip + help HTML (all HTML in a template literal!)
|
| 89 |
widgetContainer.innerHTML = `
|
| 90 |
<div id="viewer-container-${instanceId}" class="viewer-container">
|
| 91 |
<div id="progress-dialog-${instanceId}" class="progress-dialog">
|
|
@@ -111,7 +106,6 @@ const currentScriptTag = document.currentScript;
|
|
| 111 |
</div>
|
| 112 |
`;
|
| 113 |
|
| 114 |
-
// Append the widget container immediately after the <script> tag
|
| 115 |
scriptTag.parentNode.appendChild(widgetContainer);
|
| 116 |
|
| 117 |
// 6. Grab references to new DOM elements
|
|
@@ -134,14 +128,22 @@ const currentScriptTag = document.currentScript;
|
|
| 134 |
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
| 135 |
const isMobile = isIOS || /Android/i.test(navigator.userAgent);
|
| 136 |
|
| 137 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
const tooltipInstruction = config.tooltips_url
|
| 139 |
? '- Cliquez sur ⦿ pour afficher/masquer les tooltips.<br>'
|
| 140 |
: '';
|
| 141 |
|
| 142 |
-
// Fill help text with instructions plus the two new French lines
|
| 143 |
if (isMobile) {
|
| 144 |
-
helpTextDiv.innerHTML =
|
| 145 |
'- Pour vous déplacer, glissez deux doigts sur l\'écran.<br>' +
|
| 146 |
'- Pour orbiter, utilisez un doigt.<br>' +
|
| 147 |
'- Pour zoomer, pincez avec deux doigts.<br>' +
|
|
@@ -149,7 +151,7 @@ const currentScriptTag = document.currentScript;
|
|
| 149 |
'- ⟲ Réinitialise la caméra.<br>' +
|
| 150 |
'- ⇱ Passe en plein écran.<br>';
|
| 151 |
} else {
|
| 152 |
-
helpTextDiv.innerHTML =
|
| 153 |
'- orbitez avec le clic droit<br>' +
|
| 154 |
'- zoomez avec la molette<br>' +
|
| 155 |
'- déplacez vous avec le clic gauche<br>' +
|
|
@@ -158,14 +160,12 @@ const currentScriptTag = document.currentScript;
|
|
| 158 |
'- ⇱ Passe en plein écran.<br>';
|
| 159 |
}
|
| 160 |
|
| 161 |
-
// Ensure instructions panel is visible by default
|
| 162 |
menuContent.style.display = 'block';
|
| 163 |
viewerContainerElem.style.display = 'block';
|
| 164 |
|
| 165 |
// Variable to hold the drag-hide listener reference
|
| 166 |
let dragHide = null;
|
| 167 |
|
| 168 |
-
// Utilities to hide panels
|
| 169 |
function hideTooltipPanel() {
|
| 170 |
if (dragHide) {
|
| 171 |
viewerContainerElem.removeEventListener('pointermove', dragHide);
|
|
@@ -183,13 +183,24 @@ const currentScriptTag = document.currentScript;
|
|
| 183 |
viewerModule = await import('https://mikafil-viewer-gs.static.hf.space/viewer.js');
|
| 184 |
await viewerModule.initializeViewer(config, instanceId);
|
| 185 |
} catch (err) {
|
| 186 |
-
// Do not break UI, but don't continue
|
| 187 |
return;
|
| 188 |
}
|
| 189 |
|
| 190 |
const canvasId = 'canvas-' + instanceId;
|
| 191 |
const canvasEl = document.getElementById(canvasId);
|
| 192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
// 8. Conditional display of tooltips-toggle button
|
| 194 |
if (tooltipsToggleBtn) {
|
| 195 |
if (!config.tooltips_url) {
|
|
@@ -372,8 +383,16 @@ const currentScriptTag = document.currentScript;
|
|
| 372 |
});
|
| 373 |
|
| 374 |
if (canvasEl) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 375 |
canvasEl.addEventListener('wheel', hideTooltipPanel, { passive: true });
|
| 376 |
}
|
|
|
|
| 377 |
document.addEventListener('keydown', (e) => {
|
| 378 |
if ((e.key === 'Escape' || e.key === 'Esc') && isFullscreen) exitFullscreen();
|
| 379 |
});
|
|
|
|
| 27 |
const response = await fetch(configUrl);
|
| 28 |
config = await response.json();
|
| 29 |
} catch (error) {
|
|
|
|
|
|
|
| 30 |
return;
|
| 31 |
}
|
| 32 |
} else {
|
|
|
|
| 33 |
return;
|
| 34 |
}
|
| 35 |
|
|
|
|
| 69 |
}
|
| 70 |
}
|
| 71 |
|
| 72 |
+
// 5. Create the widget container
|
| 73 |
const widgetContainer = document.createElement('div');
|
| 74 |
widgetContainer.id = 'ply-widget-container-' + instanceId;
|
| 75 |
widgetContainer.classList.add('ply-widget-container');
|
|
|
|
| 77 |
widgetContainer.style.paddingBottom = aspectPercent;
|
| 78 |
widgetContainer.setAttribute('data-original-aspect', aspectPercent);
|
| 79 |
|
|
|
|
| 80 |
const tooltipsButtonHTML = config.tooltips_url
|
| 81 |
? `<button id="tooltips-toggle-${instanceId}" class="widget-button tooltips-toggle">⦿</button>`
|
| 82 |
: '';
|
| 83 |
|
|
|
|
| 84 |
widgetContainer.innerHTML = `
|
| 85 |
<div id="viewer-container-${instanceId}" class="viewer-container">
|
| 86 |
<div id="progress-dialog-${instanceId}" class="progress-dialog">
|
|
|
|
| 106 |
</div>
|
| 107 |
`;
|
| 108 |
|
|
|
|
| 109 |
scriptTag.parentNode.appendChild(widgetContainer);
|
| 110 |
|
| 111 |
// 6. Grab references to new DOM elements
|
|
|
|
| 128 |
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
| 129 |
const isMobile = isIOS || /Android/i.test(navigator.userAgent);
|
| 130 |
|
| 131 |
+
// Prevent iOS pinch-zoom and double-tap zoom on the container
|
| 132 |
+
if (isIOS) {
|
| 133 |
+
widgetContainer.style.touchAction = "none";
|
| 134 |
+
widgetContainer.addEventListener('touchmove', function(e) {
|
| 135 |
+
// Prevent all default browser zooms/scrolls on the widget area
|
| 136 |
+
if (e.touches.length > 1) e.preventDefault();
|
| 137 |
+
}, { passive: false });
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
// French help/instructions
|
| 141 |
const tooltipInstruction = config.tooltips_url
|
| 142 |
? '- Cliquez sur ⦿ pour afficher/masquer les tooltips.<br>'
|
| 143 |
: '';
|
| 144 |
|
|
|
|
| 145 |
if (isMobile) {
|
| 146 |
+
helpTextDiv.innerHTML =
|
| 147 |
'- Pour vous déplacer, glissez deux doigts sur l\'écran.<br>' +
|
| 148 |
'- Pour orbiter, utilisez un doigt.<br>' +
|
| 149 |
'- Pour zoomer, pincez avec deux doigts.<br>' +
|
|
|
|
| 151 |
'- ⟲ Réinitialise la caméra.<br>' +
|
| 152 |
'- ⇱ Passe en plein écran.<br>';
|
| 153 |
} else {
|
| 154 |
+
helpTextDiv.innerHTML =
|
| 155 |
'- orbitez avec le clic droit<br>' +
|
| 156 |
'- zoomez avec la molette<br>' +
|
| 157 |
'- déplacez vous avec le clic gauche<br>' +
|
|
|
|
| 160 |
'- ⇱ Passe en plein écran.<br>';
|
| 161 |
}
|
| 162 |
|
|
|
|
| 163 |
menuContent.style.display = 'block';
|
| 164 |
viewerContainerElem.style.display = 'block';
|
| 165 |
|
| 166 |
// Variable to hold the drag-hide listener reference
|
| 167 |
let dragHide = null;
|
| 168 |
|
|
|
|
| 169 |
function hideTooltipPanel() {
|
| 170 |
if (dragHide) {
|
| 171 |
viewerContainerElem.removeEventListener('pointermove', dragHide);
|
|
|
|
| 183 |
viewerModule = await import('https://mikafil-viewer-gs.static.hf.space/viewer.js');
|
| 184 |
await viewerModule.initializeViewer(config, instanceId);
|
| 185 |
} catch (err) {
|
|
|
|
| 186 |
return;
|
| 187 |
}
|
| 188 |
|
| 189 |
const canvasId = 'canvas-' + instanceId;
|
| 190 |
const canvasEl = document.getElementById(canvasId);
|
| 191 |
|
| 192 |
+
// Prevent iOS double-tap to zoom on the canvas
|
| 193 |
+
if (isIOS && canvasEl) {
|
| 194 |
+
let lastTouch = 0;
|
| 195 |
+
canvasEl.addEventListener('touchend', function(e) {
|
| 196 |
+
const now = new Date().getTime();
|
| 197 |
+
if (now - lastTouch <= 400) {
|
| 198 |
+
e.preventDefault();
|
| 199 |
+
}
|
| 200 |
+
lastTouch = now;
|
| 201 |
+
}, { passive: false });
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
// 8. Conditional display of tooltips-toggle button
|
| 205 |
if (tooltipsToggleBtn) {
|
| 206 |
if (!config.tooltips_url) {
|
|
|
|
| 383 |
});
|
| 384 |
|
| 385 |
if (canvasEl) {
|
| 386 |
+
// Prevent pinch-zoom and double-tap zoom on iOS (extra guard)
|
| 387 |
+
if (isIOS) {
|
| 388 |
+
canvasEl.style.touchAction = "none";
|
| 389 |
+
canvasEl.addEventListener('gesturestart', e => e.preventDefault());
|
| 390 |
+
canvasEl.addEventListener('gesturechange', e => e.preventDefault());
|
| 391 |
+
canvasEl.addEventListener('gestureend', e => e.preventDefault());
|
| 392 |
+
}
|
| 393 |
canvasEl.addEventListener('wheel', hideTooltipPanel, { passive: true });
|
| 394 |
}
|
| 395 |
+
|
| 396 |
document.addEventListener('keydown', (e) => {
|
| 397 |
if ((e.key === 'Escape' || e.key === 'Esc') && isFullscreen) exitFullscreen();
|
| 398 |
});
|