improved projet page, created projet archives page

This commit is contained in:
2026-08-24 14:20:12 +02:00
parent 6627a63805
commit b3db746273
10 changed files with 556 additions and 85 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+88 -41
View File
@@ -55,8 +55,9 @@ gsap.registerPlugin(ScrollTrigger);
initTitles();
initBurgerMenu();
initSmoothScroll();
initColumnScrollSync();
initHomeColumnScrollSync();
initFsLightbox();
initPageFull();
// initVues()
}
@@ -89,7 +90,7 @@ gsap.registerPlugin(ScrollTrigger);
};
function initTitles() {
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2, article.node-type-projet>.cols>.left>h2');
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2, article.node-type-projet>.cols>.left>h2, article.node-type-projet.view-mode-full h2.node-title');
for (const txt of titles) {
txt.classList.add("variable-title");
const splitted = Splitting({ target: txt, by: 'chars' });
@@ -100,43 +101,6 @@ gsap.registerPlugin(ScrollTrigger);
}
}
const pageTitle = document.querySelector('article.node-type-projet.view-mode-full h2.node-title');
console.log('pageTitle', pageTitle);
if (pageTitle) {
// needs requestAnimationFrame to get the real titleHeight after splitting
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const initTitleH = pageTitle.offsetHeight;
// console.log(`initTitleH: ${initTitleH}`);
const titleScaleTarget = 0.4;
const end = initTitleH - initTitleH * titleScaleTarget;
// console.log(`end: ${end}`);
gsap_mm.add('(min-width: 768px)', () => {
gsap.to(pageTitle, {
scale: titleScaleTarget,
y: end,
ease: 'none',
scrollTrigger: {
scroller: scroller,
start: 0,
end: end, // scroll maximum du conteneur (robuste au resize)
scrub: true,
invalidateOnRefresh: true,
},
});
})
});
});
}
}
/**
@@ -301,8 +265,8 @@ gsap.registerPlugin(ScrollTrigger);
* `main[role="main"]`, pas dans la fenêtre : GSAP utilise donc ce conteneur
* comme `scroller`.
*/
function initColumnScrollSync() {
console.log('initColumnScrollSync');
function initHomeColumnScrollSync() {
console.log('initHomeColumnScrollSync');
const firstColumn = document.querySelector('.layout--twocol-section--50-50 .layout__region--first');
const secondColumn = document.querySelector('.layout--twocol-section--50-50 .layout__region--second');
@@ -344,6 +308,89 @@ gsap.registerPlugin(ScrollTrigger);
window.addEventListener('load', () => ScrollTrigger.refresh());
}
function initPageFull(){
console.log('initPageFull');
// PAGE TITLE SCALING DOWN
const pageTitle = document.querySelector('article.node-type-projet.view-mode-full h2.node-title');
console.log('pageTitle', pageTitle);
if (pageTitle) {
// needs requestAnimationFrame to get the real titleHeight after splitting
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const initTitleH = pageTitle.offsetHeight;
// console.log(`initTitleH: ${initTitleH}`);
const titleScaleTarget = 0.4;
const end = initTitleH - initTitleH * titleScaleTarget;
// console.log(`end: ${end}`);
gsap_mm.add('(min-width: 768px)', () => {
gsap.to(pageTitle, {
scale: titleScaleTarget,
y: end,
ease: 'none',
scrollTrigger: {
scroller: scroller,
start: 0,
end: end, // scroll maximum du conteneur (robuste au resize)
scrub: true,
invalidateOnRefresh: true,
},
});
})
});
});
}
// BLOCAGE DE LA COLONNE GAUCHE
// La gauche défile normalement puis se fige (pin) quand le bas de son
// contenu atteint le bas du viewport, pendant que la colonne droite (plus
// haute) continue. Piloté en GSAP plutôt qu'en `position: sticky` (qui ne
// prend pas dans ce contexte scroller custom + GSAP). `.cols` est en
// `align-items: flex-start`, donc .col.left a bien la hauteur de son
// contenu (sinon `bottom bottom` tomberait à la fin du scroll).
const cols = document.querySelector('article.node-type-projet.view-mode-full .cols');
const leftColumn = cols && cols.querySelector('.col.left');
if (cols && leftColumn) {
// Doit rester identique au scale-down du titre (voir plus haut).
const titleScaleTarget = 0.4;
// Seuil de scroll (px) après lequel la colonne gauche se fige :
// - gauche plus haute que le viewport : quand son bas atteint le bas ;
// - gauche plus courte : quand le scale-down du titre est terminé, pour
// qu'elle remonte AVEC le titre puis s'arrête (sans disparaître en haut).
const leftFreezeStart = () => {
const overflow = leftColumn.offsetHeight - scroller.clientHeight;
if (overflow > 0) return overflow;
return pageTitle ? pageTitle.offsetHeight * (1 - titleScaleTarget) : 0;
};
gsap_mm.add('(min-width: 768px)', () => {
// On NE pin PAS (le pin sort l'élément du flux et casse le flex .cols).
// On translate la colonne : défilement natif jusqu'à `leftFreezeStart`,
// puis contre-translation 1:1 du scroll → elle se fige, tout en restant
// un flex-item normal (la colonne droite garde sa place).
gsap.fromTo(leftColumn,
{ y: 0 },
{
y: () => (scroller.scrollHeight - scroller.clientHeight) - leftFreezeStart(),
ease: 'none',
scrollTrigger: {
scroller: scroller,
start: leftFreezeStart, // px de scroll où la gauche se fige
end: 'max',
scrub: true,
invalidateOnRefresh: true,
},
}
);
});
}
}
function initFsLightbox(){
console.log('initFsLightbox');
// console.log(window.FsLightbox);
+80 -35
View File
@@ -205,6 +205,50 @@ header[role="banner"]{
// }
}
@mixin projetListe{
>header{
>h2{
font-size: 5em;
}
}
// only with images, title overlap the image
div.field_artiste_s_invite_s.field-items.multiple{
// display: flex;
// flex-direction: row;
.field-item{
display: inline-block;
&:not(:last-of-type):after{
content: ", ";
}
}
}
&.has-image{
>header{
>h2{
position: relative;
max-height: 1em;
overflow: visible;
z-index: 10;
// text-shadow: 0 0 10px #fff;
// box-shadow: 0 0 15px #f00;
// filter: drop-shadow(0 0 5px #fff);
}
div.field_images{
position:relative;
// width: 100%;
z-index: 5;
a{
display:block;
img{
width:100%;
height: auto;
}
}
}
}
}
}
// _____ _____ __ ____ ___ _ ____
// |_ _/ _ \ \ / / / ___/ _ \| | / ___|
// | || | | \ \ /\ / / | | | | | | | \___ \
@@ -228,40 +272,7 @@ div.layout.layout--twocol-section--50-50{
margin-bottom: 2em;
max-width: 100%;
article.node-type-projet{
>header{
>h2{
font-size: 5em;
}
}
>div{
// margin-top: 3em;
}
// only with images, title overlap the image
&.has-image{
>header{
>h2{
position: relative;
max-height: 1em;
overflow: visible;
z-index: 10;
// text-shadow: 0 0 10px #fff;
// box-shadow: 0 0 15px #f00;
// filter: drop-shadow(0 0 5px #fff);
}
div.field_images{
position:relative;
// width: 100%;
z-index: 5;
a{
display:block;
img{
width:100%;
height: auto;
}
}
}
}
}
@include projetListe();
}
}
@@ -279,12 +290,15 @@ article.node-type-projet.view-mode-full{
display: flex;
flex-direction: row;
gap: $colsgap;
// column-gap: 2em;
align-items: flex-start;
div.col{
flex:0 0 calc(50% - $colsgap / 2);
max-width: calc(50% - $colsgap / 2);
&.left{
z-index: 10;
// padding-bottom: 5em;
// box-sizing: border-box;
>h2.node-title{
position: relative;
font-size: 12em;
@@ -313,6 +327,11 @@ article.node-type-projet.view-mode-full{
font-weight: 400;
}
}
>div.spacer{
display: block;
height: 5em;
}
}
&.right{
// Étire .field_images sur toute la hauteur de la colonne (= colonne la
@@ -389,3 +408,29 @@ article.node-type-projet.view-mode-full{
}
// __ ___ _ _ _ ____ _ _
// \ \ / (_) _____ _____ / \ _ __ ___| |__ (_)_ _____ ___ | _ \ _ __ ___ (_) ___| |_
// \ \ / /| |/ _ \ \ /\ / / __| / _ \ | '__/ __| '_ \| \ \ / / _ \/ __| | |_) | '__/ _ \| |/ _ \ __|
// \ V / | | __/\ V V /\__ \ / ___ \| | | (__| | | | |\ V / __/\__ \ | __/| | | (_) | | __/ |_
// \_/ |_|\___| \_/\_/ |___/ /_/ \_\_| \___|_| |_|_| \_/ \___||___/ |_| |_| \___// |\___|\__|
// |__/
div.views-archives-projets{
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 2em;
gap: $colsgap;
div.views-row{
flex: 1 0 calc(25% - $colsgap);
width: calc(25% - $colsgap);
article.node-type-projet.view-mode-tableau_liste{
@include projetListe();
>header{
>h2{
font-size: 3em;
}
}
}
}
}