Spaces:
Running
Running
File size: 8,176 Bytes
c5da84a 090021b c5da84a 090021b c5da84a 090021b c5da84a 48b3594 c5da84a 48b3594 c5da84a 090021b c5da84a 090021b c5da84a 48b3594 c5da84a 090021b 48b3594 c5da84a 090021b c5da84a 090021b 48b3594 c5da84a 090021b c5da84a e50b47f c5da84a e50b47f c5da84a 090021b c5da84a 090021b c5da84a e50b47f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | // ==============================
// 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.)
})();
|