به طور عادی ایجاد انیمیشن در صفحات وب بر عهده CSS است اما در برخی موارد برای ایجاد انیمیشن نمیتوان تنها به آن اتکا کرد و باید به سراغ JavaScript بریم. تا همین چند سال پیش برای ایجاد یک انیمیشن به وسیله جاوا اسکریپ تنها دومتد setInterval() و setTimeout() وجود داشت.
setTimeout() یک تابع یا عبارت را به عنوان آرگومان اول و یک مقداری عددی را به عنوان آرگومان دوم دریاف میکند و آن تا بع یا عبارت را بعد از مقدار زمانی که به صورت عدد در آرگومان دوم مشخص کردیم بر حسب میلی ثانیه اجرای میکند. به عنوان کثال قطعه کد زیر 3 ثانیه پس از لود شدن صفحه و اجرای اولین دستور جاوا اسکریپ، پیام ” 3 ثانیه گذشت ” را نمایش می دهد.
window.setTimeout( () = alert("3 تانیه گذشت") , 3000);
متد بعدی که از آن استفاده زیادی می شود تابع setTimeout() است که ساختاری مشابه متد قبلی دارد با این تفاوت که از آن برای تکرار یک قطعه کد در بازه زمانی مشخص استفاده می شود.
window.setInterval() = alert("1 تانیه گذشت") , 1000);
برای مثال در قطعه کد بالا هر یک ثانیه پیام “1 ثانیه گذشت” نمایش داده می شود.
اما این متدها دو مشکل اساسی دارند که به ویژه در انیمیشن های پیچیده، میتواند کیفیت انیمیشن را کاهش دهد.
۱- این متدهای هیچ تضمینی در مورد دقت زمانبندی نمیدهند. مثلاً عملی که باید بعد از ۵۰۰ میلیثانیه انجام شود، ممکن است بعد از 550 میلیثانیه و یا حتی بعد از 1500 میلیثانیه انجام شود. یعنی بسته به توان سخت افزاری سیستم و مشغله مرورگر و سیستم عامل، همیشه یک تاخیر در اجرای عمل مورد نظر وجود دارد. هرچند میزان این تاخیر معمولاً بسیار کوچک است، اما وجود این تاخیر و متغیر بودن میزان تاخیر، میتواند اجرای انیمیشن را دچار اختلال کرده و کیفیت آن را کاهش دهد.
۲- محتوای گرافیکی صفحه نمایش نیز مانند یک انیمیشن است. زیرا به صورت متوالی و در بازههای زمانی کوچک در حال به روز رسانی است. در واقع در هر سیستم عاملی، رویدادی به نام paint وجود دارد که در هر ثانیه به تعداد مشخصی رخ میدهد. و با هر بار وقوع این رویداد، یک بار محتوای صفحه نمایش مجدداً ترسیم میشود. تعداد دفعات وقوع این رویداد در سیستمهای کامپیوتری مختلف، یکسان نیست. اما در بیشتر سیستمهای کامپیوتری امروزی این رویداد ۶۰ بار در هر ثانیه رخ میدهد. لازم به ذکر است که رویداد paint برای تمام پنجرههای موجود در صفحه نمایش نیز رخ میدهد که مرورگر نیز یکی از همین پنجرهها است. برای داشتن یک انیمیشن یکنواخت و با کیفیت، باید فریمهای انیمیشن را دقیقاً همزمان با رویداد paint ترسیم کرد. اما متدهای setInterval و setTimeout این همزمانی را تضمین نمیکنند. به همین دلیل انیمیشنهای ایجاد شده با این متدها معمولاً کیفیت بالایی ندارند.
تا اینکه چندی پیش متد requestAnimationFrame برای حل دو مشکل فوق به وجود آمد و خوشبختانه در تمام مرورگرهای امروزی پشتیبانی میشود. این متد مشکل همزمانی با رویداد paint را به طور کامل برطرف میکند. و مشکل تاخیر در زمانبندی را نیز تا حد زیادی برطرف میکند. البته هنوز هم در شرایطی که بار پردازشی CPU خیلی زیاد باشد کمی تاخیر ایجاد خواهد شد.
متد requestAnimationFrame یک آرگومان ورودی دریافت میکند که یک تابع Callback است که در زمان ترسیم فریم بعدی باید فراخوانی شود. این متد از مرورگر درخواست میکند تا تابع Callback را دقیقاً قبل از ترسیم بعدی (repaint) مرورگر اجرا کند. به همین دلیل زمان اجرای تابع Callback دقیقاً با زمان ترسیم مرورگر یا همان رویداد paint همگام میشود. توجه کنید که با استفاده از این متد، بر خلاف متد setInterval نیازی به تعیین زمان نیست. زیرا زمان اجرای تابع Callback با رویداد paint همگام شده و زمان وقوع این رویداد نیز توسط سیستم عامل تعیین میشود.
کد زیر مثال ساده ای از کاربرد requestAnimationFrame را نشان میدهد.
function repeatOften() {
// Do whatever
requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);
برای اجرا انیمیش یک بار تابع آن را فراخوانی میکنیم و در انتهای تابع مجددا خود تابع را فراخوانی میکنیم.
شروع و توقف انیمیشن requestAnimationFrame :
متد requestAnimationFrame مانند متدههای setInterVal و setTimeOut یک شناسه بر می گرداند که با کمک آن میتوان انیمیشن را کنترل کرد.
در قطعه کد زیر با استفاده از متد cancelAnimationFrame انیمیشنی که ایجاد کردیم را می توان متوقف کرد.
let animation
function repeatOften() {
//Do any things
animation = requestAnimationFrame(callback);
}
animation = requestAnimationFrame(callback);
cancelAnimationFrame(animation);
در کد فوق با استفاده از متد requestAnimationFrame یک انیمیشن ایجاد کردیم و شناسه آن را در متغیر animation ذخیره کردیم و با استفاده از متد cancelAnimationFrame و ارسال شناسه انیمیشن به عنوان آرگومان آن را متوقف میکنیم.
مثال:
See the Pen
Manaid-Simple requestAnimationFrame sample by Manaid (@manaid)
on CodePen.
از وب سایت …Can I use میتونید پشتیانی مرورگرهای مختلف از این متد رو بررسی کنید.