→ לכל המאגר

G56 · מדיה שנפתחת לרוחב מלא בגלילה

GSAP GSAP · ScrollTrigger pin · clip-path תמונות וגלריותהירו ופתיחה ממתין

תמונה שמתחילה ככרטיס קטן ומעוגל במרכז המסך, ונפתחת בגלילה עד שהיא ממלאת את המסך כולו. הכותרת שמעליה נמוגה בדיוק כשהמסגרת נעלמת.

מתי משתמשים: פתיחת עמוד בית, מעבר לסקשן מוצר, סוף סיפור מותג. הרגע שבו התמונה מפסיקה להיות איור ומתחילה להיות סצנה.

הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.

הדמו

מהכרטיס אל הסצנה

אותה תמונה, רק שהיא כבר לא מוצגת בתוך מסגרת אלא מקיפה את המבקר.

אותו מהלך עובד גם הפוך: מתחילים ממסך מלא ומתכווצים לכרטיס, כשרוצים לסגור סקשן במקום לפתוח אותו.

הפיתוי הוא לעשות את זה עם `scale`, וזו טעות: הגדלה מותחת את התמונה ומטשטשת אותה, ומזיזה גם את הטקסט שמעליה. `clip-path: inset(...)` פותח את החלון שדרכו רואים את המדיה בלי לגעת בה בכלל, והרדיוס נכנס לאותו ערך עצמו דרך `round`, כך ששני הדברים מונפשים בטוויין אחד. GSAP מסוגל לעשות אינטרפולציה בין שני `inset` רק כשהם כתובים באותו מבנה בדיוק, כולל אותה יחידה ואותו `round` בשני הצדדים; ערבוב של אחוזים ופיקסלים שובר את המעבר. הסקשן מוצמד ב-`position:sticky` ולא ב-pin של ScrollTrigger, ולכן אין spacer ואין קפיצה בסוף.

קוד להדבקה

הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית. הרכיב הזה מסתמך על dir="rtl".

פתח קובץ עצמאי ↗
הצג את הקוד כאן

CSS

/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.ph{display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;border-radius:var(--r, 14px)}
.ph-b{background:linear-gradient(160deg,#5f3dc4,#9775fa)}

/* G56 · מדיה שנפתחת לרוחב מלא בגלילה */
.ex{height:260vh;position:relative}
.ex-stick{position:sticky;top:0;height:100vh;overflow:hidden;background:var(--bg, #f7f7fa)}
.ex-media{position:absolute;inset:0;font-size:0;border-radius:0;
  clip-path:inset(22% 26% 22% 26% round 26px)}
.ex-cap{position:absolute;inset:0;display:grid;place-items:center;text-align:center;pointer-events:none;padding-inline:var(--gutter, clamp(24px, 5vw, 96px))}
.ex-cap h3{margin:0;color:#fff;font-size:clamp(28px,5.5vw,74px);line-height:1.1;max-width:16ch;
  text-shadow:0 4px 30px rgba(0,0,0,.35)}
.ex-cap p{margin:14px 0 0;color:#fff;opacity:0;font-size:clamp(15px,1.6vw,20px);max-width:40ch}
.ex-after{padding:14vh var(--gutter, clamp(24px, 5vw, 96px));max-width:min(680px,92vw);margin-inline:auto;text-align:center;
  color:var(--muted, #6a6d85);font-size:17px;line-height:1.9}

HTML

<div class="ex"><div class="ex-stick">
  <div class="ph ex-media ph-b"></div>
  <div class="ex-cap"><div><h3>מהכרטיס אל הסצנה</h3><p>אותה תמונה, רק שהיא כבר לא מוצגת בתוך מסגרת אלא מקיפה את המבקר.</p></div></div>
</div></div>
<p class="ex-after">אותו מהלך עובד גם הפוך: מתחילים ממסך מלא ומתכווצים לכרטיס, כשרוצים לסגור סקשן במקום לפתוח אותו.</p>

JS

gsap.registerPlugin(ScrollTrigger);

(function(){
  const media=document.querySelector(".ex-media"),h=document.querySelector(".ex-cap h3"),p=document.querySelector(".ex-cap p");
  const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
  if(reduce){gsap.set(media,{clipPath:"inset(0% 0% 0% 0% round 0px)"});gsap.set(p,{opacity:1});return;}
  gsap.timeline({scrollTrigger:{trigger:".ex",start:"top top",end:"bottom bottom",scrub:.6}})
    // clip-path ולא scale: התוכן לא נמתח ולא מטשטש, רק החלון שדרכו רואים אותו גדל
    // משכים מפורשים: בלי זה הפתיחה מסתיימת בשליש הראשון של הגלילה והשאר ריק
    .fromTo(media,{clipPath:"inset(22% 26% 22% 26% round 26px)"},
                  {clipPath:"inset(0% 0% 0% 0% round 0px)",duration:1,ease:"none"},0)
    .to(h,{scale:1.08,opacity:0,duration:.45,ease:"none"},0)
    .to(p,{opacity:1,duration:.3,ease:"none"},.68);
})();