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.)

})();