מספר גדול שנספר פעם אחת כשהוא נכנס למסך, עם ease-out טבעי ושמירת סיומת.
מתי משתמשים: סקשן מספרים ונתונים. פעם אחת, לא בכל גלילה.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --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}
.center{text-align:center}
/* B02 · Count-Up (מספר שסופר) */
.cnums{display:flex;gap:clamp(40px,5vw,110px);flex-wrap:wrap;justify-content:center}
.cnum{font-size:clamp(48px,4vw,96px);font-weight:700}
.cnums small{display:block;color:var(--muted, #6a6d85);font-size:15px;text-align:center}
<div class="stage tight center"><div class="cnums">
<div><span class="cnum" data-count="340" data-suffix="+">0</span><small>לקוחות</small></div>
<div><span class="cnum" data-count="97" data-suffix="%">0</span><small>שביעות רצון</small></div>
<div><span class="cnum" data-count="12" data-suffix="">0</span><small>שנות ניסיון</small></div>
</div></div>
const io=new IntersectionObserver(es=>{es.forEach(e=>{
if(!e.isIntersecting)return;
const el=e.target,to=+el.dataset.count,sfx=el.dataset.suffix||"";let t0=null;
function step(ts){if(!t0)t0=ts;const p=Math.min((ts-t0)/900,1);
el.textContent=Math.round(to*(1-Math.pow(1-p,3)))+sfx;
if(p<1)requestAnimationFrame(step);}
if(!matchMedia("(prefers-reduced-motion: reduce)").matches)requestAnimationFrame(step);
else el.textContent=to+sfx;
io.unobserve(el);
})},{threshold:.6});
document.querySelectorAll(".cnum").forEach(el=>io.observe(el));