→ לכל המאגר

G126 · גרף קו שנמשך עם נקודה בקצה

GSAP GSAP · ScrollTrigger · DrawSVG מספרים ונתונים ממתין

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

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

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

הדמו

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

פניות בחודש, לפני ואחרי

אותו עסק, אותו תקציב פרסום. רק האתר השתנה.

12
ינוארהאתר החדש עלהדצמבר
עוד מסלול גלילה. נסה גם חזרה למעלה ↑
DrawSVG על path הקו, והנקודה ממוקמת בכל עדכון לפי getPointAtLength של אותו path. הערך מחושב מהנקודה. במובייל הגרף נמוך יותר והתווית מעל הנקודה קטנה.

קוד להדבקה

הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --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}

/* G126 · גרף קו שנמשך עם נקודה בקצה */
.lg{max-width:min(900px,94vw);margin-inline:auto;padding-block:16vh 30vh}
.lg h2{margin:0 0 6px;font-size:var(--fs-h2, clamp(28px, 1.9vw + 0.5rem, 52px))}
.lg p{margin:0 0 26px;color:var(--muted, #6a6d85)}
.lg-box{position:relative;background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);border-radius:var(--r, 14px);padding:24px;direction:ltr}
.lg svg{width:100%;height:auto;overflow:visible;display:block}
.lg-grid line{stroke:var(--line, #e4e4ee);stroke-width:1}
.lg-line{fill:none;stroke:var(--accent, #4a3aff);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.lg-fill{fill:url(#lg-g);opacity:0}
.lg-dot{fill:var(--accent, #4a3aff);stroke:var(--card, #fff);stroke-width:4}
.lg-val{position:absolute;background:var(--ink, #16182b);color:var(--bg, #f7f7fa);font-size:14px;font-weight:700;padding:6px 10px;border-radius:8px;translate:-50% -140%;pointer-events:none;font-variant-numeric:tabular-nums;white-space:nowrap}
.lg-ax{display:flex;justify-content:space-between;font-size:12px;color:var(--muted, #6a6d85);margin-top:10px}

HTML

<div class="stage"><div class="lg">
  <h2>פניות בחודש, לפני ואחרי</h2><p>אותו עסק, אותו תקציב פרסום. רק האתר השתנה.</p>
  <div class="lg-box">
    <svg viewBox="0 0 800 300" aria-label="גרף פניות">
      <defs><linearGradient id="lg-g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="var(--accent)" stop-opacity=".25"/><stop offset="1" stop-color="var(--accent)" stop-opacity="0"/></linearGradient></defs>
      <g class="lg-grid"><line x1="0" y1="75" x2="800" y2="75"/><line x1="0" y1="150" x2="800" y2="150"/><line x1="0" y1="225" x2="800" y2="225"/><line x1="0" y1="300" x2="800" y2="300"/></g>
      <path class="lg-fill" d="M0 250 C 100 245, 160 240, 240 236 C 320 232, 380 228, 420 200 C 470 165, 520 120, 600 90 C 680 60, 740 40, 800 30 V 300 H 0 Z"/>
      <path class="lg-line" d="M0 250 C 100 245, 160 240, 240 236 C 320 232, 380 228, 420 200 C 470 165, 520 120, 600 90 C 680 60, 740 40, 800 30"/>
      <circle class="lg-dot" r="7" cx="0" cy="250"/>
    </svg>
    <div class="lg-val">12</div>
    <div class="lg-ax" dir="rtl"><span>ינואר</span><span>האתר החדש עלה</span><span>דצמבר</span></div>
  </div>
</div></div>

JS

gsap.registerPlugin(ScrollTrigger, DrawSVGPlugin);

(function(){
  const box=document.querySelector(".lg-box"),svg=box.querySelector("svg"),line=svg.querySelector(".lg-line"),dot=svg.querySelector(".lg-dot"),val=box.querySelector(".lg-val");
  const L=line.getTotalLength(),MIN=12,MAX=118;
  const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
  const o={p:reduce?1:0};
  function paint(){const pt=line.getPointAtLength(L*o.p);dot.setAttribute("cx",pt.x);dot.setAttribute("cy",pt.y);
    // מיקום התווית: מקואורדינטות SVG לפיקסלים של הקופסה
    const r=svg.getBoundingClientRect(),b=box.getBoundingClientRect();val.style.left=(r.left-b.left+pt.x/800*r.width)+"px";val.style.top=(r.top-b.top+pt.y/300*r.height)+"px";
    val.textContent=Math.round(MIN+(MAX-MIN)*Math.pow(o.p,1.6));}
  gsap.set(line,{drawSVG:reduce?"100%":"0%"});
  if(reduce){gsap.set(".lg-fill",{opacity:1});paint();return;}
  gsap.timeline({onUpdate:paint,scrollTrigger:{trigger:".lg-box",start:"top 80%",end:"top 25%",scrub:.5,onRefresh:paint}})
    .to(line,{drawSVG:"100%",ease:"none",duration:1},0)
    .to(o,{p:1,ease:"none",duration:1},0)
    .to(".lg-fill",{opacity:1,duration:.3},.7);
  paint();
})();