v0.4.2: iconen gerepareerd, lucht-achtergrond (skybox) met toggle
- bootstrap-icons: @font-face correct ingebed (selector .bi::before was stuk) - core/skybox.js + assets/skybox-data.js (lazy), knop Lucht in alle 3D-weergaven - woning: met lucht aan raster en sandwichpanelen onzichtbaar Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3591fad220
commit
3a4b9608c0
@@ -0,0 +1,79 @@
|
||||
/*!
|
||||
* 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 = '<i class="bi bi-cloud-sun"></i>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 };
|
||||
})();
|
||||
Reference in New Issue
Block a user