شروع کار با انیمیشن های React Native

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

 شروع کار با انیمیشن های React Native

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

تاریخچه و سیر تکاملی

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

برای دستیابی به بالاترین عملکرد انیمیشن های ری اکت نیتیو باید در thread مربوط به UI رندر شود. از آنجایی که داده ها باید در عنصر پل مرتب شوند این کار، گاهی اوقات باعث انسداد thread مربوط به جاوا اسکریپت می شود، این مشکل از سال 2015 شایع بوده است که استفاده از انیمیشن های ری اکت نیتیو یکی از بزرگترین محدودیت های ری اکت بوده اند.

خوشبختانه این شرایط از زمانی که جامعه استفاده کنندگان از انیمیشن های ری اکت نیتیو آن را ساپورت کرده اند بهبود پیدا کرده است، دستیابی به 60 فریم بر ثانیه امروزه برای انیمیشن های ری اکت نیتیو رایج می باشد. API هایی که در این زمینه وجود دارند مانند Animated زمان پردازش انیمیشن های ری اکت نیتیو را به میزان زیادی کاهش داده اند.

 انیمیشن های ری اکت نیتیو


استفاده از Animated API برای بهبود عملکرد

با این وجود کار کردن توسعه دهندگان بر روی بهبود عملکرد انیمیشن های ری اکت نیتیو غیر عادی نیست مخصوصا زمانی که برای انیمیشن های پیچیده تری کار می کنند. همانطور که در بالا گفتیم مشکلات عملکردی به دلیل این است که انیمیشن های ری اکت نیتیو بر روی thread مربوط به جاوا اسکریپت بسیار سنگین هستند که به همین علت سرعت فریم را کاهش می دهند و باعث ایجاد یک تجربه بد در کاربر می شوند. برای غلبه بر این مشکل شما باید سرعت فریم خود را بر روی 60 فریم بر ثانیه نگه دارید.

استفاده از Animated API بهترین کار برای حل این مشکل می باشد، ایده اصلی پشت این کتابخانه این است که تمام انیمیشن ها قبلا یک بار تعریف می شوند و به همین دلیل تعریف آنها در جاوا اسکریپت می تواند به سرعت مرتب سازی شود و به متغیر پل ارسال شود. حال یک مدیریت کننده می تواند به راحتی این انیمیشن را فریم به فریم اجرا کند. روش های زیادی برای پیاده سازی انیمیشن های ری اکت نیتیو وجود دارد که در ادامه برخی از مهمترین آنها را برای شما بیان خواهیم کرد.

 انیمیشن های ری اکت نیتیو


استفاده از مقادیر Animated برای پیاده سازی انیمیشن های ری اکت نیتیو

استفاده از مقادیر Animated در صدر لیست من برای ساختن بلاک هایی برای انیمیشن ها در هر اپلیکیشن ری اکت نیتیو است، این مقادیر در واقع به یک مقدار واقعی اشاره دارند که زمانی که با یک مولفه انیمیشن بازگردانده می شود به یک عدد تبدیل می شود.

به مثال زیر توجه کنید:

Animated.timing(this.value To Animate, {

    toValue: 42;

    duration: 1000;

}).start()

در مثال بالا من مقدار متغیر value.To Animate را برابر 42 تعریف کردم که بعد از 1000 میلی ثانیه اجرا خواهد شد. شما همچنین می توانید از مقادیر Animated  ویژگی ها را تعریف کنید که از جمله این ویژگی ها می توان به میزان تاری و یا پوزیشن اشاره کرد. در ادامه مثالی آورده ایم که پیاده سازی ویژگی تاری با استفاده از مقادیر Animated را نشان می دهد:

<Animated.View style={{ opacity: my Animated Opacity }} />

 انیمیشن های ری اکت نیتیو


استفاده از مدیریت کننده های انیمیشن مانند Animated.timing، Animated.event و Animated.decay

درباره مدیریت کننده انیمیشن های ری اکت نیتیو می توانید مانند ریشه های گراف فکر کنید که مقدار Animated را در هر فریم تغییر می دهد، به عنوان مثال Animated.timing یک مقدار را افزایش می دهد در حالی که Animated.decay مقدار را یک واحد در طول تغییر فریم کاهش خواهد داد. به مثال زیر توجه کنید:

Animated.decay(this.valueToAnimate, {

  velocity: 2.0,

  deceleration: 0.9

}).start();

این مثال انیمیشن های ری اکت نیتیو را با سرعت خاصی اجرا می کند و در یک زمان خاص سرعت آن را کاهش می دهد، من دوست دارم که این کار را در یک برنامه کراس پلتفرم انجام دهم. این یک تجربه عالی است و راه های بسیار زیادی برای ساخت انیمیشن های ری اکت نیتیو به یادماندنی وجود دارد.

شما همچنین می توانید از Animated.event برای زمانی که کاربر شما اسکرول می کند استفاده کنید:

<ScrollView on Scroll={Animated.event(

 [{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]

)}

>

</ScrollView>

در مثال بالا  Animated.event یک تابع باز می گرداند که scrollView's native Event.content Offset.y را در حالت فعلی اسکرول شما تنظیم می کند. به صورت کلی مدیریت کننده های انیمیشن های ری اکت نیتیو در تخصیص دهی با مقادیر Animated و سایر مدیریت کننده های انیمیشن مورد استفاده قرار می گیرند. به عنوان یک نکته جانبی به خاطر داشته باشید که وقتی یک مدیریت کننده یک فریم را به روز رسانی می کند مقدار جدید بلافاصله ویژگی View را به روز رسانی می کند، بنابراین در هنگام تعریف متغیرها به دامنه آنها توجه ویژه ای داشته باشید.

 انیمیشن های ری اکت نیتیو


متدهای تبدیل

متدهای تبدیل به شما کمک می کنند تا بتوانید مقادیر Animated را به یک مقدار Animated جدید تبدیل کنید، شما می توانید از این متدها مانند Animated.add()،Animated.multiply() یا Animated.interpolate() استفاده کنید تا بتوانید متدهای تبدیل را پیاده سازی کنید،  شما می توانید این متدها را در هر ریشه ای از گراف انیمیشن های ری اکت نیتیو به شکل زیر اجرا کنید:

new Animated.Value(55).interpolate(.....) // Transformation operation using Animated.interpolate() method

 انیمیشن های ری اکت نیتیو


استفاده از Animated props

Animated props در واقع ریشه های خاصی از گراف هستند که یک مقدار Animated را به یک pop در یک کامپوننت مپ می کنند. این زمانی تولید می شود که شما یک Animated.view را رندر می کنید و به آن ویژگی هایی را اختصاص می دهید، به قطعه کد زیر توجه داشته باشید:

Var opacity = new Animated.Value(0.7);

<Animated.View style={{ opacity }} />

من در اینجا یک Animated prop اضافه کرده ام که مقدار 0.7 را به یک ویژگی تبدیل می کند، اگر یک متد مقدار را به روز رسانی کند این تغییر در ویژگی View نمایان خواهد شد. متدهایی که در بالا توضیح داده شدند یک نقش حیاتی را در به حرکت در آوردن اشیا در ری اکت نیتیو ایفا می کنند.

مقدار Animated برای هر فریم از انیمیشن توسط مدیریت کننده انیمیشن تغییر می کند که این مدیریت کننده های انیمیشن های ری اکت نیتیو شامل Animated.Timing، Animated.Event و Animated.Decay می باشند. بعد از انجام این کار نتیجه به توابع تبدیل ارسال می شود و این توابع آن را به عنوان یک Pop در view خود ذخیره می کنند. بعد از انجام این مرحله دوباره نتیجه توسط جاوا اسکریپت به نیتیو انتقال داده می شود و view نیز در حین فراخوانی setNativeProps به روز رسانی می شود. در نهایت نیز نتیجه به IOS یا اندروید فرستاده می شود و UI سیستم عامل نیز به روز رسانی می شود.

 انیمیشن های ری اکت نیتیو


پیاده سازی انیمیشن های ری اکت نیتیو با استفاده از Animated API و مدیریت کننده نیتیو

از زمان آغاز کار انیمیشن های Animated API ری اکت نیتیو یک مدیریت کننده جاوا اسکریپت برای اجرای فریم مورد استفاده قرار گرفت، اما از آنجایی که به صورت مستقیم با منطق برنامه همراه بود بر روی thread جاوا اسکریپت تاثیر منفی می گذاشت و سرعت آن را کم می کرد. برای دستور دادن به frame drops آخرین نسخه از درایور یا مدیریت کننده به صورت کاملا نیتیو ساخته شد و در حال حاضر با اجرای انیمیشن های ری اکت نیتیو به صورت فریم به فریم در نیتیو کاملا سازگار می باشد.

مدیریت کننده نیتیو هنگامی که در کنار Animated API مورد استفاده قرار می گیرد به ماژول animated نیتیو اجازه می دهد که view ها را به صورت مستقیم و بدون نیاز به محاسبه مقدار آن در جاوا اسکریپت به روز رسانی کند. برای استفاده از مدیریت کننده نیتیو شما باید مقدار ویژگی useNativeDrive در تنظیمات انیمیشن های ری اکت نیتیو را برابر true قرار دهید:

useNativeDriver: true

 انیمیشن های ری اکت نیتیو


استفاده از PanResponder برای مدیریت کردن حرکت ها در ری اکت نیتیو

Animated API ری اکت نیتیو زمانی که شما انیمیشن های ری اکت نیتیو را پیاده سازی می کنید می تواند کارهای زیادی را برای شما انجام دهد، با این حال آن زمانی که قصد دارد تا حرکت ها را در انیمیشن های ری اکت نیتیو پیاده سازی کند دارای یک محدودیت کلیدی می باشد که این محدودیت این است که نمی تواند نسبت به حرکت هایی که فراتر از اسکرول کردن هستند پاسخ مناسبی دهد.

در حالی که شما می توانید کارهای زیادی را با استفاده از یک کامپوننت ساده ScrollView انجام دهید، احتمالا شما هم با این موضوع موافق هستید که موبایل بدون حرکت و انیمیشن ناقص است، که منظور از این حرکات نیز در واقع همان اقداماتی هستند که کاربران انجام می دهند، مانند اسکرول کردن و ... .

در ری اکت نیتیو حرکات می توانند با استفاده از PanResponder که توسط Animated API فراهم شده است مدیریت شوند. PanResponder در واقع لمس های مختلف صورت گرفته را به یک حرکت خاص تبدیل می کند، PanResponder یک لمس واحد را ایجاد می کند که در مقابل لمس های مختلف واکنش گراست. به صورت پیش فرض PanResponder شامل یک مدیریت کننده InteractionManager می باشد که رویدادهایی که در thread مربوط به جاوا اسکریپت در حال اجرا هستند را مسدود می کند.

 انیمیشن های ری اکت نیتیو


بهبود زمان به روز رسانی برای انتقال های کند navigation

در انیمیشن های ری اکت نیتیو که از یک اسکریپت به اسکریپت دیگر در برنامه منتقل می شوند معمولا از کامپوننت های navigation استفاده می شود، کامپوننت های Navigation مانند React Navigation به صورت عمومی برای انتقال های navigation استفاده می شود. در React Native انتقال ها معمولا در thread مربوط به جاوا اسکریپت رخ می دهد که می تواند در سیستم عامل باعث کندی شود. انتقال های navigation کند زمانی رخ می دهد که ری اکت نیتیو در زمان اجرای انیمیشن های ری اکت نیتیو در بک اند سعی می کند تا یک صفحه جدید را رندر کند. برای جلوگیری از چنین شرایطی InteractionManager بعد از آنکه یکی از انیمیشن های ری اکت نیتیو در thread مربوط به جاوا اسکریپت اجرا شد اجازه اجرای طولانی یک پروسه را می دهد.

 انیمیشن های ری اکت نیتیو


انیمیشن های ری اکت نیتیو در layout ( بخش اول)

LayoutAnimation در واقع یک API ساده است که به صورت خودکار View را حرکت می دهد تا زمانی که layout بعدی ظاهر می شود به پوزیشن مد نظر بعدی برسد. این API  بر روی thread مربوط به UI کار می کند که همین موضوع باعث عملکرد بهتر آن می شود. انیمیشن های ری اکت نیتیو با استفاده از Layout Animation تنظیم می شوند زمانی که فراخوانی می شوند بر روی تمامی کامپوننت ها اجرا می شوند، درست برخلاف سایر انیمیشن های ری اکت نیتیو که با روش های دیگر تنظیم می شوند که برای حرکت داده شدن باید مقدار Animated آنها تغییر پیدا کند. LayoutAnimation سازگار است که بتواند هر چیزی که در ادامه رندر خواهد شد را حرکت دهد، بنابراین شما باید قبل از فراخوانی setState آن را فراخوانی کنید.

 انیمیشن های ری اکت نیتیو


انیمیشن های ری اکت نیتیو در layout ( بخش دوم)

layout animation را باید قبل از فراخوانی setState تنظیم کنید تا مطمئن شوید انیمیشن های ری اکت نیتیو به خوبی اجرا در thread مربوط به نیتیو به خوبی اجرا می شوند. روش دیگر استفاده از Layout Animation این است که آن را درون کامپوننت Will Receive Props فراخوانی کنید. فراخوانی ساده Layout Animation.configure Next به همراه ارسال پارامترهای مناسب برای تنظیمات مربوط به انیمیشن های ری اکت نیتیو در کد زیر نشان داده شده است:

Layout Animation.configure Next(animation Configuration, callback Completion Method);

this.set State({ state To Change: new State Value });

LayoutAnimation تنها دو ویژگی را پشتیبانی می کند: تاری و مقیاس پذیری.

Layout Animation در واقع view ها را با استفاده از کلید یکتای آنها تشخیص می دهد و پوزیشن مورد انتظار آنها را محاسبه می کند. علاوه بر این Layout Animation تغییرات فریم را نیز مانند انیمیشن های ری اکت نیتیو نشان می دهد. انیمیشن های ری اکت نیتیو که با استفاده از Layout Animation پیاده سازی شده اند به صورت نیتیو ظاهر می شوند که از دیدگاه عملکردی بسیار خوب است.

 انیمیشن های ری اکت نیتیو


سخن پایانی درباره این موضوع جذاب در ری اکت نیتیو

این مقاله فقط به صورت سطحی انیمیشن های ری اکت نیتیو را مورد بررسی قرار داده است، یک قانون کلی برای استفاده از ری اکت نیتیو این است که هر زمان که ممکن بود از Animated API استفاده کنید، برای حرکت دادن از PanResponder نیز در کنار Animated API استفاده کنید. مدیریت کننده نیتیو را با استفاده از Leveraging در کنار Animated API توانمندتر کنید که می تواند در طول کار کردن با انیمیشن ها در ری اکت نیتیو کمک بسیار زیادی به شما کند. اگر هنوز هم سرعت عملکرد شما پایین است سعی کنید از Layout Animation استفاده کنید.

 انیمیشن های ری اکت نیتیو