מד עגול כמו בלוח מכונית: המחט מטפסת מהאפס לערך ככל שגוללים, הקשת נצבעת מאחוריה והמספר במרכז רץ. ביצועים, ציון, מהירות טעינה.
מתי משתמשים: מהירות אתר, ציון ביקורת, רמת שירות, כל נתון שיש לו סקאלה. אחד לסקשן.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית.
/* G146 · מד מהירות שהמחט שלו זזה בגלילה */
.gg{display:grid;justify-items:center;gap:10px;padding-block:14vh 30vh;text-align:center}
.gg svg{width:min(360px,70vw);height:auto;overflow:visible}
.gg .arc{fill:none;stroke:var(--line, #e4e4ee);stroke-width:16;stroke-linecap:round}
.gg .fill{fill:none;stroke:var(--accent, #4a3aff);stroke-width:16;stroke-linecap:round}
.gg .ndl{stroke:var(--ink, #16182b);stroke-width:4;stroke-linecap:round}
.gg .hub{fill:var(--ink, #16182b)}
.gg-val{font-size:clamp(44px,7vw,84px);font-weight:900;line-height:1;margin-top:-40px;font-variant-numeric:tabular-nums}
.gg-val small{font-size:.35em;font-weight:500;color:var(--muted, #6a6d85);display:block;margin-top:4px}
<div class="gg">
<svg viewBox="0 0 200 140" aria-label="ציון מהירות 98">
<path class="arc" d="M 22 128 A 88 88 0 1 1 178 128"/>
<path class="fill" d="M 22 128 A 88 88 0 1 1 178 128" pathLength="100" stroke-dasharray="100" stroke-dashoffset="100"/>
<line class="ndl" x1="100" y1="110" x2="100" y2="34"/>
<circle class="hub" cx="100" cy="110" r="8"/>
</svg>
<div class="gg-val"><span class="gg-n">0</span><small>ציון מהירות טעינה</small></div>
</div>
gsap.registerPlugin(ScrollTrigger);
(function(){
const fill=document.querySelector(".gg .fill"),ndl=document.querySelector(".gg .ndl"),n=document.querySelector(".gg-n"),TO=98;
const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches,o={v:0};
gsap.set(ndl,{svgOrigin:"100 110",rotate:-120});
gsap.to(o,{v:TO,ease:"power2.out",scrollTrigger:{trigger:".gg",start:"top 75%",end:"top 25%",scrub:reduce?false:.5},
onUpdate(){gsap.set(fill,{strokeDashoffset:100-o.v});gsap.set(ndl,{svgOrigin:"100 110",rotate:-120+240*o.v/100});n.textContent=Math.round(o.v);}});
})();