/*! * Tectum * Copyright © 2026 Machiel Heinen. * Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming. * Zie LICENTIE.md. */ // ============================================================ // core/skybox.js — lucht-achtergrond (equirectangulair panorama) voor de // 3D-weergaven, met een "Lucht"-knop in de 3D-werkbalk. De afbeelding // (assets/skybox-data.js, gegenereerd uit assets/skybox.webp) wordt pas bij // de eerste keer aanzetten geladen en daarna gedeeld. De keuze aan/uit wordt // onthouden (localStorage, alleen gemak). // Plain script (geen ES-module). // ============================================================ window.Skybox = (() => { const PREF_KEY = 'tectum.skybox'; let texturePromise = null; function load() { if (texturePromise) return texturePromise; texturePromise = new Promise((resolve, reject) => { const fromData = () => { const img = new Image(); img.onload = () => { const tex = new THREE.Texture(img); tex.mapping = THREE.EquirectangularReflectionMapping; tex.needsUpdate = true; resolve(tex); }; img.onerror = reject; img.src = window.TECTUM_SKYBOX; }; if (window.TECTUM_SKYBOX) return fromData(); const s = document.createElement('script'); s.src = 'assets/skybox-data.js'; s.onload = fromData; s.onerror = reject; document.head.appendChild(s); }); texturePromise.catch(() => { texturePromise = null; }); return texturePromise; } function isOn() { try { return localStorage.getItem(PREF_KEY) === '1'; } catch (e) { return false; } } function remember(on) { try { localStorage.setItem(PREF_KEY, on ? '1' : '0'); } catch (e) { /* geen opslag: alleen deze sessie */ } } // Zet de achtergrond van `scene`: lucht als on, anders fallbackColor (hex). // wanted() wordt na het laden nog eens gevraagd (knop intussen uitgezet?). function apply(scene, on, fallbackColor, wanted) { if (!on) { scene.background = new THREE.Color(fallbackColor); return; } load().then(tex => { if (!wanted || wanted()) scene.background = tex; }) .catch(() => { scene.background = new THREE.Color(fallbackColor); }); } // "Lucht"-knop in een 3D-werkbalk. onChange(on) bij elke klik (en niet bij // aanmaken: de aanroeper leest de begintoestand met isOn()). function createToggle(toolbar, onChange) { const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'btn-3d-toggle' + (isOn() ? ' active' : ''); btn.title = 'Lucht als achtergrond'; btn.innerHTML = 'Lucht'; btn.addEventListener('click', () => { const on = !btn.classList.contains('active'); btn.classList.toggle('active', on); remember(on); onChange(on); }); toolbar.appendChild(btn); return btn; } return { load, isOn, apply, createToggle }; })();