/* ---------------------------------------------------------------- Le Shed — Objets v5-bach Charge les SVGs de assets/shapes/v5-bach, les inline dans le DOM, et répartit leurs formes unitaires entre deux layers (under/over) pour que chaque objet traverse le contenu. Horizontaux → côtés gauche et droit Verticaux → centre (entre les colonnes) Chaque objet a 5 formes unitaires (index 0..4). Formes 0,1,2 → layer under (z-index:-1) Formes 3,4 → layer over (z-index:20) ---------------------------------------------------------------- */ (function () { /* ---------------------------------------------------------------- Catalogue de placement side : 'left' | 'right' | 'center' x : décalage depuis le bord (px, peut être négatif pour déborder) y : position verticale depuis le haut du layout (px) size : largeur cible en px (hauteur proportionnelle) splitAt: index de la première forme qui passe en "over" (défaut: 3) ---------------------------------------------------------------- */ var CATALOGUE = [ // --- Horizontaux gauche --- { file: 'horizontaux/Group.svg', side: 'left', x: -100, y: 180, size: 255, speed: -1 }, { file: 'horizontaux/Group-3.svg', side: 'left', x: -90, y: 550, size: 225, speed: 1.5 }, { file: 'horizontaux/Group-6.svg', side: 'left', x: -110, y: 950, size: 270, speed: -1.5 }, { file: 'horizontaux/Group-9.svg', side: 'left', x: -95, y: 1380, size: 240, speed: 1 }, { file: 'horizontaux/Group-7.svg', side: 'left', x: -100, y: 1780, size: 245, speed: -1.5 }, // --- Horizontaux droite --- { file: 'horizontaux/Group-2.svg', side: 'right', x: -90, y: 350, size: 270, speed: 1.5 }, { file: 'horizontaux/Group-5.svg', side: 'right', x: -105, y: 750, size: 245, speed: -1 }, { file: 'horizontaux/Group-8.svg', side: 'right', x: -95, y: 1150, size: 255, speed: 1 }, { file: 'horizontaux/Group-10.svg', side: 'right', x: -100, y: 1580, size: 285, speed: -1.5 }, { file: 'horizontaux/Group-4.svg', side: 'right', x: -90, y: 1950, size: 240, speed: 1.5 }, // --- Verticaux centre --- { file: 'verticaux/Group.svg', side: 'center', x: -30, y: 280, size: 120, speed: 1 }, { file: 'verticaux/Group-3.svg', side: 'center', x: 40, y: 650, size: 115, speed: -1.5 }, { file: 'verticaux/Group-6.svg', side: 'center', x: -20, y: 1050, size: 125, speed: 1.5 }, { file: 'verticaux/Group-9.svg', side: 'center', x: 35, y: 1450, size: 118, speed: -1 }, { file: 'verticaux/Group-12.svg', side: 'center', x: -35, y: 1850, size: 120, speed: 1 }, { file: 'verticaux/Group-4.svg', side: 'center', x: 25, y: 2200, size: 115, speed: -1.5 }, ]; /* ---------------------------------------------------------------- Parse un SVG depuis le dictionnaire inline (pas de fetch) ---------------------------------------------------------------- */ function loadSVG(key) { var data = window.LeShedObjets2Data; if (!data || !data[key]) { console.warn('LeShedObjets2: SVG non trouvé:', key); return Promise.resolve(null); } var parser = new DOMParser(); var doc = parser.parseFromString(data[key], 'image/svg+xml'); var svgEl = doc.querySelector('svg'); if (!svgEl) return Promise.resolve(null); var topG = svgEl.querySelector('svg > g'); if (!topG) return Promise.resolve(null); var shapes = Array.from(topG.children).filter(function (c) { return c.tagName === 'g'; }); return Promise.resolve({ svgEl: svgEl, shapes: shapes }); } /* ---------------------------------------------------------------- Crée un clone avec les formes données, positionné en absolute ---------------------------------------------------------------- */ function makeSVGFragment(sourceSVG, shapes, spec, naturalW, naturalH) { var targetW = spec.size; var targetH = Math.round(naturalH * (targetW / naturalW)); var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('viewBox', '0 0 ' + naturalW + ' ' + naturalH); svg.setAttribute('width', targetW); svg.setAttribute('height', targetH); svg.setAttribute('fill', 'none'); if (spec.speed !== undefined) svg.setAttribute('data-rellax-speed', spec.speed); svg.style.cssText = 'position:absolute;pointer-events:none;'; // Position horizontale if (spec.side === 'left') { svg.style.left = spec.x + 'px'; } else if (spec.side === 'right') { svg.style.right = spec.x + 'px'; } else { // center : centré entre les colonnes (centre de la page) svg.style.left = '50%'; svg.style.marginLeft = (spec.x - targetW / 2) + 'px'; } svg.style.top = spec.y + 'px'; // Copie les defs si présents var defs = sourceSVG.querySelector('defs'); if (defs) svg.appendChild(defs.cloneNode(true)); shapes.forEach(function (g) { svg.appendChild(g.cloneNode(true)); }); return svg; } /* ---------------------------------------------------------------- Inject principal ---------------------------------------------------------------- */ function injectObjets2() { var layout = document.querySelector('.layout'); if (!layout) return Promise.resolve(); // Layer under : position absolute dans le layout, z-index négatif var layerUnder = document.createElement('div'); layerUnder.className = 'objets2-layer objets2-layer--under'; layerUnder.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:-1'; // Layer over : position absolute dans le layout, z-index positif var layerOver = document.createElement('div'); layerOver.className = 'objets2-layer objets2-layer--over'; layerOver.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:20'; // Insérer avant le contenu pour que le z-index fonctionne layout.insertBefore(layerUnder, layout.firstChild); layout.appendChild(layerOver); var promises = CATALOGUE.map(function (spec) { return loadSVG(spec.file).then(function (result) { if (!result) return; var shapes = result.shapes; var svgEl = result.svgEl; var naturalW = parseFloat(svgEl.getAttribute('width')); var naturalH = parseFloat(svgEl.getAttribute('height')); var splitAt = spec.splitAt !== undefined ? spec.splitAt : 3; var shapesUnder = shapes.slice(0, splitAt); var shapesOver = shapes.slice(splitAt); if (shapesUnder.length) { layerUnder.appendChild( makeSVGFragment(svgEl, shapesUnder, spec, naturalW, naturalH) ); } if (shapesOver.length) { layerOver.appendChild( makeSVGFragment(svgEl, shapesOver, spec, naturalW, naturalH) ); } }); }); return Promise.all(promises); } window.LeShedObjets2 = { inject: injectObjets2 }; }());