کاستومایز
پوسترهای پرندهFlying Posters
حلقهی بینهایتِ پوستر که با اسکرول یا کشیدن میچرخه و هر پوستر موقعِ عبور از لبهها دور میزنه و از سمتِ دیگه برمیگرده — با ستونهای یکدرمیان، خمِ اسکرول و محوِ لبه.
وابستگیها
نوع تعامل
چرخِ ماوس روی صحنه، پوسترها رو میچرخونه (صفحه اسکرول نمیشه) و کشیدن با نشانگر یا انگشت هم همین کار رو میکنه. پوسترهای نزدیکِ دو سرِ صحنه با منحنیِ نرم دور میزنن و از سمتِ دیگه برمیگردن؛ با `speed` یه رانشِ پیوسته بساز و با `lean` بذار موقعِ اسکرولِ تند به عقب خم شن. کلیکِ کوتاه روی هر پوستر با `onItemClick` گزارش میشه.
پراپها
گزینههایی که میتونی به کامپوننت بدی؛ ستارهدارها اجباریاند.
itemsArray<string | { image: string; link?: string; alt?: string }>پیشفرض: []تصویرهای پوسترها؛ هر کدام برای پرکردنِ قاب برشِ مرکزی میخورند و برای پر شدنِ دید تکرار میشوند. دموی میزکار شش عکسِ محلی میدهد.
planeWidthnumberپیشفرض: 320عرضِ هر پوستر بر حسبِ پیکسل، در دوربینِ پیشفرض.
planeHeightnumberپیشفرض: 320ارتفاعِ هر پوستر بر حسبِ پیکسل، در دوربینِ پیشفرض.
distortionnumberپیشفرض: 3اینکه یک گوشهی پوستر چقدر زودتر از گوشهی دیگر بچرخد؛ همان پیچشِ حینِ عبور، ۰ تا ۱۰.
scrollEasenumberپیشفرض: 0.01پوسترها چقدر سریع خودشان را به چرخ و کشیدن برسانند؛ عددِ کمتر یعنی لغزشِ کشیدهتر (۰٫۰۰۲ تا ۰٫۱).
cameraFovnumberپیشفرض: 45زاویهی دیدِ دوربین بر حسبِ درجه؛ زاویهی بازتر یعنی دوردستتر.
نصب
۱. این آدرس رو یکبار توی components.json بذار تا shadcn مخزن فارسیفای رو بشناسه.
{
"registries": {
"@farsify": "https://farsify.ir/r/{name}.json"
}
}۲. بعد با دستورِ زیر کامپوننت رو نصب کن.
npx shadcn@latest add @farsify/flying-postersپیشنیاز: Tailwind CSS v4 و صفحهٔ راستبهچپ dir="rtl".
نمونه
"use client";
import FlyingPosters from "@/components/farsify/flying-posters";
const posters = [
"/images/peak.jpg",
"/images/forest.jpg",
"/images/beach.jpg",
"/images/night.jpg",
"/images/mist.jpg",
"/images/city.jpg",
];
export function PosterWall() {
return (
<div style={{ height: 560, position: "relative" }}>
<FlyingPosters items={posters} />
</div>
);
}
// چرخ ماوس و کشیدن از قبل فعالاند؛ صحنه باید ارتفاعِ قطعی داشته باشد
// دیوارِ گالریِ سهستونه با پوسترهای عمودی و گوشهی گرد
<FlyingPosters
items={posters}
planeWidth={220}
planeHeight={300}
columns={3}
radius={14}
axis="diagonal"
/>
// رانشِ آرام وقتی کسی اسکرول نمیکند + خمِ هنگامِ اسکرولِ تند
<FlyingPosters items={posters} speed={-24} lean={0.6} shading={0.3} />
// پوسترهای کرویگوشه با محوِ لبهها
<FlyingPosters items={posters} radius={28} fade={0.55} />
// کلیکِ کوتاه روی هر پوستر
<FlyingPosters
items={posters}
onItemClick={(item, index) => console.log(item.image, index)}
/>نکتهها
- بدونِ هیچ وابستگی: یک برنامهی WebGL2، اطلسِ بافتِ همهی تصویرها و رسمِ همهی پوسترها با `drawElementsInstanced` در یک فراخوانی.
- چرخِ ماوس روی بوم صفحه رو اسکرول نمیکنه و خودِ پوسترها رو میچرخونه؛ برای اسکرولِ عادیِ صفحه، نشانگر رو از روی بوم بردار.
- چند ستون با `columns` + ستونهای یکدرمیان (`alternate`) حسِ دیوارِ گالری میدهد؛ برای پوسترهای عمودیِ واقعی `planeHeight` را از `planeWidth` بیشتر بگیرید.
- توی `prefers-reduced-motion` رانش و خم خاموشه و ورودِ محو فوری میشه؛ کشیدنِ دستی سرِ جاشه.
- اگر WebGL2 در دسترس نباشد، صحنه ساکت میماند — مرجع هم همین رفتار را دارد.
مجوز
کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژهی خودت نگهش دار. برای پروژههای شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسیفای رو یه جا توی پروژه نگه دار.