→ לכל המאגר

B61 · משיכה מגנטית לעבר הסמן

התנהגויות vanilla JS hover ומיקרו ממתין

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

מתי משתמשים: CTA ראשי אחד בעמוד, אייקונים חברתיים, לוגו בהדר. דסקטופ בלבד, ולעולם לא על טקסט רץ.

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

הדמו

in
ig
מקור: ReactBits Magnet. נכתב מחדש: המרחק נמדד מהמרכז, המשיכה היא שבר מהמרחק (לא מיקום מוחלט), על translate בלבד, וחזרה עם טרנזישן ארוך יותר מהמשיכה.

קוד להדבקה

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

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

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}
.gbtn{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding-inline:28px;border-radius:999px;background:var(--accent, #4a3aff);color:var(--accent-ink, #fff);font-weight:500;font-size:16px;border:0;cursor:pointer;font-family:inherit}

/* B61 · משיכה מגנטית לעבר הסמן */
.mg-wrap{display:flex;justify-content:center;gap:28px;flex-wrap:wrap;padding-block:40px}
.mg{position:relative;padding:40px}
.mg .gbtn,.mg .mg-ic{translate:var(--x,0) var(--y,0);transition:translate .25s cubic-bezier(.2,.6,.2,1)}
.mg.leave .gbtn,.mg.leave .mg-ic{transition-duration:.6s}
.mg-ic{width:56px;height:56px;border-radius:50%;background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);display:grid;place-items:center;font-weight:700;color:var(--ink, #16182b)}
@media (prefers-reduced-motion: reduce){.mg .gbtn,.mg .mg-ic{transition:none;translate:none}}

HTML

<div class="stage tight"><div class="mg-wrap">
  <div class="mg"><button class="gbtn">בואו נדבר</button></div>
  <div class="mg"><span class="mg-ic">in</span></div>
  <div class="mg"><span class="mg-ic">ig</span></div>
</div></div>

JS

(function(){
  if(!matchMedia("(hover:hover) and (pointer:fine)").matches||matchMedia("(prefers-reduced-motion: reduce)").matches)return;
  const PULL=.35;   // כמה מהמרחק הכפתור עובר לעבר הסמן. 1 = דבוק לסמן, זה כבר לא אלגנטי
  document.querySelectorAll(".mg").forEach(zone=>{
    const el=zone.firstElementChild;
    zone.addEventListener("mousemove",e=>{
      const r=zone.getBoundingClientRect(),dx=e.clientX-(r.left+r.width/2),dy=e.clientY-(r.top+r.height/2);
      zone.classList.remove("leave");
      el.style.setProperty("--x",(dx*PULL).toFixed(1)+"px");el.style.setProperty("--y",(dy*PULL).toFixed(1)+"px");
    });
    zone.addEventListener("mouseleave",()=>{zone.classList.add("leave");el.style.setProperty("--x","0px");el.style.setProperty("--y","0px");});
  });
})();