→ לכל המאגר

G112 · מפלס שעולה: מילוי גלי בגלילה

GSAP GSAP · ScrollTrigger · SVG מספרים ונתוניםרקע ואווירה ממתין

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

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

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

הדמו

גלול למטה, הדמו מגיע ↓

94% מהלקוחות חוזרים

לא כי הם חייבים. כי כשמשהו עובד, ממשיכים איתו.

עוד מסלול גלילה. נסה גם חזרה למעלה ↑
הגל הוא path ב-SVG שרוחבו כפול מהמכל ונע אופקית בלולאה (CSS keyframes), והגובה שלו הוא y בסקראב. המספר מתעדכן מאותו progress. במובייל המכל קטן ל-60vw.

קוד להדבקה

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

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

CSS

/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.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}

/* G112 · מפלס שעולה: מילוי גלי בגלילה */
.lq-wrap{display:grid;grid-template-columns:auto 1fr;gap:clamp(24px,5vw,80px);align-items:center;max-width:900px;margin-inline:auto;padding-block:20vh 30vh}
.lq{position:relative;width:min(300px,60vw);aspect-ratio:1;border-radius:50%;background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);overflow:hidden;box-shadow:inset 0 0 0 10px var(--bg, #f7f7fa)}
.lq svg{position:absolute;left:0;top:0;width:200%;height:100%;will-change:transform;animation:lq-drift 5s linear infinite}
.lq path{fill:var(--accent, #4a3aff);opacity:.9}
.lq-num{position:absolute;inset:0;display:flex;direction:ltr;align-items:center;justify-content:center;gap:.04em;font-size:clamp(44px,7vw,84px);font-weight:900;color:var(--ink, #16182b);font-variant-numeric:tabular-nums;text-shadow:0 1px 0 var(--card, #fff)}
.lq-num small{font-size:.5em;font-weight:800}
@keyframes lq-drift{to{transform:translateX(-50%)}}
.lq-txt h2{margin:0 0 10px;font-size:var(--fs-h2, clamp(28px, 1.9vw + 0.5rem, 52px))}
.lq-txt p{margin:0;color:var(--muted, #6a6d85);line-height:1.7;max-width:36ch}
@media(max-width:767px){.lq-wrap{grid-template-columns:1fr;justify-items:center;text-align:center}}
@media (prefers-reduced-motion: reduce){.lq svg{animation:none}}

HTML

<div class="stage"><div class="lq-wrap">
  <div class="lq" role="img" aria-label="94 אחוז שביעות רצון">
    <svg viewBox="0 0 400 200" preserveAspectRatio="none" aria-hidden="true"><g class="lq-wave"><path d="M0 40 Q 50 20 100 40 T 200 40 T 300 40 T 400 40 V 400 H 0 Z"/></g></svg>
    <div class="lq-num"><span class="lq-val">0</span><small>%</small></div>
  </div>
  <div class="lq-txt"><h2>94% מהלקוחות חוזרים</h2><p>לא כי הם חייבים. כי כשמשהו עובד, ממשיכים איתו.</p></div>
</div></div>

JS

gsap.registerPlugin(ScrollTrigger);

(function(){
  const wave=document.querySelector(".lq-wave"),val=document.querySelector(".lq-val"),TARGET=94;
  const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
  const o={p:0};
  // המפלס: הגל יושב ב-y=40 מתוך 200 בגובה ה-SVG, ולכן 0% = הזזה של 200 למטה ו-100% = 0
  gsap.set(wave,{y:200});
  gsap.to(o,{p:1,ease:"none",scrollTrigger:{trigger:".lq",start:"top 85%",end:"top 25%",scrub:reduce?false:.5},
    onUpdate(){const lvl=o.p*TARGET/100;gsap.set(wave,{y:200-lvl*200});val.textContent=Math.round(o.p*TARGET);}});
})();