ترکیب Transition و Animation

Combination of Transition and Animation

Vue.JS 2: ترکیب transition و animation - قسمت 60

در قسمت قبل از animation ها استفاده کردیم تا بتوانیم یک افکت slide را برای کادر info ایجاد کنیم اما برایتان توضیح دادم که به نظر من باید این انیمیشن را بهتر کنیم.

در ویدیوی بالا، انیمیشن اول مربوط به افکت fade است که در جلسات قبل نوشته شد و با آن کاری نداریم اما انیمیشن دوم مربوط به افکت slide ای است که اخیرا کدهایش را نوشتیم. همانطور که مشاهده می کنید، در این انیمیشن کادر ما بالا و پایین می رود اما همزمان با بالا و پایین رفتن محو نمی شود که باعث ناپسند شدن ظاهر انیمیشن ما شود. راه حل این مشکل ترکیب کردن transition (در افکت fade آن را دیدیم) و animation است. بنابراین در همان فایل App.vue به سراغ کلاس slide-enter رفته و opacity را در آن مشخص می کنیم:

.slide-enter {
    opacity: 0;
  /* transform: translateY(20px); */
}

یعنی زمانی که انیمیشن ما در لحظه شروع است، چیزی قابل نمایش نباشد. یادتان باشد که این کلاس برای زمانی است که کادر info ای در صفحه وجود ندارد و کاربر باید روی دکمه Show Alert کلیک کند تا کادر را ببیند بنابراین در ابتدا opacity حتما روی صفر خواهد بود. سپس در slide-enter-active خصوصیت transition را مشخص می کنیم:

.slide-enter-active {
  animation: slide-in 1s ease-out forwards;
  transition: opacity 0.5s;
}

شما می توانید برای transition از گزینه All (تمام جوانب تغییر یک عنصر) نیز استفاده کنید اما من می خواهم در نوشتن کدها دقیق باشم تا شما بدانید دقیقا چه چیزی را هدف گرفته ایم. من اینجا گفته ام که از لحظه کلیک روی دکمه تا زمان پدیدار شدن کادر info، باید نیم ثانیه طول بکشد. توجه کنید که این مقدار برای transition (محو شدن به آرامی) تنظیم شده است نه برای animation (حرکت بالا به پایین و بالعکس).

احتمالا با خودتان می گویید مگر نمی توانستیم opacity را در همان keyframe ها تغییر بدهیم؟ سوالتان کاملا درست و حق با شما است. به سلیقه خودتان بستگی دارد که آن را در keyframe مشخص کنید یا از transition استفاده کنید. از آنجایی که هدف من یادگیری ترکیب transition و animation است، این کار را انجام داده ام.

برای slide-leave چیزی نمی خواهیم چرا که تمام عناصر به صورت پیش فرض دارای opacity کامل (معادل عدد 1) می باشند بنابراین آن را خالی بگذارید اما برای Slide-leave-active می گوییم:

.slide-leave-active {
  animation: slide-out 1s ease-out forwards;
  transition: opacity 1s;
  opacity: 0;
}

یعنی در اینجا نیز opacity را به transition داده ایم تا به نرمی محو شود (کد قبلی برای شروع انیمیشن و ظاهر شدن کادر info بود و این کد برای انیمیشن خروجی و محو شدن این کادر است). حالا کدها را ذخیره کرده و به مرورگر بروید، کدها به شکل بسیار بهتری نمایش داده می شوند:

شاید فکر کنید که کارمان تمام شده است اما نه! کدهای ما مشکل مهمی دارند. به کدهای انیمیشن توجه کنید:

.slide-enter-active {
  animation: slide-in 1s ease-out forwards;
  transition: opacity 0.5s;
}
.slide-leave-active {
  animation: slide-out 1s ease-out forwards;
  transition: opacity 1s;
  opacity: 0;
}

در کدهای بالا (لحظه اجرای انیمیشن ورودی و خروجی) مقدار animation های slide-in و slide-out روی یک ثانیه تنظیم شده است یعنی یک ثانیه طول می کشد که کل انیمیشن اجرا شود. حالا فرض کنید مقدار transition برای opacity را روی 3 ثانیه تنظیم کنیم:

.slide-leave-active {
  animation: slide-out 1s ease-out forwards;
  transition: opacity 3s;
  opacity: 0;
}

اجرای این کد باعث می شود در مرورگر شاهد چنین صحنه ای باشیم:

همانطور که می بینید، کادر info در آخر کار جهشی را انجام می دهد. قسمتی از دلیل این جهش این است که کادر اول (افکت fade) اجرا می شود بنابراین از بین می رود اما کادر دوم هنوز در حال slide شدن است و از بین نرفته، بنابراین زمانی که fade از بین می رود جای آن خالی شده و عنصر دوم جای عنصر اول را می گیرد. بنابراین با حذف کردن کادر اول مشکل حل می شود مگر نه؟ شاید ما نخواهیم کادر اول را حذف کنیم! آنگاه باید چه کار کرد؟

مسئله اینجاست که وقتی عنصر ما به سمت پایین حرکت کرد و به انتهای حرکتش رسید، باید انیمیشن آن نیز تمام شود اما در حال حاضر زمانی که به پایین می رسد، انیمیشن هنوز ادامه پیدا می کند. یعنی ما animation و transition را با هم ترکیب کرده ایم و Vue نمی داند از کدام یک به عنوان طول انیمیشن استفاده کند. به همین دلیل گزینه طولانی تر (3 ثانیه که برای transition ثبت شده) را انتخاب می کند. ما می توانیم به Vue بگوییم که کدام یک از این خصوصیات را به عنوان خصوصیت اصلی انیمیشن در نظر بگیرد:

<transition name="slide" type="animation">
    <div class="alert alert-info" v-if="show">This is some Info</div>
</transition>

با این کار (اضافه کردن type) گفته ایم که ملاک اصلی ما animation است نه transition. بنابراین زمانی که animation تمام شود (مدت یک ثانیه که حرکت کادر طول می کشد) کل انیمیشن ما نیز تمام خواهد شد و دیگر شاهد آن جهش زشت نیستیم. منظورم از تمام شدن انیمیشن حذف شدن حرکات کادر نیست بلکه منظورم تمام شدن خصوصیت animation در CSS برای فریم ورک Vue است. با اجرای کد بالا در مرورگر چنین نتیجه ای را می بینیم:

در ویدیوی بالا اجرای کل انیمیشن در ظاهر 3 ثانیه طول می کشد اما در اصل خصوصیتِ CSS به نام animation برای Vue (حرکت بالا و پایین عنصر) در همان یک ثانیه تمام شده است بنابراین این خصوصیت (animation) حذف می شود و دیگر با آن کاری نداریم. سپس فقط transition در ادامه کار باقی می ماند (3 ثانیه – ناپدید شدن به آرامی) که کارش را انجام می دهد و نهایتا شاهد جهش نخواهیم بود.

بنابراین یادتان باشد که اگر animation و transition را ترکیب کردید، حتما به Vue بگویید که کدام یک ملاک اصلی برای مدت زمان اجرای انیمیشن است.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.