const HEADER_PATH = "header.html"; const FOOTER_PATH = "footer.html"; document.addEventListener("DOMContentLoaded", () => { fetch(HEADER_PATH) .then(res => res.text()) .then(data => { const headerPlaceholder = document.getElementById("page-header"); if (headerPlaceholder) { headerPlaceholder.innerHTML = data; smoothScrollFix(); } }); fetch(FOOTER_PATH) .then(res => res.text()) .then(data => { const footerPlaceholder = document.getElementById("page-footer"); if (footerPlaceholder) { footerPlaceholder.innerHTML = data; } }); if (document.getElementById("background-canvas") && typeof THREE !== 'undefined') { initBackground(); } }); function smoothScrollFix() { const links = document.querySelectorAll("nav a[href^='#']"); links.forEach(link => { link.addEventListener("click", (e) => { if (link.getAttribute("href").length <= 1) return; e.preventDefault(); const targetID = link.getAttribute("href").substring(1); const target = document.getElementById(targetID); if (target) { const offset = -80; const topPos = target.getBoundingClientRect().top + window.scrollY + offset; window.scrollTo({ top: topPos, behavior: "smooth" }); } }); }); } let scene, camera, renderer, particles, cubes = []; function initBackground() { const canvas = document.getElementById("background-canvas"); if (!canvas) { console.error("Erreur Three.js: Le canvas #background-canvas est introuvable."); return; } scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); const particleCount = 500; const positions = []; for (let i = 0; i < particleCount; i++) { positions.push((Math.random() - 0.5) * 200); positions.push((Math.random() - 0.5) * 200); positions.push((Math.random() - 0.5) * 200); } const geometry = new THREE.BufferGeometry(); geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3)); const material = new THREE.PointsMaterial({ color: 0x00eaff, size: 0.4, transparent: true, opacity: 0.8 }); particles = new THREE.Points(geometry, material); scene.add(particles); for (let i = 0; i < 25; i++) { const cubeGeo = new THREE.BoxGeometry(2, 2, 2); const cubeMat = new THREE.MeshStandardMaterial({ color: Math.random() * 0xffffff, wireframe: true }); const cube = new THREE.Mesh(cubeGeo, cubeMat); cube.position.set( (Math.random() - 0.5) * 120, (Math.random() - 0.5) * 120, (Math.random() - 0.5) * 120 ); cubes.push(cube); scene.add(cube); } const light = new THREE.PointLight(0xffffff, 1.2); light.position.set(15, 50, 40); scene.add(light); camera.position.z = 70; animateBackground(); } function animateBackground() { requestAnimationFrame(animateBackground); particles.rotation.y += 0.0009; particles.rotation.x += 0.0004; cubes.forEach(cube => { cube.rotation.x += 0.01; cube.rotation.y += 0.015; cube.position.x += (Math.random() - 0.5) * 0.02; cube.position.y += (Math.random() - 0.5) * 0.02; }); renderer.render(scene, camera); } window.addEventListener("resize", () => { if (camera && renderer) { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } });