File size: 7,485 Bytes
c5da84a
 
 
 
465cac7
c5da84a
 
 
d10bcd5
c5da84a
 
 
465cac7
 
 
c5da84a
 
 
465cac7
 
 
c5da84a
 
 
 
465cac7
 
 
 
 
 
 
 
 
 
c5da84a
 
 
465cac7
c5da84a
639d776
465cac7
639d776
 
c5da84a
 
465cac7
c5da84a
639d776
465cac7
d10bcd5
 
 
465cac7
 
 
 
 
 
 
 
 
 
 
d10bcd5
 
465cac7
 
 
 
 
d10bcd5
 
 
db721fa
c5da84a
639d776
c5da84a
465cac7
d10bcd5
 
 
db721fa
fffc65b
639d776
 
 
 
465cac7
 
 
 
 
db721fa
465cac7
 
 
c5da84a
 
db721fa
 
 
 
 
465cac7
c5da84a
db721fa
1f40e45
d10bcd5
 
db721fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465cac7
db721fa
 
090021b
db721fa
090021b
 
639d776
db721fa
465cac7
 
db721fa
c5da84a
fffc65b
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
// ==============================
// 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.

})();