جلدِ ترکِ سقوط از فدایی
سقوطفدایی
سقوط — فدایی

کارتِ کجTilted Card

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

محمدجواد

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

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

وابستگی‌ها

بدون وابستگی

نوع تعامل

با حرکتِ نشانگر روی کارت، کارت به سمتش کج می‌شه و برقِ نور و سایه با همون زاویه جابه‌جا می‌شن؛ یه برچسبِ کوچیک هم دنبالِ نشانگر می‌آد. اگه `backContent` بدی، کلیک یا Enter کارت رو برمی‌گردونه (کشیدنِ نشانگر تا ۶ پیکسلِ بیشتر، چرخش رو لغو می‌کنه تا با انتخابِ متن اشتباه نشه). روی موبایل، کج‌شدن با کج‌کردنِ خودِ گوشی کار می‌کنه (توی iOS با اولین لمس اجازه می‌گیره). با `prefers-reduced-motion` دامنهٔ کج‌شدن به ۳۰٪ و برچسبِ سرگردان خاموش می‌شه.

پراپ‌ها

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

imageSrc
string

تصویری که سطحِ کارت رو پر می‌کنه.

altText
stringپیش‌فرض: "تصویرِ کارت"

متنِ جایگزینِ تصویر — وقتی کارت تعاملیه، همین توی `aria-label` هم می‌آد.

children
ReactNode

محتوای روی کارت — روی تصویر یا به‌جاش.

captionText
stringپیش‌فرض: ""

متنِ برچسبِ کوچیکی که دنبالِ نشانگر می‌آد و با سرعتِ حرکت سر می‌خوره.

showTooltip
booleanپیش‌فرض: true

نمایشِ برچسبِ دنبال‌کننده توی هاور.

overlayContent
ReactNodeپیش‌فرض: null

محتوایی که جلوی سطحِ کارت، لایه‌بالاتر از اون، شناور می‌شه.

نصب

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

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

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

npx shadcn@latest add @farsify/tilted-card

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

نمونه

tilted-card.tsxtsx
"use client";

import TiltedCard, { TiltedCardLayer } from "@/components/farsify/tilted-card";

export function AlbumCard() {
  return (
    <TiltedCard
      imageSrc="/album.jpg"
      altText="جلدِ آلبوم"
      captionText="سقوط — فدایی"
      containerWidth="100%"
      containerHeight="100%"
      imageWidth="100%"
      imageHeight="100%"
      rotateAmplitude={14}
    >
      {/* لایهٔ شناور — با کج‌شدنِ کارت جلو می‌آید */}
      <TiltedCardLayer depth={28}>
        <div className="absolute bottom-4 start-4 text-white">
          <strong className="text-[17px] font-semibold">سقوط</strong>
        </div>
      </TiltedCardLayer>
    </TiltedCard>
  );
}

// پشتِ کارت: با کلیک، لمس یا Enter برمی‌گردد
<TiltedCard
  imageSrc="/album.jpg"
  captionText="جزئیات"
  backContent={
    <div className="flex h-full flex-col justify-center gap-2 p-5">
      <strong>ترک‌لیست</strong>
      <span className="text-sm opacity-70">پشتِ کارت هر چیزی می‌تواند باشد</span>
    </div>
  }
/>

نکته‌ها

  • این پورت **هیچ چیزش از هندسه آینه نشده**: کج‌شدن، جهتِ سایه و برق فیزیکِ محضن و `dir` اثری روی‌شون نداره — متنِ فارسیِ روی کارت و برچسبِ دنبال‌کننده خودبه‌خود راست‌به‌چپ رندر می‌شه. جای متا و دکمه‌ها روی جلد، چیدمانه نه فیزیک، و توی دمو با `start`/`end` منطقی چیده شده.
  • لایهٔ شناور رو با `TiltedCardLayer` بساز: `<TiltedCardLayer depth={28}>` با کج‌شدنِ کارت جلو می‌آد و عمقِ سه‌بعدیِ واقعی می‌ده — depthِ منفی پشتِ تصویر می‌ره.
  • پشتِ کارت هر چیزی می‌تونه باشه: ترک‌لیست، فرم، کد QR. تا `backContent` ندی کارت تعاملی نمی‌شه و کلیک‌پذیری هم به همین دلیل خاموش می‌مونه.
  • چرخشِ ناخواسته با انتخابِ متن پشتِ کارت نمی‌خوره: کشیدنِ نشانگر بیش از ۶ پیکسل (FLIP_THRESHOLD مرجع) کلیکِ چرخش رو لغو می‌کنه.
  • برای ردیفی از کارت‌ها `introDelay` رو پلکانی بده (`index * 110` مثلِ مرجع) تا کارت‌ها یکی‌یکی بالا بیان.
  • روی موبایل دو راهِ کج‌شدن داری: لمس (پرحساسیت، مثلِ مرجع) و ژیروسکوپ که با اولین لمس اجازهٔ iOS رو هم خودش می‌گیره.

مجوز

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