→ לכל המאגר

G90 · שכבות מוצר שמתפרקות ומתחברות

GSAP GSAP · ScrollTrigger · 3D תמונות וגלריותתהליך ושלבים ממתין

מוצר שמוצג כערימת שכבות באיזומטריה. בגלילה השכבות מתרחקות זו מזו, כל אחת מקבלת תווית, ובסוף חוזרות ומתחברות. תרשים מפורק (exploded view) חי.

מתי משתמשים: מוצר עם שכבות אמיתיות (מזרן, נעל, מכשיר, ארכיטקטורת מערכת, חבילת שירות). שלוש עד חמש שכבות.

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

הדמו

גלול למטה, הדמו מגיע ↓
בסיס
מנוע
ממשק
מעטפת

מה יש בפנים

ארבע שכבות שעובדות ביחד. גלול כדי לפרק.

  • 01בסיס נתונים מאובטח, גיבוי יומי
  • 02מנוע אוטומציות שרץ ברקע
  • 03ממשק בעברית, לכל מכשיר
  • 04מעטפת שירות ותמיכה
עוד מסלול גלילה. נסה גם חזרה למעלה ↑
כל שכבה היא div ב-preserve-3d עם translateZ שגדל בסקראב; ההטיה האיזומטרית (rotateX 58, rotateZ -32) קבועה על המכל. כל השכבות מתחילות בהפרש z קטן כדי שלא יהבהבו זו דרך זו, והתוויות נדלקות בתוך הטיימליין ולא במחלקה עם transition, כי תחת scrub טרנזישן מקפיץ. במובייל ההטיה קטנה והמרווח בין השכבות חצי, כדי שהכל ייכנס ל-390px.

קוד להדבקה

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

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

CSS

/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.ph-a{background:linear-gradient(160deg,#3b5bdb,#748ffc)}
.ph-l{background:rgba(16,18,43,.72);color:#fff;padding:.18em .7em;border-radius:999px;line-height:1.3;font-size:max(.78em,12px)}

/* G90 · שכבות מוצר שמתפרקות ומתחברות */
.ex{position:relative;height:260vh}
.ex-pin{position:sticky;top:0;height:100vh;display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:var(--gap, clamp(16px, 1.6vw, 36px));padding-inline:var(--gutter, clamp(24px, 5vw, 96px));overflow:hidden}
.ex-stage{perspective:1400px;display:grid;place-items:center;height:70vh}
.ex-stack{position:relative;width:min(34vw,380px);aspect-ratio:1;transform-style:preserve-3d;transform:rotateX(58deg) rotateZ(-32deg)}
.ex-layer{position:absolute;inset:0;border-radius:22px;transform-style:preserve-3d;backface-visibility:hidden;display:grid;place-items:center;color:#fff;font-weight:800;font-size:22px;box-shadow:0 30px 60px rgba(0,0,0,.18);border:1px solid rgba(255,255,255,.35);will-change:transform}
.ex-copy h2{margin:0 0 12px;font-size:var(--fs-h2, clamp(28px, 1.9vw + 0.5rem, 52px))}
.ex-copy p{margin:0 0 22px;color:var(--muted, #6a6d85)}
.ex-list{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.ex-list li{display:flex;gap:12px;align-items:baseline;opacity:.28}
.ex-list li.on{opacity:1}
.ex-list b{font-size:12px;color:var(--accent, #4a3aff);letter-spacing:.12em;min-width:2.4em}
@media(max-width:767px){.ex{height:200vh}.ex-pin{grid-template-columns:1fr;align-content:center;gap:10px}.ex-stage{height:44vh}.ex-stack{width:56vw;transform:rotateX(52deg) rotateZ(-28deg)}.ex-copy h2{font-size:clamp(22px,6vw,32px)}}

HTML

<div class="ex">
  <div class="ex-pin">
    <div class="ex-stage"><div class="ex-stack">
      <div class="ex-layer ph-a" style="background:linear-gradient(160deg,#3b5bdb,#748ffc)"><span class="ph-l">בסיס</span></div>
      <div class="ex-layer" style="background:linear-gradient(160deg,#0b7285,#3bc9db)">מנוע</div>
      <div class="ex-layer" style="background:linear-gradient(160deg,#5f3dc4,#9775fa)">ממשק</div>
      <div class="ex-layer" style="background:linear-gradient(160deg,#e8590c,#ffa94d)">מעטפת</div>
    </div></div>
    <div class="ex-copy"><h2>מה יש בפנים</h2><p>ארבע שכבות שעובדות ביחד. גלול כדי לפרק.</p>
      <ul class="ex-list"><li><b>01</b>בסיס נתונים מאובטח, גיבוי יומי</li><li><b>02</b>מנוע אוטומציות שרץ ברקע</li><li><b>03</b>ממשק בעברית, לכל מכשיר</li><li><b>04</b>מעטפת שירות ותמיכה</li></ul></div>
  </div>
</div>

JS

gsap.registerPlugin(ScrollTrigger);

(function(){
  const layers=gsap.utils.toArray(".ex-layer"),items=gsap.utils.toArray(".ex-list li");
  if(matchMedia("(prefers-reduced-motion: reduce)").matches){items.forEach(l=>l.classList.add("on"));layers.forEach((l,i)=>gsap.set(l,{z:i*40}));return;}
  const GAP=matchMedia("(max-width:767px)").matches?76:140;
  gsap.set(layers,{z:(i)=>i*9});                              // בלי הפרש פתיחה ארבע השכבות באותו z ומהבהבות זו דרך זו
  const tl=gsap.timeline({scrollTrigger:{trigger:".ex",start:"top top",end:"bottom bottom",scrub:.5}});
  layers.forEach((l,i)=>{
    // אטימות התווית חיה בטיימליין ולא במחלקה עם transition: תחת scrub טרנזישן ומחלקה מקפיצים
    tl.to(l,{z:i*GAP,duration:1,ease:"power2.inOut"},i*.25)
      .to(items[i],{opacity:1,duration:.4,ease:"none"},i*.25+.2);
  });
  tl.to({},{duration:.6});                                    // רגע של שהייה במצב המפורק
  tl.to(layers,{z:(i)=>i*9,duration:1.2,ease:"power2.inOut",stagger:{each:.08,from:"end"}});   // מתחבר חזרה מלמעלה למטה
})();