243 lines
8.7 KiB
JavaScript
243 lines
8.7 KiB
JavaScript
/* ----------------------------------------------------------------
|
|
Le Shed — Initialisation
|
|
1. Injection des motifs décoratifs (formes vectorielles colorées)
|
|
2. Initialisation de Rellax sur les objets décoratifs
|
|
3. Parallax custom de la colonne droite :
|
|
- Les deux colonnes démarrent à la même hauteur (top aligné)
|
|
- Les deux colonnes finissent à la même hauteur (bottom aligné)
|
|
- Le translateY est appliqué sur .col__cards (wrapper interne)
|
|
pour ne pas casser le position:sticky du heading.
|
|
---------------------------------------------------------------- */
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
/* ---- Header compact au scroll + padding-top dynamique ---- */
|
|
|
|
var masthead = document.querySelector('.masthead');
|
|
var layout = document.querySelector('.layout');
|
|
|
|
var headerSyncing = false;
|
|
|
|
function syncHeaderHeight() {
|
|
if (!masthead || !layout) return;
|
|
var h = masthead.offsetHeight;
|
|
layout.style.paddingTop = h + 'px';
|
|
document.documentElement.style.setProperty('--header-h', h + 'px');
|
|
}
|
|
|
|
function syncHeaderLoop() {
|
|
syncHeaderHeight();
|
|
syncColHeadingH();
|
|
if (headerSyncing) requestAnimationFrame(syncHeaderLoop);
|
|
}
|
|
|
|
function startHeaderSync() {
|
|
if (headerSyncing) return;
|
|
headerSyncing = true;
|
|
syncHeaderLoop();
|
|
setTimeout(function () {
|
|
headerSyncing = false;
|
|
syncHeaderHeight();
|
|
}, 350);
|
|
}
|
|
|
|
function syncColHeadingH() {
|
|
var headingLeft = document.querySelector('.col--left .col__heading');
|
|
if (headingLeft) {
|
|
document.documentElement.style.setProperty('--col-heading-h', headingLeft.offsetHeight + 'px');
|
|
}
|
|
}
|
|
|
|
function onHeaderScroll() {
|
|
if (!masthead) return;
|
|
var scrolled = window.scrollY > 20;
|
|
if (scrolled !== masthead.classList.contains('is-compact')) {
|
|
masthead.classList.toggle('is-compact', scrolled);
|
|
startHeaderSync();
|
|
}
|
|
}
|
|
|
|
syncHeaderHeight();
|
|
syncColHeadingH();
|
|
window.addEventListener('resize', function () { syncHeaderHeight(); syncColHeadingH(); });
|
|
window.addEventListener('scroll', onHeaderScroll, { passive: true });
|
|
onHeaderScroll();
|
|
|
|
/* ---- Rellax pour les objets décoratifs uniquement ---- */
|
|
|
|
function initRellax() {
|
|
var rellax = new Rellax('[data-rellax-speed]', {
|
|
center: false,
|
|
wrapper: null,
|
|
round: true,
|
|
vertical: true,
|
|
horizontal: false
|
|
});
|
|
|
|
window.addEventListener('resize', function () {
|
|
rellax.refresh();
|
|
});
|
|
}
|
|
|
|
/* ---- Parallax custom colonne droite ---- */
|
|
|
|
function initColumnParallax() {
|
|
var colLeft = document.querySelector('.col--left');
|
|
var colRight = document.querySelector('.col--right');
|
|
var cardsRight = document.querySelector('.col--right .col__cards');
|
|
if (!colLeft || !colRight || !cardsRight) return;
|
|
|
|
var titlesRight = Array.from(colRight.querySelectorAll('.col__cards .card__title'));
|
|
var ticking = false;
|
|
var dims = {};
|
|
var maxScroll = 0;
|
|
var currentOffset = 0;
|
|
|
|
// top de base des titres sticky (sans parallax)
|
|
var baseStickyTop = 0;
|
|
|
|
function readBaseStickyTop() {
|
|
var headerH = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--header-h')) || 80;
|
|
var headingRight = colRight.querySelector('.col__heading');
|
|
var colHeadingH = headingRight ? headingRight.offsetHeight : 35;
|
|
baseStickyTop = headerH + colHeadingH - 2;
|
|
}
|
|
|
|
function recalc() {
|
|
cardsRight.style.transform = '';
|
|
titlesRight.forEach(function (t) { t.style.top = ''; });
|
|
layout.style.height = '';
|
|
dims.leftH = colLeft.offsetHeight;
|
|
dims.rightH = colRight.offsetHeight;
|
|
|
|
var cs = getComputedStyle(layout);
|
|
var padTop = parseFloat(cs.paddingTop) || 0;
|
|
var padBot = parseFloat(cs.paddingBottom) || 0;
|
|
var minColH = Math.min(dims.leftH, dims.rightH);
|
|
layout.style.height = (padTop + minColH + padBot) + 'px';
|
|
|
|
maxScroll = Math.max(1, document.documentElement.scrollHeight - window.innerHeight);
|
|
readBaseStickyTop();
|
|
}
|
|
|
|
function onScroll() {
|
|
if (!ticking) {
|
|
ticking = true;
|
|
requestAnimationFrame(function () {
|
|
readBaseStickyTop();
|
|
var progress = Math.min(1, Math.max(0, window.scrollY / maxScroll));
|
|
var delta = dims.leftH - dims.rightH;
|
|
currentOffset = Math.round(delta * progress);
|
|
cardsRight.style.transform = 'translateY(' + currentOffset + 'px)';
|
|
// Compenser le translateY sur le top des titres sticky
|
|
// pour qu'ils se collent toujours juste sous "Actions publiques"
|
|
var correctedTop = baseStickyTop - currentOffset;
|
|
titlesRight.forEach(function (t) {
|
|
t.style.top = correctedTop + 'px';
|
|
});
|
|
ticking = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
recalc();
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|
window.addEventListener('resize', function () {
|
|
recalc();
|
|
onScroll();
|
|
});
|
|
|
|
onScroll();
|
|
}
|
|
|
|
/* ---- Settings panel toggle ---- */
|
|
|
|
var settingsBtn = document.getElementById('settings-toggle');
|
|
var settingsPanel = document.getElementById('settings-panel');
|
|
|
|
if (settingsBtn && settingsPanel) {
|
|
settingsBtn.addEventListener('click', function () {
|
|
settingsPanel.hidden = !settingsPanel.hidden;
|
|
});
|
|
|
|
document.addEventListener('click', function (e) {
|
|
if (!document.getElementById('settings').contains(e.target)) {
|
|
settingsPanel.hidden = true;
|
|
}
|
|
});
|
|
}
|
|
|
|
/* ---- Switch motifs ---- */
|
|
|
|
var rellaxInstance = null;
|
|
|
|
function clearMotifs() {
|
|
document.querySelectorAll('.objets-layer, .objets2-layer, .paysage-layer').forEach(function (el) {
|
|
el.remove();
|
|
});
|
|
if (rellaxInstance) {
|
|
try { rellaxInstance.destroy(); } catch (e) {}
|
|
rellaxInstance = null;
|
|
}
|
|
}
|
|
|
|
function activateMotif(mode) {
|
|
clearMotifs();
|
|
if (mode === 'paysage' && window.LeShedPaysage) {
|
|
window.LeShedPaysage.inject().then(function () {
|
|
rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false });
|
|
});
|
|
} else if (mode === 'objets' && window.LeShedObjets) {
|
|
window.LeShedObjets.inject().then(function () {
|
|
rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false });
|
|
});
|
|
} else if (mode === 'objets2' && window.LeShedObjets2) {
|
|
window.LeShedObjets2.inject().then(function () {
|
|
rellaxInstance = new Rellax('[data-rellax-speed]', { center: false, round: true, vertical: true, horizontal: false });
|
|
});
|
|
}
|
|
}
|
|
|
|
document.querySelectorAll('input[name="motifs"]').forEach(function (radio) {
|
|
radio.addEventListener('change', function () {
|
|
if (radio.checked) activateMotif(radio.value);
|
|
});
|
|
});
|
|
|
|
/* ---- Couleur motifs ---- */
|
|
|
|
var couleurCustomInput = document.getElementById('couleur-custom');
|
|
|
|
function applyMotifColor(value) {
|
|
var color = value === 'custom' ? couleurCustomInput.value : value;
|
|
document.documentElement.style.setProperty('--motif-color', color);
|
|
}
|
|
|
|
document.querySelectorAll('input[name="couleur"]').forEach(function (radio) {
|
|
radio.addEventListener('change', function () {
|
|
if (radio.checked) applyMotifColor(radio.value);
|
|
});
|
|
});
|
|
|
|
if (couleurCustomInput) {
|
|
couleurCustomInput.addEventListener('input', function () {
|
|
var customRadio = document.querySelector('input[name="couleur"][value="custom"]');
|
|
if (customRadio) customRadio.checked = true;
|
|
applyMotifColor('custom');
|
|
});
|
|
}
|
|
|
|
/* ---- Boot ---- */
|
|
|
|
document.querySelectorAll('input[name="motifs"]').forEach(function (r) {
|
|
r.checked = r.value === 'objets2';
|
|
});
|
|
document.querySelectorAll('input[name="couleur"]').forEach(function (r) {
|
|
r.checked = r.value === '#1a1a1a';
|
|
});
|
|
applyMotifColor('#1a1a1a');
|
|
activateMotif('objets2');
|
|
initColumnParallax();
|
|
|
|
});
|