آهنرباMagnet

هر عنصری رو به سمتِ نشانگر می‌کشه: جابه‌جایی، کج‌شدنِ سه‌بعدی و مقیاس با فنر، و برگشتِ نرم وقتی نشانگر دور می‌شه.

محمدجواد

ساخته شده توسط محمدجواد

سازنده فارسی‌فای، بچه دولوپر

وابستگی‌ها

بدون وابستگی

نوع تعامل

با نزدیک‌شدنِ نشانگر، عنصر به سمتش کشیده می‌شه و هرچی نزدیک‌تر، محکم‌تر؛ هم‌زمان کمی به سمتِ نشانگر کج می‌شه و بزرگ می‌شه. با دور شدن، فنر برش می‌گردونه سرِ جاش و حرکت وسطِ راه رها نمی‌شه. اگه چند آهنربا توی یه ناحیه باشن، به‌طورِ پیش‌فرض فقط نزدیک‌ترین به نشانگر کشیده می‌شه؛ با خاموش‌کردنِ `exclusive` همه با هم میدان می‌سازن. روی صفحه‌ی لمسی نشانگری نیست، پس حرکت نمی‌کنه — برای همون حالت `autoPreview` یا یه انیمیشنِ جایگزین بده.

پراپ‌ها

گزینه‌هایی که می‌تونی به کامپوننت بدی؛ ستاره‌دارها اجباری‌اند.

children*
ReactNode

عنصری که حرکت می‌کنه. خودِ کامپوننت ظاهر ندارد؛ هر چیزی بده حرکت می‌گیرد.

padding
numberپیش‌فرض: 100

بردِ کشش از لبه‌ی عنصر، پیکسل. بزرگ‌تر یعنی از دورتر جذب می‌کنه.

magnetStrength
numberپیش‌فرض: 2

قدرتِ کشش؛ جابه‌جایی بر این تقسیم می‌شه. ۱ یعنی عیناً دنبالِ نشانگر، ۳ یعنی یک‌سومِ راه.

maxOffset
number

سقفِ جابه‌جایی از جای اصلی، پیکسل. ندادنش یعنی بدونِ سقف.

exclusive
booleanپیش‌فرض: true

فقط نزدیک‌ترین آهنربا کشیده شود. برای گروه‌های کنارِ هم خاموشش کن تا همه با هم میدان بسازند.

axis
"both" | "x" | "y"پیش‌فرض: "both"both · x · y

محورِ کشش.

نصب

۱. این آدرس رو یک‌بار توی components.json بذار تا shadcn مخزن فارسی‌فای رو بشناسه.

components.jsonjson
{
  "registries": {
    "@farsify": "https://farsify.ir/r/{name}.json"
  }
}

۲. بعد با دستورِ زیر کامپوننت رو نصب کن.

npx shadcn@latest add @farsify/magnet

پیش‌نیاز: Tailwind CSS v4 و صفحهٔ راست‌به‌چپ dir="rtl".

نمونه

magnet.tsxtsx
"use client";

import Magnet from "@/components/farsify/magnet";

export function MagneticButton() {
  return (
    <Magnet padding={140} magnetStrength={2.4} tilt={6} scale={1.05}>
      <button className="rounded-full bg-black px-6 py-3 text-white">
        شروع کنید
      </button>
    </Magnet>
  );
}

// چند آهنربای کنارِ هم: همه با هم میدان می‌سازند
<Magnet exclusive={false} padding={90} maxOffset={18}>
  <span className="chip">خانه</span>
</Magnet>

// پیش‌نمایشِ بی‌تعامل (کارت/گالری): نشانگرِ خیالی مدار می‌زند
<Magnet autoPreview padding={120}>
  <div className="card">…</div>
</Magnet>

نکته‌ها

  • بدونِ هیچ وابستگی: فنر روی `requestAnimationFrame` حل می‌شه و حلقه وقتی نشست، خودش می‌خوابه — توی سکون صفر مصرفِ CPU.
  • همه‌ی آهنرباهای صفحه یک شنونده‌ی `pointermove` مشترک دارند؛ ده‌ها آهنربا هزینه‌ی چند برابر نمی‌سازد.
  • برای نوارِ آیکن‌ها `exclusive={false}` بده تا کلِ نوار به سمتِ نشانگر خم شه، نه فقط یه آیکن.
  • روی لمس حرکت نمی‌کنه (نشانگری نیست)؛ اگه پیش‌نمایشِ موبایل می‌خوای `autoPreview` رو روشن کن.
  • `maxOffset` تورِ ایمنیِ چیدمان است: بدونش عنصرِ نزدیک به مرکزِ ناحیه می‌تواند تا نصفِ فاصله جابه‌جا شود.

مجوز

کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژه‌ی خودت نگهش دار. برای پروژه‌های شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسی‌فای رو یه جا توی پروژه نگه دار.