Hamid Bluri
Hamid Bluri
خواندن ۵ دقیقه·۳ سال پیش

ساخت کتابخونه انیمیشن خودم

این پست، بیشتر شبیه ی پیشنویس هست تا ی مقاله ای که روی جزئیات تمرکز کرده باشه :-)


چند وقت پیش با دیدن این چندتا لینک زیر، جو منو گرفته بود و گفتم میرم ی کتابخونه مینویسم که استفاده اش از اینایی که هست راحت تر باشه و از همه مهم تر "ماژولار" ( یعنی بشه مثلا ی component ساخت و با ی سری API ، بشه جاهای مختلف ازش استفاده کرد و خلاصه بشه به خود کتابخونه هم قسمت جدید اضافه کرد ) باشه.


اینا چیز هایی هست که ازش انگیزه گرفتم:

  1. انیمیشن توضیح raft
  2. سایت introbrand که لوگوی خودت رو آپلود میکنی و میزاره روی انیمیشن های از پیش ساخته شدس
  3. سایت render forest که کار سایت بالا رو میکنه به صورت حرفه ای تر و البته خفن تر
  4. کتابخونه انیمیشن برای پایتون manim
  5. کتابخونه انیمیشن برای نیم nanim
  6. کتابخونه svg برای نیم که قابلیت انیمیشن هم داره
  7. و همه مقاله ها و کتاب هایی که بجای اینکه ی gif یا عکس ساده بیارن به توی 2 دقیقه مطلب رو بگیری، 5 صفحه نوشتن که خوندنش 20 دقیقه طول میکشه.


خب من یکم با Figma کار کرده بودم و تقریبا میشه گفت با فرمت SVG رابطه خوبی داشتم. به علاوه با کتابخونه Konva برای ی پروژه کار کرده بودم و خب در کنارش دوتا پروژه کوچیک توی گیتهاب هم باهاش زدم.

  1. برنامه نشونه گذاری و ذخیره سازی پیکسل های توی تصویر :: لینک
  2. برنامه رسم چند تا شکل ساده و ی شکل پیچیده ( اون فلش عه ) :: لینک
  3. و حتی برای انجمن مون ی ویدئو intro درست کرده بودم. ( SVG و کد جاوااسکریپت )
https://www.aparat.com/v/4mLA9


توی پروژه دومی نیاز بود که در مورد path ها توی SVG یادبگیرم - جالبه شما هم ی نگاهی بندازید

برای شروع، نیاز داشتم که در مورد SVG بیشتر یادبگیرم ( استاندارد ها و...) که این سری آموزش خیلی بهم کمک کرد.


نحوه کارکرد برنامه ساده بود. ( اسم کتابخونه ام رو گذاشتم motionly )

ساخته شده با draw.io
ساخته شده با draw.io


برنامه من از روی انیمیشن هایی که براش تعریف شده، فایل SVG رو دستکاری میکنه و هر فریم از انیمیشن رو توی فایل های متفاوت با فرمت SVG ذخیره میکنه. بعد با نرم افزار imageMagic میاد اون عکس هارو به GIF تبدیل میکنه. ( در واقع برنامه من روی شونه های imageMagic ایساده ? - البته چند تا از کتابخونه هایی که بالا معرفی کردم هم همین کار رو کردن)


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

https://www.aparat.com/v/n0jqu

خب محتویات صفحه ( غیر از اون مربع هایی که توش عدده ) رو اینطوری تعریف کردم.

خب استایلش خیلی شبیه به همون محتویات فایل SVG هست که به صورت XML نوشته شده ولی با syntax زبان Nim

ی سری نکته:

  1. با as میشه برای اون المان اسم تعریف کرد و بعدا توی انیمیشن با همین اسم استفاده اش کرد.
  2. با embed میشه ی فایل SVG خارجی رو به اصطلاح include کرد ( به اون قسمت اضافه کرد )
  3. میشه المان دلخواه تعریف کرد مثل cursor ( البته در واقع ی المان path هست که ی سری attribute از پیش تعریف شده داره )
  4. اون مربع ها با عدد ها توی گروه @list قرار میگیرن

این هم تعریف timeline ( نوار زمانی ):

چند تا نکته در مورد timeline:

  1. ا flow ها تابع هایی هستن که زیرمجموعه defTimeline قرار میگیرن و غیر از ورودی های خودشون، دو تا ورودی دیگه میگیرن که با meta-programming بهشون اضافه میشه ولی شما نمینویسید
  2. بلاک before هم قبل از اجرای انیمیشن اجرا میشه
  3. ی سری بلاک دیگه مثل after و frame و at و ... هم وجود داره که توی این مثال استفاده نمیشه


این از بلاک before:

  1. اول که میام مکان المان های @key و @title رو توی صفحه تنظیم میکنم
  2. بعد میام چند تا از اون flow هایی که بالاتر تعریف کردم رو صدا میزنم ( برای تنظیم کردن ی سری دیگه از المان ها توی صفحه ) - نکته ای که وجود داره اینه که چون گفتم دو تا ورودی دیگه غیر از ورودی های خودشون میگیرن، برای این که اون دوتا ورودی اضافه رو ننویسم، اومدم ی ماکرو با اسم ! تعریف کردم که به طور خودکار اون دوتا ورودی اضافه رو به ورودی های اون تابعی که صدا زدم اضافه میکنه
  3. با تابع genAnimationActions که قبلا تعریف کردم، میام اون اتفاقاتی که توی انیمیشن قراره بیفته رو تولید میکنم و توی متغیر actions میریزم
  4. بعد با توجه به هر action ی سری انیمیشن هارو اعمال میکنم
  5. در آخر هم اون مقدار @key غیب میشه. در واقع هدفم از نشون دادن این خط آخر این بود که ببینید انیمیشن دادن چقدر راحته. المان رو به تابع fadeOut دادم و بعد با علامت ~> اومدم انیمیشن اش رو تعریف کردم. 3 تا ورودی بعد ~> به ترتیب این ها هستن ( زمان انیمیشن، تابع زمانی انیمیشن، و در آخر هم تاخیر شروع انیمیشن ).

اگر با انیمیشن های CSS کار کرده باشید، احتمالا با تابع های زمانی آشنا هستید.


نمونه تعریف شئ Transition:

نکاتی در مورد syntax زبان Nim:

  • ا proc میشه معادل تابع توی زبان های دیگه
  • ا {.nimcall.} یعنی تابعی که توی ماژول تعریف شده ( برعکس closure )
  • اون ستاره بعد اسم ها به معنی export هست

در مورد مفهوم تصویر بالا:

  • نوع داده ای Progress، یک عدد اعشاری بین 0 تا 1 هست
  • تعریف یک Transition به صورته که یک تاخیر ( delay ) داره و یک زمان کل ( totalTime )
  • دو تا تابع هم داره یکی easingFn که تابع زمانی هست و یک تابع UpdateFn که با توجه به پیشرفت زمانی، میاد اون فریم رو میسازه و تغیرات رو اعمال میکنه




همین! هنوز این کتابخونه رو public نکردم. فکر نمیکنم هیچوقت اینکارو انجام بدم. فکر نمیکنم زبان انیمیشن کد باشه. درسته که استفاده از کتابخونه های مثل این درست کردن انیمیشن های تکراری و با ی الگوی مشخص رو راحت میکنه، ولی من واسه همین انیمیشن ساده 5 ساعت وقت گذاشتم.


با وجود motion graphic ها و کتابخونه های انیمیشن دیگه، فکر نمیکنم کتابخونه من چیزی واسه ارائه داشته باشه. این کتابخونه هنوز خیلی از ویژگی هارو نداره مثل بدست آوردن اندازه متنی که توی المان text هست، یا بدست اوردن اندازه المان های path. و البته قعلا فقط چند تا انیمیشن مثل fade و حرکت داره.


درست کردن انیمیشن با کد از چیزی که فکرشو میکردم سخت تره، شاید زبان انیمیشن، کد نیست ...

برنامه نویسیانیمیشنکدprogramminganimation
life is what you choose it to be ...
شاید از این پست‌ها خوشتان بیاید