امروز برای اولین بار نیاز داشتم برای اپ انگولارم یک انیمیشن بسازم و برای اجرا پارامترهای داینامیک براش ارسال کنم. بعد از تحقیق و پیاده سازی موفق شدم انجامش بدم. اول صورت مسئله رو توضیح بدم که داستان چی بود. طبق طراحی UI پروژه، من باید برای حذف یک سطر سفارش، انیمیشنی پیاده سازی میکردم که سطر رو از سمت راست لیست خارج و محو کنه و سطرهای پایین تر به آرامی بیان بالا و جای سطر حذف شده رو بگیرند. تصمیم گرفتم این انیمیشن رو داخل کامپوننت سطر سفارش و برای host element بسازم.
برای این کار به تغییرات زیر روی host element کامپوننت سطر سفارش نیاز داشتم:
۱. مقدار opacity رو از یک به 0.5 تغییر بدم
۲. مقدار margin left رو از مقدار اولیه صفر پیکسل به دو برابر عرض (width) سطر تغییر بدم.
۳. ارتفاع سطر رو از هر مقدار اولیه ای که هست به صفر تغییر بدم تا سطرهای پایینی به آرامی به سمت بالا حرکت کنند.
قدم اول:
برای پیاده سازی اولیه، یک متغیر boolean ساختم به اسم hideOrderAnimationFlag که برای تریگر کردن انیمیشن ازش استفاده کنم. مقدار اولیه ش هم false گذاشتم، چون سفارش دیده میشه و هنوز مخفی نشده. با تغییر این مقدار به true، انیمیشن شروع به کار میکنه.
قدم دوم:
انیمیشن مربوطه رو به تعریف component اضافه کردم:
اسم انیمیشن hideOrder هست و دو وضعیت exists ( وضعیت اولیه) و removed (وضعیت نهایی) داره. در وضعیت exists (وضعیت اولیه) چسبیده به سمت چپ لیست با وضوح کامل نشون داده میشه ( حالت پیش فرض نمایش سطر ).
در وضعیت removed (وضعیت نهایی) مقدار opacity صفر میشه، ارتفاع سطر به صفر میرسه و مقدار margin left به اندازه ثابت ۲۰۰۰ پیکسل مقداردهی شده. این مقدار بر اساس عرض صفحه و عرض سطر باید تغییر کنه، چون ثابت بودنش ممکنه باعث بشه در بعضی نمایشگرها سطر کامل محو نشه. در صورت مسئله ما، این مقدار باید به حالت متغیر در بیاد و مقدارش دو برابر عرض سطر بعد از رندر شدنش مقداردهی بشه.
برای مقداردهی زمان انیمیشن از وضعیت exists به removed ، از یک متغیر به نام animationTime استفاده کردم که مقدارش ۷۰۰ میلی ثانیه است و ممکنه بعدا به زمانی بهینه تر عوض بشه.
قدم سوم:
حالا موقع bind کردن انیمیشن تعریف شده به host element رسیده:
این کد رو داخل کلاس کامپوننت قرار دادم.
قدم چهارم:
مقدار hideOrderAnimationFlag رو زمانی که انیمیشن باید شروع به کار کنه true میکنم و انیمیشن کار میکنه.
حالا وقتش رسیده که اون ۲۰۰۰ پیکسل رو داینامیک کنیم.
میخوایم مقدار margin left رو به اندازه دو برابر عرض سطر تنظیم کنیم. اول باید ببینیم چطور پارامتر رو برای انیمیشن تعریف کنیم.
قدم اول:
میخوایم مقدار ۲۰۰۰ پیکسل رو مثل پارامتر به انیمیشن پاس بدیم. اول باید پارامتر رو تعریف کنیم:
پارامتر elementWidth ( که البته اسمش رو باید بهتر انتخاب میکردم، چون به margin left ارتباط داره نه دلیلش ) رو با مقدار اولیه صفر تعریف کردم. با اجرای انیمیشن، سطر سفارش در همون وضعیتی که بود به سمت بالا جمع شد و opacity به 0.5 رسید (با marginLeft صفر و بدون حرکت به راست)
مقدار اولیه رو به ۲۰۰۰ پیکسل تغییر دادم و دیدم حرکت به راست هم به انیمیشن اضافه شد. پس تا اینجا پارامتر کار میکنه و فقط کافیه مقدار دو برابر عرض سطر رو بهش پاس بدم.
قدم دوم:
برای محاسبه عرض سطر باید به host element دسترسی داشته باشیم. پس ElementRef رو import میکنیم:
و در constructor کلاس کامپوننت inject میکنیم:
قدم سوم:
میخوایم عرض سطر سفارش رو بعد از رندر کامپوننت به دست بیاریم.
اول یک متغیر به اسم hostElementWidth با مقدار اولیه صفر داخل کامپوننت میسازیم برای اینکه مقدار عرض سطر سفارش رو داخلش نگه داریم:
بعد نیاز به hook انگولار به اسم ngAfterViewInit داریم. پس اول AfterViewInit رو از core وارد ماژول میکنیم تا هوک مورد نظرمون رو implement کنیم:
حالا تابع هوک رو پیاده سازی میکنیم و داخلش عرض سطر سفارش رو به دست آورده و نگه میداریم:
قدم چهارم :
میخوایم مقدار hostElementWidth رو به صورت پارامتر به انیمیشن پاس بدیم:
و کار جمع شد.
تو این مقاله هم با روش ساخت انیمیشن های انگولار آشنا شدیم. هم دسترسی به host element رو در کامپوننت دیدیم. هم تونستیم به انیمیشن انگولار مقدار پاس بدیم.
:)