viewer_sgos / interface.js
MikaFil's picture
Update interface.js
090021b verified
raw
history blame
8.18 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 ────────────────────────────────────────────
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);
// Conditionally add the tooltips toggle button only if defined
const tooltipsButtonHTML = config.tooltips_url
? `<button id="tooltips-toggle-${instanceId}" class="widget-button tooltips-toggle">β¦Ώ</button>`
: '';
// Add all inner HTML, including help panel with French lines
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">⟲</button>
${tooltipsButtonHTML}
<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="tooltip-panel" class="tooltip-panel" style="display: none;">
<div class="tooltip-content">
<span id="tooltip-close" class="tooltip-close">Γ—</span>
<div id="tooltip-text" class="tooltip-text"></div>
<img id="tooltip-image" class="tooltip-image" src="" alt="" style="display: none;" />
</div>
</div>
`;
// Append to DOM
scriptTag.parentNode.appendChild(widgetContainer);
// ─── 6. Grab references ───────────────────────────────────────────────────────
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 tooltipsToggleBtn = document.getElementById('tooltips-toggle-' + instanceId);
const menuContent = document.getElementById('menu-content-' + instanceId);
const helpTextDiv = menuContent.querySelector('.help-text');
// Tooltip panel refs
const tooltipPanel = document.getElementById('tooltip-panel');
const tooltipTextDiv = document.getElementById('tooltip-text');
const tooltipImage = document.getElementById('tooltip-image');
const tooltipCloseBtn = document.getElementById('tooltip-close');
// ─── 6a. Mobile detection ─────────────────────────────────────────────────────
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
const isMobile = isIOS || /Android/i.test(navigator.userAgent);
// Conditionally include the French tooltip instruction
const tooltipInstruction = config.tooltips_url
? '- Cliquez sur β¦Ώ pour afficher/masquer les tooltips.<br>'
: '';
// ─── 6b. Populate help-text with French instructions ──────────────────────────
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>
⟲ Réinitialise la caméra.<br>
⇱ Passe en plein Γ©cran.<br>
${tooltipInstruction}
`;
} else {
helpTextDiv.innerHTML = `
- orbitez avec le clic droit<br>
- zoomez avec la molette<br>
- dΓ©placez vous avec le clic gauche<br>
⟲ Réinitialise la caméra.<br>
⇱ Passe en plein Γ©cran.<br>
${tooltipInstruction}
`;
}
// Show help panel by default
menuContent.style.display = 'block';
viewerContainerElem.style.display = 'block';
// ─── 7. Dynamically load viewer.js ───────────────────────────────────────────
try {
console.log('[Viewer-Debug] About to import viewer.js');
const viewerModule = await import('./viewer.js');
console.log('[Viewer-Debug] viewer.js imported, calling initializeViewer()');
await viewerModule.initializeViewer(config, instanceId);
console.log('[Viewer-Debug] initializeViewer() completed');
} catch (err) {
console.error("Failed to load viewer.js or initialize the 3D viewer:", err);
return;
}
// ─── 8. Rest of the event listeners (fullscreen, help toggle, tooltips, etc.) ─
// (This section remains exactly as before, wiring up all button behaviour,
// drag-to-hide, wheel-to-hide, resize listeners, etc., without alteration.)
})();