viewer_sgos / interface.js
MikaFil's picture
Update interface.js
db721fa verified
raw
history blame
7.49 kB
// ==============================
// interface.js
// ==============================
// Store a reference to the <script> tag that loaded this file
const currentScriptTag = document.currentScript;
(async function() {
// ─── 1. Locate the <script> and read data-config ───────────────────────────────
let scriptTag = currentScriptTag;
if (!scriptTag) {
const scripts = document.getElementsByTagName('script');
for (let i = 0; i < scripts.length; i++) {
if (scripts[i].src.includes('interface.js') && scripts[i].hasAttribute('data-config')) {
scriptTag = scripts[i];
break;
}
}
if (!scriptTag && scripts.length > 0) {
scriptTag = scripts[scripts.length - 1];
}
}
const configUrl = scriptTag.getAttribute('data-config');
let config = {};
if (configUrl) {
try {
const response = await fetch(configUrl);
config = await response.json();
} catch (error) {
console.error("Error loading config file:", error);
return;
}
} else {
console.error("No config file provided. Please set a data-config attribute on the <script> tag.");
return;
}
// ─── 2. If config.css_url is provided, inject a <link> to that CSS ─────────────
if (config.css_url) {
const linkEl = document.createElement('link');
linkEl.rel = "stylesheet";
linkEl.href = config.css_url;
document.head.appendChild(linkEl);
}
// ─── 3. Generate a unique instanceId for this widget ───────────────────────────
const instanceId = Math.random().toString(36).substr(2, 8);
// ─── 4. Compute the aspect ratio (padding-bottom %) ────────────────────────────
let aspectPercent = "100%";
if (config.aspect) {
if (config.aspect.includes(":")) {
const parts = config.aspect.split(":");
const w = parseFloat(parts[0]);
const h = parseFloat(parts[1]);
if (!isNaN(w) && !isNaN(h) && w > 0) {
aspectPercent = (h / w * 100) + "%";
}
} else {
const aspectValue = parseFloat(config.aspect);
if (!isNaN(aspectValue) && aspectValue > 0) {
aspectPercent = (100 / aspectValue) + "%";
}
}
} else {
const parentContainer = scriptTag.parentNode;
const containerWidth = parentContainer.offsetWidth;
const containerHeight = parentContainer.offsetHeight;
if (containerWidth > 0 && containerHeight > 0) {
aspectPercent = (containerHeight / containerWidth * 100) + "%";
}
}
// ─── 5. Create the widget container (no GIF preview, no close button) ───────────
const widgetContainer = document.createElement('div');
widgetContainer.id = 'ply-widget-container-' + instanceId;
widgetContainer.classList.add('ply-widget-container');
widgetContainer.style.height = "0";
widgetContainer.style.paddingBottom = aspectPercent;
widgetContainer.setAttribute('data-original-aspect', aspectPercent);
// Add the 3D-viewer HTML + πŸ“ toggle + tooltip markup
widgetContainer.innerHTML = `
<div id="viewer-container-${instanceId}" class="viewer-container">
<div id="progress-dialog-${instanceId}" class="progress-dialog">
<progress id="progress-indicator-${instanceId}" max="100" value="0"></progress>
</div>
<button id="fullscreen-toggle-${instanceId}" class="widget-button fullscreen-toggle">⇱</button>
<button id="help-toggle-${instanceId}" class="widget-button help-toggle">?</button>
<button id="reset-camera-btn-${instanceId}" class="widget-button reset-camera-btn">
<span class="reset-icon">⟲</span>
</button>
<button id="points-toggle-${instanceId}" class="widget-button points-toggle">β¦Ώ</button>
<div id="menu-content-${instanceId}" class="menu-content">
<span id="help-close-${instanceId}" class="help-close">Γ—</span>
<div class="help-text"></div>
</div>
</div>
<div id="point-tooltip" class="point-tooltip" style="display: none;">
<div class="point-tooltip-content">
<span id="point-tooltip-close" class="point-tooltip-close">Γ—</span>
<div id="point-tooltip-text" class="point-tooltip-text"></div>
<img id="point-tooltip-image" class="point-tooltip-image" src="" alt="" style="display: none;" />
</div>
</div>
`;
scriptTag.parentNode.appendChild(widgetContainer);
// ─── 6. Grab references to new DOM elements ──────────────────────────────────
const viewerContainerElem = document.getElementById('viewer-container-' + instanceId);
const fullscreenToggle = document.getElementById('fullscreen-toggle-' + instanceId);
const helpToggle = document.getElementById('help-toggle-' + instanceId);
const helpCloseBtn = document.getElementById('help-close-' + instanceId);
const resetCameraBtn = document.getElementById('reset-camera-btn-' + instanceId);
const pointsToggleBtn = document.getElementById('points-toggle-' + instanceId);
const menuContent = document.getElementById('menu-content-' + instanceId);
const helpTextDiv = menuContent.querySelector('.help-text');
// Tooltip elements
const tooltipDiv = document.getElementById('point-tooltip');
const tooltipTextDiv = document.getElementById('point-tooltip-text');
const tooltipImage = document.getElementById('point-tooltip-image');
const tooltipCloseBtn = document.getElementById('point-tooltip-close');
// Device detection for help text
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
const isMobile = isIOS || /Android/i.test(navigator.userAgent);
// Conditionally include tooltip instruction only if points_url exists
const tooltipInstruction = config.points_url
? '- Cliquez sur β¦Ώ pour afficher/masquer les points d’information.<br>'
: '';
// Fill help text with instructions, plus two new French lines
if (isMobile) {
helpTextDiv.innerHTML = `
- Pour vous dΓ©placer, glissez deux doigts sur l'Γ©cran.<br>
- Pour orbiter, utilisez un doigt.<br>
- Pour zoomer, pincez avec deux doigts.<br>
${tooltipInstruction}
- ⟲ Réinitialise la caméra.<br>
- ⇱ Passe en plein Γ©cran.<br>
`;
} else {
helpTextDiv.innerHTML = `
- orbitez avec le clic droit<br>
- zoomez avec la molette<br>
- dΓ©placez vous avec le clic gauche<br>
${tooltipInstruction}
- ⟲ Réinitialise la caméra.<br>
- ⇱ Passe en plein Γ©cran.<br>
`;
}
// Ensure instructions panel is visible by default
menuContent.style.display = 'block';
viewerContainerElem.style.display = 'block';
// …rest of the original working tooltip, drag-hide, fullscreen, resize, dynamic-import logic remains unchanged…
// ─── 7. Dynamically load viewer.js ─────────────────────────────────────────
let viewerModule;
try {
viewerModule = await import('./viewer.js');
await viewerModule.initializeViewer(config, instanceId);
} catch (err) {
console.error("Failed to load viewer.js or initialize the 3D viewer:", err);
return;
}
// …etc.
})();