זוהר עוקב

נותן עומק לסקשן כהה בלי להוסיף תמונה או וידאו. המיקום נכתב למשתנה CSS ולא ל-state, ולכן תזוזת עכבר לא מרנדרת את הדף מחדש. זוהר עוקב הוא רכיב מתוך רכיבים של כליקס. מה שמורידים הוא רכיב שלם, גם כ-HTML עצמאי וגם כרכיב React. אין ספרייה חיצונית, אין שלב בנייה, ואם כליקס ייעלם מחר הקוד ימשיך לעבוד. מתאים לעמודים ולמסמכים שעוסקים בריחוף, בלי ספריות ורקע. באותה סדרה יש גם שאלות נפוצות, ציר תהליך וקרוסלת המלצות.

רכיב · ריחוף · בלי ספריות · רקע

<!-- זוהר עוקב: הוסיפו את המחלקה klix-spotlight לכל אלמנט -->
<style>
  .klix-spotlight{position:relative;overflow:hidden}
  .klix-spotlight::before{
    content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
    background:radial-gradient(var(--klix-spot-size,460px) circle at var(--sx,-9999px) var(--sy,-9999px),
               var(--klix-spot-color,rgba(200,164,21,.22)), transparent 65%);
  }
  .klix-spotlight > *{position:relative;z-index:1}
</style>

<script>
(function () {
  // במגע אין ריחוף, ו-pointerleave לא אמין — הזוהר היה נתקע במקום
  if (!window.matchMedia('(hover: hover)').matches) return;

  document.querySelectorAll('.klix-spotlight').forEach(function (el) {
    var tx = -9999, ty = -9999, cx = -9999, cy = -9999;
    var raf = 0, running = false;

    // החלקה ב-lerp. הלולאה נרגעת מעצמה כשהזוהר מגיע ליעד,
    // כדי שלא יישאר rAF שרץ לנצח על דף שאיש לא נוגע בו.
    function tick() {
      cx += (tx - cx) * 0.18;
      cy += (ty - cy) * 0.18;
      el.style.setProperty('--sx', cx + 'px');
      el.style.setProperty('--sy', cy + 'px');
      if (Math.abs(tx - cx) < 0.5 && Math.abs(ty - cy) < 0.5) { running = false; return; }
      raf = requestAnimationFrame(tick);
    }
    function ensure() { if (!running) { running = true; raf = requestAnimationFrame(tick); } }

    el.addEventListener('pointermove', function (e) {
      var r = el.getBoundingClientRect();
      tx = e.clientX - r.left;
      ty = e.clientY - r.top;
      ensure();
    });
    el.addEventListener('pointerleave', function () { tx = -9999; ty = -9999; ensure(); });
  });
})();
</script>