امروز، شما یاد خواهید گرفت که چگونه یک مسیر ترن هوایی ایجاد کنید که توپ با استفاده از بزیرهای مکعبی و انتقال CSS دنبال می کند. شما همچنین خواهید آموخت که چگونه
cubic-bezier
تابع در CSS با جزئیات کار می کند و چگونه می توان چندین انیمیشن ساده را برای ایجاد یک انیمیشن پیچیده روی هم قرار داد.
توجه داشته باشید: این مقاله فرض می کند که شما دانش اولیه انیمیشن های CSS را دارید. اگر این کار را نمی کنید، لطفاً قبل از ادامه این مقاله، این راهنمای تام واترهاوس را بررسی کنید.
ایجاد انیمیشن های CSS پیشرفته برای اهداف UX و طراحی عالی است. شما می توانید یک وب سایت تعاملی بسازید که بازدید کننده را خوشحال کند و باعث شود وب سایت شما را به خاطر بسپارد. انیمیشنها موضوع سختی به نظر میرسند، اما زمانی که آنها را درک کردید، میتوانید وبسایتهای شگفتانگیزی مانند آن ایجاد کنید این یکی! بله، این فقط با CSS ایجاد می شود!
ابتدا بیایید به جادو و قدرت آن شیرجه بزنیم cubic-bezier
عملکرد.
cubic-bezier
: چیست و چگونه می توانیم از آن استفاده کنیم؟
در cubic-bezier
تابع در CSS یک تابع آسانکننده است که به شما کنترل کاملی بر نحوه رفتار انیمیشن شما با توجه به زمان میدهد. در اینجا تعریف رسمی است:
«یک تابع آسانکننده مکعبی Bézier یک نوع است عملکرد تسهیل با چهار عدد واقعی تعریف می شود که دو نقطه کنترل P1 و P2 یک منحنی مکعبی بزیه را مشخص می کند که نقاط انتهایی P0 و P3 به ترتیب در (0، 0) و (1، 1) ثابت هستند. مختصات x P1 و P2 به محدوده محدود شده است [0, 1]”
– پیش نویس پیشنهادات نامزد W3C سطح 1 توابع تسهیل CSS، 1 آوریل 2021
اگر میخواهید درباره عملکردهای آسانسازی اطلاعات بیشتری کسب کنید، میتوانید این مقاله توسط Adrian Bece را بررسی کنید. پشت صحنه چقدر خطی است، cubic-bezier
و توابع راه پله کار می کنند.

محور x (زمان) بین محدود شده است [0,1]. با این حال، محور y (خروجی) به محدوده خاصی محدود نمی شود.
هدف ما برای مکعب بیزیر ایجاد سهمی کشویی در ابتدای انیمیشن مورد نیاز است. اما برای اینکه به آنجا برسیم، از کوچک شروع می کنیم و یاد می گیریم که چگونه یک منحنی سهموی با استفاده از مکعب بزیر ایجاد کنیم.
منحنی سهمی
از تعریف منحنی سهموی، ممکن است متوجه شوید که ایجاد یک منحنی سهموی کامل غیرممکن به نظر می رسد زیرا P0 باید در (0، 0) و P3 باید در (1، 1) باشد در حالی که منحنی های سهمی در همان محور افقی شروع و پایان می یابند. ، بنابراین ما باید P3 در (1، 0) باشد.

درست است که ما نمی توانیم یک سهمی کامل بسازیم. با این حال، ما می توانیم چیزی نزدیک به آن ایجاد کنیم.
ایجاد توپ
ما باید یک شی بسازیم که برای انیمیشن خود مدل کنیم، من یک توپ را انتخاب کردم زیرا ساده است، اما البته شما آزاد هستید که از هر شیئی که می خواهید استفاده کنید.
کد زیر را به فایل های HTML و CSS خود اضافه کنید:
<div class="ball"></div>
.ball {
background-color: burlywood;
height: 50px;
width: 50px;
border: 1px solid black;
border-radius: 50px;
position: fixed;
left: 10px;
top: 300px;
}
شما باید چیزی شبیه به این دریافت کنید:

حرکت توپ در امتداد محور X
ما می خواهیم دو انیمیشن بسازیم، یکی در محور x و دیگری در محور y. انیمیشن محور x یک انیمیشن خطی است که توپ را از یک نقطه به نقطه دیگر حرکت می دهد.
- یک فریم کلیدی اضافه کنید، آن را x می نامیم:
@keyframes x {
to {
left: 500px;
}
}
- فریم کلیدی را به ویژگی انیمیشن در کلاس توپ اضافه کنید:
.ball {
background-color: burlywood;
height: 50px;
width: 50px;
border: 1px solid black;
border-radius: 50px;
position: fixed;
left: 10px;
top: 300px;
animation: x 2s linear forwards;
}
حالا توپ در امتداد محور x حرکت می کند!
قلم را ببینید [x-axis animation](https://codepen.io/smashingmag/pen/qBxawvO) توسط یسرا عماد.
حرکت توپ در امتداد محور Y
برای انیمیشن در امتداد محور y، می خواهیم توپ در امتداد یک منحنی حرکت کند. آخرین نقطه در محور y همان نقطه اولیه است. با این حال، برای اینکه انیمیشن اجرا شود، باید تفاوت کوچکی در محور y ایجاد کنیم. بنابراین، در مورد ما، ما را تغییر خواهیم داد top
ویژگی کلاس توپ از 300 تا 299.5.
توجه کنید که چگونه ما کاهش یافته مقدار ویژگی بالا؛ این باعث می شود انیمیشن ما در جهت عادی حرکت کند (پایین → بالا → پایین). اگر به جای آن مقدار ویژگی top را به 300.5 افزایش دهیم، انیمیشن را در جهت مخالف پخش می کند:
@keyframes y {
to {
top: 299.5px;
}
}
- فریم های کلیدی جدید را به همان انیمیشن در کلاس توپ اضافه کنید
animation: x 2s linear forwards, y 2s cubic-bezier(0, 500, 1, 500) forwards;
این انیمیشن حاصل می شود:
قلم را ببینید [y-axis animation](https://codepen.io/smashingmag/pen/mdXRzRW) توسط یسرا عماد.
اما چرا ما این مقادیر مشخص تابع مکعب بیزیر را انتخاب کردیم؟ بیایید دریابیم!
🚨 هشدار: ریاضیات در پیش است! 🚨
ریاضیات پشت cubic-bezier
عملکرد
یک بزیر مکعبی را می توان با استفاده از فرمول زیر تعریف کرد:
$$P = (1-t)^3P_0 + 3(1-t)^2tP_1 +3(1-t)t^2P_2+t^3P_3$$
ما می خواهیم منحنی ما دقیقاً در 0.5 زمان به اوج برسد. برای انجام این کار، $P_1$ و $P_2$ باید به ترتیب در (0,x) و (1,x) باشند. اگر نمیخواهید پیک روی 0.5 باشد، باید موقعیت زمانی $P_0$ و $P_1$ را تغییر دهید. در حال حاضر، ما به ایجاد منحنی در نیمه زمان انیمیشن پایبند هستیم.
اکنون می دانیم که:
$$P_0 = (0.0)، P_1 = (0، X)، P_2 = (1،X)، P_3 = (1،1)$$
با جایگزینی معادله، می توانیم دو معادله مجزا به دست آوریم، یکی برای هر محور:
- محور x:
$$X
.ball {
background-color: burlywood;
height: 50px;
width: 50px;
border: 1px solid black;
border-radius: 50px;
position: fixed;
left: 10px;
top: 300px;
}
اکنون باید مسیر ترن هوایی را بسازیم. مسیر از دو بخش تشکیل شده است:
- قسمت کشویی
- قسمت حلقه

قسمت کشویی
ایجاد بخشی که توپ در آن می لغزد را می توان با استفاده از تابع مکعب-بزیر انجام داد! این انیمیشن از 2 انیمیشن تشکیل شده است، یکی در امتداد محور x و دیگری در امتداد محور y. انیمیشن محور x یک انیمیشن خطی معمولی در امتداد محور x است. می توانیم فریم های کلیدی آن را به صورت زیر تعریف کنیم:
@keyframes x {
to {
left: 500px;
}
}
به صورت زیر آن را به ویژگی انیمیشن خود در مسیر توپ اضافه کنید:
animation: x 4s linear forwards
انیمیشن محور y همانی است که در آن از تابع مکعب بزیر استفاده خواهیم کرد. اجازه دهید ابتدا فریم های کلیدی انیمیشن را تعریف کنیم. ما می خواهیم تفاوت بین نقطه شروع و نقطه پایان آنقدر کم باشد که توپ تقریباً به همان ارتفاع برسد.
@keyframes y {
to {
top: 299.5px;
}
}
حالا بیایید به تابع مکعب بیزیر فکر کنیم. ما میخواهیم مسیرمان به آرامی به سمت راست حرکت کند، سپس وقتی میلغزد، باید سریعتر پیش رود.

- حرکت آهسته به سمت راست به این معنی است که P1 در امتداد محور x قرار خواهد گرفت. بنابراین، ما می دانیم که در (V, 0) است
- باید یک V مناسب انتخاب کنیم که باعث شود انیمیشن ما به آرامی به سمت راست برود اما نه خیلی زیاد که کل فضا را اشغال کند. در این مورد متوجه شدم که 0.55 بهترین تناسب را دارد
- برای دستیابی به اثر لغزشی، باید P2 را به سمت پایین محور y حرکت دهیم (مقدار منفی) بنابراین P2=(X, -Y)
- Y باید یک مقدار بزرگ باشد. در این مورد، Y=800 را انتخاب کردم
- برای بدست آوردن X، می دانیم که سرعت انیمیشن ما باید در هنگام لغزش سریعتر و در هنگام بالا رفتن دوباره کندتر باشد. بنابراین، هر چه X به صفر نزدیکتر باشد، انیمیشن شیبدارتر میشود. در این مورد، X = 0.8 را بگذارید
حالا شما تابع مکعب بیزیر خود را دارید، این کار خواهد بود cubic-bezier(0.55, 0, 0.2, -800)
.
بیایید فریم های کلیدی را به ویژگی انیمیشن خود اضافه کنیم:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards;
این اولین قسمت از انیمیشن ما است، بنابراین تاخیر انیمیشن صفر است. ما باید یک ویژگی animation-delay اضافه کنیم زیرا از انیمیشن بعدی، انیمیشن ها در زمانی متفاوت از انیمیشن اول شروع می شوند.
animation-delay: 0s, 0s;
توجه داشته باشید: اگر در مورد مقادیر تابع مکعب بیزیر مطمئن نیستید، می توانید بررسی کنید این وب سایت جایی که میتوانید مکعببزیرها را تجسم کنید و ایده بگیرید که P0 و P1 باید در کجا باشند.
افزودن یک انیمیشن در امتداد محور X
قبل از ایجاد حلقه، توپ باید برای مدت کوتاهی در امتداد محور x حرکت کند تا بین هر دو انیمیشن فاصله وجود داشته باشد. بنابراین، بیایید این کار را انجام دهیم!
@keyframes x2 {
to {
left: 600px;
}
}
- آن را به ویژگی انیمیشن اضافه کنید:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards, x2 0.5s linear forwards;
این انیمیشن باید بعد از انیمیشن کشویی شروع شود و انیمیشن کشویی چهار ثانیه طول می کشد، بنابراین تاخیر انیمیشن چهار ثانیه خواهد بود:
animation-delay: 0s, 0s, 4s;
نتیجه
قلم را ببینید [rollercoaster part 1](https://codepen.io/smashingmag/pen/JjpEmLG) توسط یسرا عماد.
قسمت حلقه
برای ایجاد یک دایره (حلقه) در CSS، باید دایره را به مرکز حلقه منتقل کرده و انیمیشن را از آنجا شروع کنیم. ما می خواهیم شعاع دایره 100 پیکسل باشد، بنابراین موقعیت دایره را به تغییر می دهیم top: 200px
(300 – شعاع دلخواه). با این حال، این باید پس از انجام انیمیشن کشویی اتفاق بیفتد، بنابراین انیمیشن دیگری با مدت زمان صفر ثانیه ایجاد می کنیم و تاخیر انیمیشن مناسب را اضافه می کنیم.
@keyframes pointOfCircle {
to {
top: 200px;
}
}
- این را به لیست انیمیشن های با مدت زمان = 0 ثانیه اضافه کنید
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards;
- تاخیر انیمیشن را اضافه کنید که 4.5 ثانیه خواهد بود
animation-delay: 0s, 0s, 4s, 4.5s;
خود حلقه
برای ایجاد یک انیمیشن حلقه:
- یک فریم کلیدی ایجاد کنید که توپ را به موقعیت قبلی برمی گرداند و سپس توپ را می چرخاند:
@keyframes loop {
from {
transform: rotate(0deg) translateY(100px) rotate(0deg);
}
to {
transform: rotate(-360deg) translateY(100px) rotate(-360deg);
}
}
- فریم های کلیدی حلقه را به ویژگی انیمیشن اضافه کنید:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards, loop 3s linear forwards;
- تأخیر انیمیشن را اضافه کنید که در اینجا نیز 4.5 ثانیه خواهد بود:
animation-delay: 0s, 0s, 4s, 4.5s, 4.5s;

حرکت دادن توپ در امتداد محور X (دوباره)
ما تقریباً تمام شده ایم! فقط باید توپ را بعد از انیمیشن در امتداد محور x حرکت دهیم تا توپ دقیقاً بعد از حلقه متوقف نشود، همانطور که در تصویر بالا انجام می شود.
@keyframes x3 {
to {
left: 1000px;
}
}
- فریم های کلیدی را به ویژگی انیمیشن اضافه کنید:
animation: x 4s linear forwards,
y 4s cubic-bezier(0.55, 0, 0.2, -800) forwards, x2 0.5s linear forwards,
pointOfCircle 0s linear forwards, loop 3s linear forwards,
x3 2s linear forwards;
- با اضافه کردن تاخیر مناسب، در اینجا 7.5 ثانیه خواهد بود:
animation-delay: 0s, 0s, 4s, 4.5s, 4.5s, 7.5s;
خروجی نهایی
قلم را ببینید [rollercoaster](https://codepen.io/smashingmag/pen/oNEBadz) توسط یسرا عماد.
نتیجه
در این مقاله به نحوه ترکیب چندین فریم کلیدی برای ایجاد یک مسیر انیمیشن پیچیده پرداختیم. ما همچنین مکعببزیرها و نحوه استفاده از آنها را برای ایجاد عملکرد آسانکننده خود توضیح دادیم. من توصیه می کنم ادامه دهید و مسیر انیمیشن خود را ایجاد کنید تا دستان خود را با انیمیشن ها کثیف کنید. اگر به کمک نیاز دارید یا میخواهید بازخورد بدهید، میتوانید به هر یک از آنها پیام ارسال کنید لینک های اینجا. روز/شب فوق العاده ای داشته باشید!

(il)