MatteoScript commited on
Commit
6ea7c9c
·
verified ·
1 Parent(s): d70f053

Update ar.html

Browse files
Files changed (1) hide show
  1. ar.html +63 -47
ar.html CHANGED
@@ -32,7 +32,10 @@
32
 
33
  /* --- ENGINE GRAFICO (Camera e Canvas) --- */
34
 
35
- video {
 
 
 
36
  position: fixed !important;
37
  top: 0 !important;
38
  left: 0 !important;
@@ -45,6 +48,18 @@
45
  margin: 0 !important;
46
  padding: 0 !important;
47
  }
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  .a-canvas {
50
  position: fixed !important;
@@ -128,6 +143,15 @@
128
  color: white;
129
  font-weight: bold;
130
  box-shadow: 0 0 15px rgba(255, 0, 85, 0.5);
 
 
 
 
 
 
 
 
 
131
  }
132
  </style>
133
  </head>
@@ -156,7 +180,6 @@
156
  <span id="sys-status" class="text-[#00ff41] font-bold text-lg tracking-wider animate-pulse">SCANNING...</span>
157
  <span class="text-[8px] text-white/40 font-mono mt-1">FPS: <span id="fps-counter">60</span> | STABLE_MODE: ON</span>
158
  </div>
159
- <!-- Pulsante chiusura (Decorativo o funzionale se necessario) -->
160
  <div class="w-10 h-10 flex items-center justify-center border border-[#00ff41]/50 rounded-full bg-black/40 backdrop-blur-md opacity-50">
161
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
162
  </div>
@@ -202,7 +225,6 @@
202
  </button>
203
 
204
  <!-- AR SCENE -->
205
- <!-- Rimosso il filterBeta troppo basso che causava lag, tornati a valori bilanciati per il JS Smoothing -->
206
  <a-scene
207
  mindar-image="imageTargetSrc: img/targets.mind; filterMinCF:0.0001; filterBeta: 0.01; uiLoading: no; uiScanning: no; missTolerance: 20; warmupTolerance: 5; maxTrack: 1"
208
  color-space="sRGB"
@@ -211,14 +233,37 @@
211
  device-orientation-permission-ui="enabled: false">
212
 
213
  <a-assets>
 
214
  <video id="vid" src="./img/video.mp4" preload="auto" loop muted playsinline webkit-playsinline crossorigin="anonymous"></video>
215
  </a-assets>
216
 
217
- <a-camera position="0 0 0" look-controls="enabled: false"></a-camera>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
- <!-- TARGET MINDAR -->
220
  <a-entity id="example-target" mindar-image-target="targetIndex: 0">
221
- <!-- GRUPPO CONTENUTO: Mettiamo tutto qui dentro per poterlo spostare facilmente -->
222
  <a-entity id="ar-content-group">
223
  <!-- VIDEO -->
224
  <a-entity id="myVid"
@@ -263,8 +308,8 @@
263
  const fpsCounter = document.querySelector("#fps-counter");
264
  const fallbackBtn = document.querySelector("#fallback-btn");
265
 
266
- const contentGroup = document.querySelector("#ar-content-group");
267
- const camera = document.querySelector("a-camera");
268
  const manualCloseBtn = document.querySelector("#manual-close-btn");
269
 
270
  let isAudioEnabled = false;
@@ -275,28 +320,21 @@
275
  let smoothPositionX = 0;
276
  let smoothPositionY = 0;
277
  let smoothPositionZ = 0;
278
- const SMOOTHING_FACTOR = 0.1; // Torniamo al valore originale (buon bilanciamento)
279
 
280
  // CUSTOM SMOOTHING LAYER
281
  const myVidEntity = document.querySelector("#myVid");
282
 
283
  setInterval(() => {
284
- // Applica solo se in modalità AR normale (target visible)
285
  if(myVidEntity && target.object3D.visible && !isManualMode) {
286
  const currentPos = target.object3D.position;
287
-
288
- // Rimosso il Deadzone Threshold che causava la "frizione"
289
- // Torniamo a un puro Lerp fluido
290
  smoothPositionX += (currentPos.x - smoothPositionX) * SMOOTHING_FACTOR;
291
  smoothPositionY += (currentPos.y - smoothPositionY) * SMOOTHING_FACTOR;
292
  smoothPositionZ += (currentPos.z - smoothPositionZ) * SMOOTHING_FACTOR;
293
 
294
- // Applichiamo al gruppo interno per dare l'effetto di "galleggiamento" stabile
295
- // Nota: In modalità normale il parent #example-target si muove con MindAR.
296
- // Questo script dovrebbe idealmente agire su un oggetto slegato, ma qui lasciamo
297
- // che MindAR gestisca il grosso e il filterBeta faccia il resto.
298
- // Per un vero custom smoothing, bisognerebbe disaccoppiare la gerarchia,
299
- // ma dato che ti piaceva "prima", torniamo alla config standard di MindAR + CSS anims.
300
  }
301
  }, 16);
302
 
@@ -306,7 +344,7 @@
306
  fpsCounter.innerText = fakeFps;
307
  }, 1000);
308
 
309
- // Loading Messages
310
  const nerdMessages = [
311
  "Calibrating sensors...",
312
  "Loading neural net...",
@@ -315,19 +353,15 @@
315
  ];
316
  let msgIndex = 0;
317
 
318
- // Caricamento Veloce
319
  const loadInterval = setInterval(() => {
320
  loadProgress += 0.55;
321
-
322
  if(loadProgress > 100) loadProgress = 100;
323
  loadingPercent.innerText = Math.floor(loadProgress) + "%";
324
  progressBar.style.width = loadProgress + "%";
325
-
326
  if(Math.floor(loadProgress) % 25 === 0 && msgIndex < nerdMessages.length) {
327
  document.querySelector('#load-msg').innerText = nerdMessages[msgIndex];
328
  msgIndex++;
329
  }
330
-
331
  if(loadProgress >= 100) {
332
  clearInterval(loadInterval);
333
  document.querySelector('#load-msg').innerText = "System Ready.";
@@ -337,7 +371,6 @@
337
  // AR PRONTA
338
  scene.addEventListener("arReady", () => {
339
  console.log("✅ AR SYSTEM ONLINE");
340
-
341
  const checkLoad = setInterval(() => {
342
  if(loadProgress >= 100) {
343
  clearInterval(checkLoad);
@@ -345,15 +378,13 @@
345
  loader.style.opacity = "0";
346
  setTimeout(() => loader.style.display = "none", 500);
347
 
348
- // TIMER 10 SECONDI PER IL BOTTONE FALLBACK
349
- // ORA APPARE SEMPRE (indipendentemente dal marker trovato)
350
  setTimeout(() => {
351
  if (!isManualMode) {
352
  fallbackBtn.classList.remove('hidden');
353
  fallbackBtn.style.display = 'flex';
354
  }
355
  }, 10000);
356
-
357
  }, 500);
358
  }
359
  }, 100);
@@ -362,23 +393,17 @@
362
  // TARGET FOUND
363
  target.addEventListener("targetFound", () => {
364
  if(isManualMode) return;
365
-
366
  video.play();
367
  statusText.innerText = "LOCKED";
368
  statusText.style.color = "#fff";
369
  statusText.classList.remove("animate-pulse");
370
  aimOverlay.style.opacity = "0";
371
-
372
- // NON nascondiamo più il bottone fallback se è già apparso
373
- // Se appare dopo 10 secondi, rimane lì come opzione
374
-
375
  if(navigator.vibrate) navigator.vibrate(50);
376
  });
377
 
378
  // TARGET LOST
379
  target.addEventListener("targetLost", () => {
380
  if(isManualMode) return;
381
-
382
  video.pause();
383
  statusText.innerText = "SEARCHING...";
384
  statusText.style.color = "#00ff41";
@@ -394,9 +419,7 @@
394
  audioText.innerText = "AUDIO ON";
395
  audioBtn.classList.add("bg-[#00ff41]", "text-black");
396
  audioBtn.classList.remove("bg-[#00ff41]/10", "text-[#00ff41]");
397
-
398
  if(navigator.vibrate) navigator.vibrate(50);
399
-
400
  setTimeout(() => {
401
  audioBtn.style.opacity = "0";
402
  audioBtn.style.pointerEvents = "none";
@@ -409,18 +432,11 @@
409
  isManualMode = true;
410
  console.log("🛠 MANUAL OVERRIDE ENGAGED");
411
 
412
- // 1. Sposta il contenuto AR dentro la camera (HUD)
413
- contentGroup.parentNode.removeChild(contentGroup);
414
- camera.appendChild(contentGroup);
415
-
416
- // FIX IMPORTANTE: Rendiamo il contenuto esplicitamente visibile
417
- // MindAR potrebbe averlo nascosto quando ha perso il target
418
- contentGroup.setAttribute("visible", "true");
419
 
420
- // 2. Posiziona il contenuto di fronte alla camera
421
- contentGroup.setAttribute("position", "0 0 -1.5");
422
- contentGroup.setAttribute("scale", "0.5 0.5 0.5");
423
- contentGroup.setAttribute("rotation", "0 0 0");
424
 
425
  // 3. UI Updates
426
  aimOverlay.style.display = "none";
 
32
 
33
  /* --- ENGINE GRAFICO (Camera e Canvas) --- */
34
 
35
+ /* FIX Z-INDEX: Applichiamo lo stile SOLO al video della webcam generato da MindAR */
36
+ /* MindAR non da una classe specifica facile, ma è l'unico video diretto nel body solitamente.
37
+ Tuttavia, per sicurezza usiamo una regola che esclude il nostro #vid */
38
+ video:not(#vid) {
39
  position: fixed !important;
40
  top: 0 !important;
41
  left: 0 !important;
 
48
  margin: 0 !important;
49
  padding: 0 !important;
50
  }
51
+
52
+ /* Nascondiamo il video sorgente dalla vista (ma deve esistere per la texture) */
53
+ #vid {
54
+ position: absolute;
55
+ top: 0;
56
+ left: 0;
57
+ width: 1px;
58
+ height: 1px;
59
+ opacity: 0;
60
+ z-index: -100;
61
+ pointer-events: none;
62
+ }
63
 
64
  .a-canvas {
65
  position: fixed !important;
 
143
  color: white;
144
  font-weight: bold;
145
  box-shadow: 0 0 15px rgba(255, 0, 85, 0.5);
146
+ cursor: pointer;
147
+ }
148
+
149
+ .animate-fade-in {
150
+ animation: fadeIn 0.5s ease-out forwards;
151
+ }
152
+ @keyframes fadeIn {
153
+ from { opacity: 0; transform: translateY(10px); }
154
+ to { opacity: 1; transform: translateY(0); }
155
  }
156
  </style>
157
  </head>
 
180
  <span id="sys-status" class="text-[#00ff41] font-bold text-lg tracking-wider animate-pulse">SCANNING...</span>
181
  <span class="text-[8px] text-white/40 font-mono mt-1">FPS: <span id="fps-counter">60</span> | STABLE_MODE: ON</span>
182
  </div>
 
183
  <div class="w-10 h-10 flex items-center justify-center border border-[#00ff41]/50 rounded-full bg-black/40 backdrop-blur-md opacity-50">
184
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
185
  </div>
 
225
  </button>
226
 
227
  <!-- AR SCENE -->
 
228
  <a-scene
229
  mindar-image="imageTargetSrc: img/targets.mind; filterMinCF:0.0001; filterBeta: 0.01; uiLoading: no; uiScanning: no; missTolerance: 20; warmupTolerance: 5; maxTrack: 1"
230
  color-space="sRGB"
 
233
  device-orientation-permission-ui="enabled: false">
234
 
235
  <a-assets>
236
+ <!-- IL VIDEO SORGENTE (nascosto visivamente via CSS ma caricato qui) -->
237
  <video id="vid" src="./img/video.mp4" preload="auto" loop muted playsinline webkit-playsinline crossorigin="anonymous"></video>
238
  </a-assets>
239
 
240
+ <!-- CAMERA + HUD MANUALE -->
241
+ <a-camera position="0 0 0" look-controls="enabled: false">
242
+ <!-- Questo gruppo è fissato alla camera (HUD) ma inizialmente INVISIBILE -->
243
+ <!-- Lo accendiamo solo in modalità manuale -->
244
+ <a-entity id="manual-hud" visible="false" position="0 0 -1.5" scale="0.5 0.5 0.5">
245
+ <!-- VIDEO -->
246
+ <a-entity
247
+ geometry="primitive: plane; width: 1.6; height: 0.9"
248
+ material="src: #vid; shader: flat; transparent: true; opacity: 1">
249
+ </a-entity>
250
+
251
+ <!-- CORNICI (Copiate dalla versione AR) -->
252
+ <a-plane position="0 0.47 0" width="1.68" height="0.03" color="#00ff41" material="shader: flat">
253
+ <a-animation attribute="opacity" from="1" to="0.7" dur="100" direction="alternate" repeat="indefinite"></a-animation>
254
+ </a-plane>
255
+ <a-plane position="0 -0.47 0" width="1.68" height="0.03" color="#00ff41" material="shader: flat"></a-plane>
256
+ <a-plane position="-0.83 0 0" width="0.03" height="0.96" color="#00ff41" material="shader: flat"></a-plane>
257
+ <a-plane position="0.83 0 0" width="0.03" height="0.96" color="#00ff41" material="shader: flat">
258
+ <a-animation attribute="opacity" from="1" to="0.7" dur="150" direction="alternate" repeat="indefinite"></a-animation>
259
+ </a-plane>
260
+ <a-text value="MANUAL_OVERRIDE" color="#ff0055" align="center" width="1.5" position="0 -0.6 0.01"
261
+ font="https://cdn.aframe.io/fonts/Roboto-msdf.json"></a-text>
262
+ </a-entity>
263
+ </a-camera>
264
 
265
+ <!-- TARGET MINDAR (AR REALE) -->
266
  <a-entity id="example-target" mindar-image-target="targetIndex: 0">
 
267
  <a-entity id="ar-content-group">
268
  <!-- VIDEO -->
269
  <a-entity id="myVid"
 
308
  const fpsCounter = document.querySelector("#fps-counter");
309
  const fallbackBtn = document.querySelector("#fallback-btn");
310
 
311
+ const arContentGroup = document.querySelector("#ar-content-group");
312
+ const manualHud = document.querySelector("#manual-hud");
313
  const manualCloseBtn = document.querySelector("#manual-close-btn");
314
 
315
  let isAudioEnabled = false;
 
320
  let smoothPositionX = 0;
321
  let smoothPositionY = 0;
322
  let smoothPositionZ = 0;
323
+ const SMOOTHING_FACTOR = 0.1; // Smooth originale
324
 
325
  // CUSTOM SMOOTHING LAYER
326
  const myVidEntity = document.querySelector("#myVid");
327
 
328
  setInterval(() => {
329
+ // Applica smoothing solo alla parte AR Reale
330
  if(myVidEntity && target.object3D.visible && !isManualMode) {
331
  const currentPos = target.object3D.position;
 
 
 
332
  smoothPositionX += (currentPos.x - smoothPositionX) * SMOOTHING_FACTOR;
333
  smoothPositionY += (currentPos.y - smoothPositionY) * SMOOTHING_FACTOR;
334
  smoothPositionZ += (currentPos.z - smoothPositionZ) * SMOOTHING_FACTOR;
335
 
336
+ // Nota: MindAR controlla il parent, noi non modifichiamo il target qui
337
+ // ma le variabili sono pronte se volessimo sganciare il contenuto
 
 
 
 
338
  }
339
  }, 16);
340
 
 
344
  fpsCounter.innerText = fakeFps;
345
  }, 1000);
346
 
347
+ // Loading
348
  const nerdMessages = [
349
  "Calibrating sensors...",
350
  "Loading neural net...",
 
353
  ];
354
  let msgIndex = 0;
355
 
 
356
  const loadInterval = setInterval(() => {
357
  loadProgress += 0.55;
 
358
  if(loadProgress > 100) loadProgress = 100;
359
  loadingPercent.innerText = Math.floor(loadProgress) + "%";
360
  progressBar.style.width = loadProgress + "%";
 
361
  if(Math.floor(loadProgress) % 25 === 0 && msgIndex < nerdMessages.length) {
362
  document.querySelector('#load-msg').innerText = nerdMessages[msgIndex];
363
  msgIndex++;
364
  }
 
365
  if(loadProgress >= 100) {
366
  clearInterval(loadInterval);
367
  document.querySelector('#load-msg').innerText = "System Ready.";
 
371
  // AR PRONTA
372
  scene.addEventListener("arReady", () => {
373
  console.log("✅ AR SYSTEM ONLINE");
 
374
  const checkLoad = setInterval(() => {
375
  if(loadProgress >= 100) {
376
  clearInterval(checkLoad);
 
378
  loader.style.opacity = "0";
379
  setTimeout(() => loader.style.display = "none", 500);
380
 
381
+ // TIMER 10 SECONDI: Il bottone appare SEMPRE
 
382
  setTimeout(() => {
383
  if (!isManualMode) {
384
  fallbackBtn.classList.remove('hidden');
385
  fallbackBtn.style.display = 'flex';
386
  }
387
  }, 10000);
 
388
  }, 500);
389
  }
390
  }, 100);
 
393
  // TARGET FOUND
394
  target.addEventListener("targetFound", () => {
395
  if(isManualMode) return;
 
396
  video.play();
397
  statusText.innerText = "LOCKED";
398
  statusText.style.color = "#fff";
399
  statusText.classList.remove("animate-pulse");
400
  aimOverlay.style.opacity = "0";
 
 
 
 
401
  if(navigator.vibrate) navigator.vibrate(50);
402
  });
403
 
404
  // TARGET LOST
405
  target.addEventListener("targetLost", () => {
406
  if(isManualMode) return;
 
407
  video.pause();
408
  statusText.innerText = "SEARCHING...";
409
  statusText.style.color = "#00ff41";
 
419
  audioText.innerText = "AUDIO ON";
420
  audioBtn.classList.add("bg-[#00ff41]", "text-black");
421
  audioBtn.classList.remove("bg-[#00ff41]/10", "text-[#00ff41]");
 
422
  if(navigator.vibrate) navigator.vibrate(50);
 
423
  setTimeout(() => {
424
  audioBtn.style.opacity = "0";
425
  audioBtn.style.pointerEvents = "none";
 
432
  isManualMode = true;
433
  console.log("🛠 MANUAL OVERRIDE ENGAGED");
434
 
435
+ // 1. Spegni AR Reale
436
+ arContentGroup.setAttribute("visible", "false");
 
 
 
 
 
437
 
438
+ // 2. Accendi HUD Manuale (Clone)
439
+ manualHud.setAttribute("visible", "true");
 
 
440
 
441
  // 3. UI Updates
442
  aimOverlay.style.display = "none";