לחיצה על קישור לא מכבה את המסך: וילון עולה, מכסה, ורק אז העמוד מתחלף. בטעינה הוא יורד חזרה, כך שהמעבר מרגיש רציף ולא כמו ניתוק.
מתי משתמשים: אתר תדמית רב-עמודי, תיק עבודות, בלוג, חנות. הדפוס הכי נפוץ בגלריה, והוא מה שמפריד בין אתר שמרגיש כמו אפליקציה לאתר שמרגיש כמו אוסף קבצים.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
לחץ על אחד הקישורים. הוילון עולה, התוכן מתחלף מאחוריו, והוילון יורד.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית.
/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.stage{padding:var(--sec, clamp(120px, 12vw, 260px)) var(--gutter, clamp(24px, 5vw, 96px));position:relative}
.stage.tight{padding-block:clamp(48px,5vw,90px)}
.stage.full{padding-inline:0}
/* G50 · וילון מעבר בין עמודים */
.pt-page{min-height:64vh;display:grid;place-items:center;text-align:center;padding:8vh var(--gutter, clamp(24px, 5vw, 96px))}
.pt-page h3{font-size:clamp(28px,5vw,62px);margin:0 0 12px}
.pt-page p{color:var(--muted, #6a6d85);font-size:17px;line-height:1.8;max-width:44ch;margin:0 auto 24px}
.pt-nav{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.pt-nav a{padding:11px 20px;border-radius:999px;border:1px solid var(--line, #e4e4ee);background:var(--card, #fff);
color:var(--ink, #16182b);text-decoration:none;font-size:15px}
.pt-nav a.on{background:var(--ink, #16182b);border-color:var(--ink, #16182b);color:var(--bg, #f7f7fa)}
/* הוילון: ארבע רצועות שעולות בהפרש קטן, כך שהכיסוי מרגיש כמו תנועה ולא כמו מסך שנדלק */
.pt-curtain{position:fixed;inset:0;z-index:90;pointer-events:none;display:grid;grid-template-columns:repeat(4,1fr)}
.pt-curtain i{background:var(--ink, #16182b);transform:translateY(101%)}
.pt-label{position:fixed;inset:0;z-index:91;display:grid;place-items:center;color:#fff;font-size:clamp(22px,4vw,44px);
font-weight:800;opacity:0;pointer-events:none}
<div class="stage tight"><div class="pt-page" id="pt-view">
<div>
<h3>אתרי תדמית</h3>
<p>לחץ על אחד הקישורים. הוילון עולה, התוכן מתחלף מאחוריו, והוילון יורד.</p>
<nav class="pt-nav">
<a href="#" data-t="אתרי תדמית" class="on">אתרי תדמית</a>
<a href="#" data-t="דפי נחיתה">דפי נחיתה</a>
<a href="#" data-t="חנויות">חנויות</a>
<a href="#" data-t="צור קשר">צור קשר</a>
</nav>
</div>
</div></div>
<div class="pt-curtain"><i></i><i></i><i></i><i></i></div>
<div class="pt-label"></div>
(function(){
const bars=gsap.utils.toArray(".pt-curtain i"),label=document.querySelector(".pt-label");
const view=document.querySelector("#pt-view");
const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
const D=reduce?0:.5;
function cover(text){
label.textContent=text; // קודם הטקסט, אחר כך החשיפה. אחרת רואים לרגע את השם הקודם
return gsap.timeline()
.to(bars,{yPercent:-101,duration:D,ease:"power3.inOut",stagger:.05})
.to(label,{opacity:1,duration:D*.5},"-="+D*.5);
}
function reveal(){
return gsap.timeline()
.to(label,{opacity:0,duration:D*.4})
.to(bars,{yPercent:-202,duration:D,ease:"power3.inOut",stagger:.05},"-="+D*.2)
.set(bars,{yPercent:101}); // מחזירים למטה בלי אנימציה, מוכנים למעבר הבא
}
document.querySelectorAll(".pt-nav a").forEach(a=>{
a.addEventListener("click",e=>{
e.preventDefault();
if(a.classList.contains("on"))return;
document.querySelectorAll(".pt-nav a").forEach(x=>x.classList.toggle("on",x===a));
gsap.timeline()
.add(cover(a.dataset.t))
// כאן, מתחת לוילון, מחליפים תוכן. באתר אמיתי: location.href=a.href
.add(()=>{view.querySelector("h3").textContent=a.dataset.t;scrollTo(0,0);})
.add(reveal());
});
});
gsap.set(bars,{yPercent:101});
})();