هوش داده افلاطون
جستجوی عمودی و هوش مصنوعی

لغزنده تصویر چرخان بی نهایت و دایره ای CSS

تاریخ:

لغزنده های تصویر (که به آنها چرخ فلک نیز گفته می شود) همه جا هستند. وجود دارد بسیاری از ترفندهای CSS برای ایجاد اسلایدر مشترک جایی که تصاویر از چپ به راست (یا برعکس) اسلاید می شوند. این همان معامله با بسیاری از کتابخانه های جاوا اسکریپت موجود است که اسلایدرهای فانتزی با انیمیشن های پیچیده ایجاد می کند. ما در این پست هیچ کدام از این کارها را انجام نمی دهیم.

از طریق مجموعه‌ای از مقالات، می‌خواهیم تعدادی لغزنده فانتزی و غیر معمول فقط CSS را بررسی کنیم. اگر از دیدن همان لغزنده های کلاسیک خسته شده اید، در جای مناسبی هستید!

سری CSS Sliders

برای این مقاله اول، ما با چیزی که من آن را "لغزنده تصویر چرخشی دایره ای" می نامم شروع می کنیم:

باحال درسته؟ بیایید کد را تشریح کنیم!

نشانه گذاری HTML

اگه سریال من رو دنبال کردی تزیینات تصویری فانتزی or شبکه CSS و اشکال سفارشی، پس می دانید که اولین قانون من کار با کوچکترین HTML ممکن است. من همیشه سعی می کنم قبل از اینکه کدم را با مقدار زیادی درهم و برهم کنم، راه حل های CSS را پیدا کنم <div>s و چیزهای دیگر

همین قانون در اینجا نیز صدق می کند - کد ما چیزی نیست جز لیستی از تصاویر در یک ظرف.

فرض کنید با چهار تصویر کار می کنیم:

<div class="gallery"> <img src="" alt=""> <img src="" alt=""> <img src="" alt=""> <img src="" alt="">
</div>

خودشه! حال به قسمت جالب کد می رویم. اما ابتدا، ما قصد داریم به این موضوع بپردازیم تا منطق نحوه عملکرد لغزنده ما را درک کنیم.

چگونه کار می کند؟

اینم یه ویدیو که حذفش میکنم overflow: hidden از CSS تا بتوانیم نحوه حرکت تصاویر را بهتر درک کنیم:

مثل این است که چهار تصویر ما روی یک دایره بزرگ قرار گرفته اند که خلاف جهت عقربه های ساعت می چرخد.

همه تصاویر دارای اندازه یکسانی هستند (نشان داده شده با S در شکل). به دایره آبی توجه کنید که دایره ای است که با مرکز تمام تصاویر قطع می شود و دارای شعاع (R). ما بعداً برای انیمیشن خود به این مقدار نیاز خواهیم داشت. R برابر است با 0.707 * S. (من از هندسه ای که این معادله را به ما می دهد بگذرم.)

بیایید کمی CSS بنویسیم!

استفاده خواهیم کرد شبکه CSS برای قرار دادن همه تصاویر در یک منطقه بالای یکدیگر:

.gallery { --s: 280px; /* control the size */ display: grid; width: var(--s); aspect-ratio: 1; padding: calc(var(--s) / 20); /* we will see the utility of this later */ border-radius: 50%;
}
.gallery > img { grid-area: 1 / 1; width: 100%; height: 100%; object-fit: cover; border-radius: inherit;
}

هیچ چیز خیلی پیچیده تا اینجا نیست. قسمت مشکل ساز انیمیشن است.

ما در مورد چرخش یک دایره بزرگ صحبت کردیم، اما در واقعیت، ما هر تصویر را به صورت جداگانه می چرخانیم و توهم یک دایره بزرگ در حال چرخش را ایجاد می کنیم. بنابراین، بیایید یک انیمیشن را تعریف کنیم، mو آن را روی عناصر تصویر اعمال کنید:

.gallery > img { /* same as before */ animation: m 8s infinite linear; transform-origin: 50% 120.7%;
} @keyframes m { 100% { transform: rotate(-360deg); }
}

ترفند اصلی به آن خط برجسته متکی است. به طور پیش فرض، CSS transform-origin دارایی برابر است با center (و یا 50% 50%) که باعث می شود تصویر به دور مرکز خود بچرخد، اما برای انجام این کار به آن نیازی نداریم. ما نیاز داریم که تصویر به دور مرکز بچرخد دایره بزرگ که حاوی تصاویر ما است، بنابراین مقدار جدید برای transform-origin.

از آنجایی که R برابر است با 0.707 * S، می توانیم بگوییم R برابر است با 70.7% از اندازه تصویر در اینجا یک شکل برای نشان دادن چگونگی به دست آوردن آن است 120.7% مقدار:

بیایید انیمیشن را اجرا کنیم و ببینیم چه اتفاقی می افتد:

میدونم میدونم. نتیجه با آنچه ما می خواهیم فاصله دارد، اما در واقعیت ما بسیار نزدیک هستیم. ممکن است به نظر برسد که فقط یک تصویر در آنجا وجود دارد، اما فراموش نکنید که ما همه تصاویر را روی هم قرار داده ایم. همه آنها به طور همزمان در حال چرخش هستند و فقط تصویر بالا قابل مشاهده است. آنچه ما نیاز داریم این است که انیمیشن هر تصویر را به تأخیر بیندازیم تا از این همپوشانی جلوگیری کنیم.

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

اوضاع در حال حاضر بهتر شده است!

اگر سرریز روی کانتینر را پنهان کنیم، می‌توانیم یک نوار لغزنده ببینیم، اما انیمیشن را کمی به‌روزرسانی می‌کنیم تا هر تصویر برای مدت کوتاهی قبل از حرکت در امتداد قابل مشاهده باشد.

برای انجام این کار، فریم های کلیدی انیمیشن خود را به روز می کنیم:

@keyframes m { 0%, 3% { transform: rotate(0); } 22%, 27% { transform: rotate(-90deg); } 47%, 52% { transform: rotate(-180deg); } 72%, 77% { transform: rotate(-270deg); } 98%, 100% { transform: rotate(-360deg); }
}

برای هر یک از 90deg (360deg/4، که در آن 4 تعداد تصاویر است) یک مکث کوچک اضافه می کنیم. هر تصویر برای قابل مشاهده باقی خواهد ماند 5% از مدت زمان کلی قبل از اینکه به مرحله بعدی برویم (27%-22%, 52%-47%، و غیره.). من می خواهم به روز رسانی animation-timing-function با استفاده از یک cubic-bezier() عملکردی که انیمیشن را کمی جذاب‌تر می‌کند:

اکنون نوار لغزنده ما کامل است! خوب، تقریباً عالی است، زیرا ما هنوز لمس نهایی را از دست می دهیم: حاشیه دایره ای رنگارنگ که در اطراف تصاویر ما می چرخد. ما می توانیم از یک شبه عنصر بر روی استفاده کنیم .gallery لفاف برای درست کردن آن:

.gallery { padding: calc(var(--s) / 20); /* the padding is needed here */ position: relative;
}
.gallery::after { content: ""; position: absolute; inset: 0; padding: inherit; /* Inherits the same padding */ border-radius: 50%; background: repeating-conic-gradient(#789048 0 30deg, #DFBA69 0 60deg); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude;
}
.gallery::after,
.gallery >img { animation: m 8s infinite cubic-bezier(.5, -0.2, .5, 1.2);
}

من یک دایره با a ایجاد کردم تکرار گرادیان مخروطی برای پس زمینه هنگام استفاده از a ترفند ماسک زدن که فقط ناحیه پر شده را نشان می دهد. سپس همان انیمیشنی را که برای تصاویر تعریف کرده بودیم روی آن اعمال می کنم.

ما تمام شدیم! ما یک نوار لغزنده دایره ای جالب داریم:

بیایید تصاویر بیشتری اضافه کنیم

کار با چهار تصویر خوب است، اما اگر بتوانیم آن را به هر تعداد تصویر مقیاس کنیم، بهتر است. پس از همه، این هدف از یک نوار لغزنده تصویر است. باید بتوانیم در نظر بگیریم N تصاویر.

برای این کار، ما قصد داریم با معرفی Sass، کد را عمومی‌تر کنیم. ابتدا یک متغیر برای تعداد تصاویر تعریف می کنیم ($n(4).

بیایید با تاخیرها شروع کنیم:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

فرمول تاخیر این است (1 - $i)*duration/$n، که حلقه Sass زیر را به ما می دهد:

@for $i from 2 to ($n + 1) { .gallery > img:nth-child(#{$i}) { animation-delay: calc(#{(1 - $i) / $n} * 8s); }
}

اگر واقعاً بخواهیم می توانیم مدت زمان را نیز متغیر کنیم. اما بریم سراغ انیمیشن:

@keyframes m { 0%, 3% { transform: rotate(0); } 22%, 27% { transform: rotate(-90deg); } 47%, 52% { transform: rotate(-180deg); } 72%, 77% { transform: rotate(-270deg); } 98%, 100% {transform: rotate(-360deg); }
}

بیایید آن را ساده کنیم تا نمای بهتری از الگو داشته باشیم:

@keyframes m { 0% { transform: rotate(0); } 25% { transform: rotate(-90deg); } 50% { transform: rotate(-180deg); } 75% { transform: rotate(-270deg); } 100% { transform: rotate(-360deg); }
}

گام بین هر حالت برابر است با 25% - که هست 100%/4 - و یک را اضافه می کنیم -90deg زاویه - که است -360deg/4. یعنی ما می توانیم حلقه خود را به این شکل بنویسیم:

@keyframes m { 0% { transform: rotate(0); } @for $i from 1 to $n { #{($i / $n) * 100}% { transform: rotate(#{($i / $n) * -360}deg); } } 100% { transform: rotate(-360deg); }
}

از آنجایی که هر تصویر می گیرد 5% از انیمیشن، این را تغییر می دهیم:

#{($i / $n) * 100}%

…با این:

#{($i / $n) * 100 - 2}%, #{($i / $n) * 100 + 3}%

لازم به ذکر است که 5% مقدار دلخواه من برای این مثال است. همچنین می‌توانیم آن را یک متغیر برای کنترل مدت زمانی که هر تصویر باید قابل مشاهده باشد، تبدیل کنیم. من برای سادگی از آن صرف نظر می کنم، اما برای انجام تکالیف، می توانید آن را انجام دهید و اجرای خود را در نظرات به اشتراک بگذارید!

@keyframes m { 0%,3% { transform: rotate(0); } @for $i from 1 to $n { #{($i / $n) * 100 - 2}%, #{($i / $n) * 100 + 3}% { transform: rotate(#{($i / $n) * -360}deg); } } 98%,100% { transform: rotate(-360deg); }
}

آخرین بیت برای به روز رسانی است transform-origin. ما به چند ترفند هندسه نیاز خواهیم داشت. تعداد تصاویر هر چه باشد، پیکربندی همیشه یکسان است. ما تصاویر خود (دایره های کوچک) را در داخل یک دایره بزرگ قرار داده ایم و باید مقدار شعاع را پیدا کنیم. R.

احتمالاً توضیح هندسه خسته کننده ای نمی خواهید، بنابراین در اینجا نحوه یافتن ما آمده است R:

R = S / (2 * sin(180deg / N))

اگر آن را به صورت درصد بیان کنیم، به ما می دهد:

R = 100% / (2 * sin(180deg / N)) = 50% / sin(180deg / N)

… که به معنی transform-origin مقدار برابر است با:

transform-origin: 50% (50% / math.sin(180deg / $n) + 50%);

انجام شد! ما یک نوار لغزنده داریم که با هر تصویر عددی کار می کند!

بیایید نه تصویر را در آنجا بیاندازیم:

هر تعداد عکس را که می خواهید اضافه کنید و به روز رسانی کنید $n متغیر با تعداد کل تصاویر

پسگفتار

با چند ترفند با استفاده از تبدیل های CSS و هندسه استاندارد، یک نوار لغزنده دایره ای زیبا ایجاد کردیم که به کد زیادی نیاز ندارد. نکته جالب در مورد این نوار لغزنده این است که ما نیازی به کپی کردن تصاویر برای حفظ انیمیشن بی نهایت نداریم زیرا یک دایره داریم. پس از یک چرخش کامل، به تصویر اول باز خواهیم گشت!

نقطه_img

جدیدترین اطلاعات

نقطه_img

چت با ما

سلام! چگونه می توانم به شما کمک کنم؟