اعمال انیمیشن با جاوا اسکریپت

Animation with JavaScript

14 آبان 1399
Vue.JS 2: اعمال انیمیشن با جاوا اسکریپت - قسمت 63

در قسمت قبل انیمیشن های CSS را به طور مفصل بررسی کردیم اما شاید بخواهید از جاوا اسکریپت برای اضافه کردن انیمیشن ها استفاده کنید. در این حالت در مورد انواع hook های آن صحبت کردیم اما استفاده از آن ها را به صورت عملی ندیده ایم. برای شروع به فایل App.vue بروید و یک button دیگر ایجاد کنید:

    <transition :name="alertAnimation" mode="out-in">
      <div class="alert alert-info" v-if="show" key="info">This is some info</div>
      <div class="alert alert-warning" v-else key="warning">This is some warning</div>
    </transition>
    <hr />
    <button class="btn btn-primary" @click="load = !load">Load / Remove element</button>
  </div>

یعنی دکمه ای برای نمایش یا حذف چند عنصر از صفحه را تعریف کرده ایم که خصوصیتی به نام load را فعال یا غیرفعال می کند. طبیعتا باید این خصوصیت را در data خود تعریف کنیم:

export default {
  data() {
    return {
      show: false,
      load: true,
      alertAnimation: "fade"
// بقیه کدها //

من علاوه بر تعریف خصوصیت load، مقدار خصوصیت show را نیز روی false گذاشته ام تا تمام کادرها و div های قبلی نمایش داده نشوند و بتوانیم روی انیمیشن جدید کار کنیم. سپس باید یک transition دیگر تعریف کنیم:

    <button class="btn btn-primary" @click="load = !load">Load / Remove element</button>
    <br />
    <br />
    <transition>
      <div style="width: 100px; height: 100px; background-color: lightgreen"></div>
    </transition>
  </div>

من دو br را برای فاصله گذاری بین عناصر قرار داده و سپس transition خود را تعریف کرده ام. این transition یک Div مربعی شکل به ابعاد 100 پیکسل در 100 پیکسل دارد و رنگ پس زمینه آن سبز روشن (lightgreen) می باشد. با ذخیره کد بالا در مرورگر و مراجعه به آن باید مربع سبز رنگ را در مرورگر مشاهده کنیم. اگر مربع را مشاهده نکردید یعنی قسمتی از کد را اشتباه نوشته اید.

در مرحله بعد باید دکمه را به این مربع متصل کنیم و برای این کار خصوصیت load را تعریف کرده ایم بنابراین می گوییم:

    <button class="btn btn-primary" @click="load = !load">Load / Remove element</button>
    <br />
    <br />
    <transition>
      <div style="width: 100px; height: 100px; background-color: lightgreen" v-if="load"></div>
    </transition>

یعنی نمایش این div را با استفاده از v-if مشروط به صحیح بودن load قرار داده ایم. دوباره اگر به مرورگر برگردید و این بار روی دکمه Load / Remove Element کلیک کنید، مربع سبز رنگ مخفی شده و با کلیک بعد دوباره نمایش داده می شود بنابراین همه چیز به درستی کار می کند. حالا نوبت استفاده از جاوا اسکریپت برای ایجاد انیمیشن است (در جلسه قبل hook های آن ها را به شما نشان دادم).

    <transition @before-enter="beforeEnter">
      <div style="width: 100px; height: 100px; background-color: lightgreen" v-if="load"></div>
    </transition>

before-enter یک event خاص است که در جلسه قبل در مورد آن صحبت کردیم. من در کد بالا گفته ام اگر before-enter اتفاق افتاد (emit شد) متدی به نام beforeEnter را اجرا کن (هنوز آن را تعریف نکرده ایم). رویداد بعدی ما برای emit شدن، رویدادی به نام enter است، سپس after-enter را داریم که پس از تمام شدن انیمیشن اجرا می شد و در نهایت enter-cancelled را داریم:

 <transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
    >
<div style="width: 100px; height: 100px; background-color: lightgreen" v-if="load"></div>
 </transition>

کد همان کد قبلی است اما برای خوانا تر شدن آن، قسمت transition را به چند خط شکسته ام. همانطور که می بینید برای هر کدام از این رویدادها یک متد به نام خود آن رویداد قرار داده ام که باید بعدا آن ها را تعریف کنیم.

نکته: شما می توانید از این hook ها روی عناصری که با CSS استایل دهی شده اند نیز استفاده کنید. مثلا می خواهید زمانی که انیمیشن تمام شد (after-enter) یک کد جاوا اسکریپت را اجرا نمایید. برای انجام این کار می توانید به راحتی از همین hook روی عنصر مورد نظر خود استفاده کنید.

تا اینجا hook های مربوط به enter را داشتیم اما اگر جلسه قبل را مطالعه کرده باشید، می دانید که hook هایی برای leave نیز داریم بنابراین آن ها را نیز اضافه می کنم:

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
>
  <div style="width: 100px; height: 100px; background-color: lightgreen" v-if="load"></div>
</transition>

حالا که تمام hook ها را به transition خود اضافه کرده ام باید تک تک متد های قرار داده شده را نیز تعریف کنم. برای این کار به قسمت Script رفته و مثل همیشه methods را تعریف می کنیم:

<script>
export default {
  data() {
    return {
      show: false,
      load: true,
      alertAnimation: "fade"
    };
  },
  methods: {
    beforeEnter(el) {
      console.log("beforeEnter");
    }
  }
};
</script>

beforeEnter به صورت خودکار یک آرگومان می گیرد: عنصری که انیمیشن روی آن اجرا می شود. این آرگومان به صورت خودکار پاس داده می شود و کار ما فقط دریافت کردن آن است. اولین کاری که کرده ام log کردن beforeEnter است تا در کنسول مرورگر بفهمیم چه زمانی به beforeEnter رسیده ایم. در مرحله بعد enter را داریم (اجرای اصلی انیمیشن) بنابراین:

  methods: {
    beforeEnter(el) {
      console.log("beforeEnter");
    },
    enter(el, done) {
      console.log("enter");
      done();
    }
  }

در enter دو آرگومان داریم:

  • آرگومان اول el همیشگی می باشد و همان عنصری است که انیمیشن روی آن اجرا می شود.
  • آرگومان دوم done می باشد که در اصل یک متد است و باید به عنوان آخرین کد، آن را اجرا کنیم.

زمانی که از انیمیشن های CSS استفاده می کردیم، مدت زمان انیمیشن را در همان ابتدا به خصوصیت animation یا transition می دادیم. مثال:

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

اما در hook هایی که در حال حاضر استفاده می کنیم، Vue نمی داند که انیمیشن ما چه زمانی تمام می شود بنابراین حتما باید متد done را صدا بزنیم تا به Vue اعلام کنیم، اجرای انیمیشن تمام شده است.

احتمالا می گویید چرا ما باید به صورت دستی به Vue اعلام کنیم که انیمیشن تمام شده است؟ مگر زمانی که اجرای تابع enter تمام شود، انیمیشن تمام نمی شود؟ آیا Vue نمی تواند به صورت خودکار این مسئله را بفهمد؟ مشکل اینجاست که شاید شما بخواهید کدهای Asynchronous (نامتقارن - مانند درخواست های پس زمینه به سرور یا API خاص) داشته باشید و تا رسیدن پاسخ باید منتظر آن بود. در چنین حالتی اگر Vue به صورت خودکار این مرحله را تمام کند، دیگر منتظر کدهای ما نمی شود و برنامه بهم می ریزد. بنابراین متد done به ما کمک بزرگی می کند.

در قسمت بعد این روند را ادامه می دهیم و بقیه کدها را نیز تکمیل خواهیم کرد.

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

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