كان استخدام الرسوم المتحركة على الويب محصورًا في JavaScript، ولكن مع انتقال العالم إلى الأجهزة الجوّالة، تم نقل الرسوم المتحركة إلى CSS بسبب البنية التعريفية والتحسينات التي تمكّنت المتصفّحات من إجرائها باستخدامها. بما أنّ هدفك هو تحقيق معدل 60 لقطة في الثانية على الأجهزة الجوّالة، من المنطقي عدم الخروج أبدًا من نطاق ما يمكن للمتصفّحات عرضه بكفاءة.
تظهر المزيد من الأدوات لجعل الصور المتحركة المستندة إلى JavaScript أكثر فعالية، ولكن الهدف هو توحيد الصور المتحركة التعريفية والإلزامية، حيث يستند قرار كيفية كتابة الصور المتحركة إلى التعليمات البرمجية الأكثر وضوحًا، وليس إلى ما يمكن تنفيذه في شكل معيّن وليس في شكل آخر.
يمكن أن تلبّي الصور المتحركة على الويب هذه الحاجة، وقد تم طرح الجزء الأول منها في الإصدار 36 من Chrome في شكل element.animate()
. تتيح لك هذه الدالة الجديدة إنشاء صورة متحركة باستخدام JavaScript فقط وتشغيلها بكفاءة مثل أي صورة متحركة أو انتقال في CSS (في الواقع، اعتبارًا من الإصدار 34 من Chrome، يستخدم محرك Web Animations نفسه جميع هذه الطرق).
تكون البنية بسيطة، ومن المفترض أن تكون أجزاؤها مألوفة لك إذا سبق لك كتابة انتقال أو حركة في CSS:
element.animate([
{cssProperty: value0},
{cssProperty: value1},
{cssProperty: value2},
//...
], {
duration: timeInMs,
iterations: iterationCount,
delay: delayValue
});
تتمثل الميزة الأكبر لهذه الوظيفة الجديدة في التخلص من الكثير من الإجراءات غير المُريحة التي كان علينا اتّخاذها سابقًا للحصول على صورة متحركة سلسة وخالية من الانقطاعات.
على سبيل المثال، في Santa Tracker العام الماضي، أردنا أن يسقط الثلج باستمرار، وقرّرنا إضافة حركة إليه باستخدام CSS حتى يمكن تنفيذ ذلك بكفاءة عالية.
ومع ذلك، أردنا اختيار موضع الثلج الأفقي بشكل ديناميكي استنادًا إلى الشاشة والأحداث الجارية في المشهد نفسه، وبالطبع لن يكون ارتفاع تساقط الثلج (ارتفاع نافذة متصفّح المستخدم) معروفًا حتى نبدأ التشغيل. وهذا يعني أنّنا اضطررنا إلى استخدام انتقالات CSS، لأنّ إنشاء حركة CSS في وقت التشغيل يصبح معقّدًا بسرعة (وتعني مئات أوراق الثلج مئات قواعد التصميم الجديدة).
لذلك اتّبعنا النهج التالي الذي من المفترض أن يكون مألوفًا لك:
snowFlake.style.transform = 'translate(' + snowLeft + 'px, -100%)';
// wait a frame
snowFlake.offsetWidth;
snowFlake.style.transitionProperty = 'transform';
snowFlake.style.transitionDuration = '1500ms';
snowFlake.style.transform = 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)';
يكمن المفتاح في تعليق "الانتظار لمدة إطار". لبدء انتقال بنجاح، يجب أن يُعلم المتصفّح أنّ العنصر في موضع البداية. هناك بضعة طرق لإجراء ذلك. ومن أكثر الطرق شيوعًا القراءة من إحدى خصائص العنصر التي تجبر المتصفّح على احتساب التنسيق، ما يضمن معرفته بأنّ للعنصر موضع بدء قبل الانتقال إلى موضع النهاية. يتيح لك استخدام هذه الطريقة تهنئة نفسك على معرفتك الفائقة بتفاصيل المتصفح الداخلية مع الشعور بالضيق مع كل ضغطة مفتاح.
في المقابل، كان طلب element.animate()
المكالمة المكافئ واضحًا تمامًا، حيث وضّح ما هو مطلوب بالضبط:
snowFlake.animate([
{transform: 'translate(' + snowLeft + 'px, -100%)'},
{transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);
هناك العديد من الخيارات الأخرى. تمامًا مثل نظيراتها في CSS، يمكن تأخير "الرسومات المتحركة على الويب" وتكرار عرضها:
snowFlake.animate([
{transform: 'translate(' + snowLeft + 'px, -100%)'},
{transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], {
duration: 1500,
iterations: 10,
delay: 300
});
AnimationPlayer
تعرِض element.animate()
في الواقع عنصر AnimationPlayer، الذي سيزداد أهميته مع إطلاق المزيد من مواصفات Web Animations. ستتضمّن كلّ من الصور المتحركة التي تم إنشاؤها باستخدام JavaScript وCSS عناصر AnimationPlayer مرتبطة بها، ما يتيح دمجها بسلاسة بطرق مفيدة ومثيرة للاهتمام.
في الوقت الحالي، لا يتضمّن AnimationPlayer سوى وظيفتَين، وكلتاهما مفيدتان جدًا. يمكنك إلغاء صورة متحركة في أي وقت باستخدام AnimationPlayer.cancel()
:
var player = snowFlake.animate([
{transform: 'translate(' + snowLeft + 'px, -100%)'},
{transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);
// less than 1500ms later...changed my mind
player.cancel();
ولإراحة كل من حاول إنشاء نظام صور متحركة حول "صور CSS المتحركة" أو "عمليات النقل" في السابق، تُطلق "صور الويب المتحركة" دائمًا حدثًا عند الانتهاء:
var player = snowFlake.animate([
{transform: 'translate(' + snowLeft + 'px, -100%)'},
{transform: 'translate(' + snowLeft + 'px, ' + window.innerHeight + 'px)'}
], 1500);
player.onfinish = function(e) {
console.log('per aspera ad terra!');
}
جرّبه الآن
سيتم طرح كل هذه الميزات في الإصدار 36 من Chrome، وسيتم طرح الإصدار التجريبي منها اليوم. إذا أردت تجربته، جرِّب استخدام التنفيذ الأصلي في Chrome 36. ومع ذلك، هناك Web Animations polyfill، الذي يقدّم جزءًا أكبر بكثير من مواصفات Web Animations الكاملة لأي من المتصفحات الحديثة التي لا تبطل صلاحيتها.
يتوفّر لك عرض توضيحي لتأثير الثلج يمكنك تجربته باستخدام كلّ من الإصدار الأصلي من element.animate()
وpolyfill.
يسرنا أن نعرف رأيك
في الواقع، هذه هي معاينة لما سيأتي، ويتم إصدارها خصيصًا للحصول على ملاحظات المطوّرين على الفور. لا نعلم بعد ما إذا كنا قد عالجنا كل حالات الاستخدام أو أزلنا كل المشاكل في واجهات برمجة التطبيقات الحالية للرسوم المتحركة. إنّ الطريقة الوحيدة لمعرفة ما إذا كانت هذه الميزة مناسبة أم لا هي من خلال تجربة المطوّرين لها وإعلامنا بآرائهم.
إنّ التعليقات على هذه المشاركة قيّمة بالتأكيد، ويمكن توجيه التعليقات على المعيار نفسه إلى مجموعتَي عمل CSS وSVG من خلال قائمة البريد الإلكتروني public-fx.
تعديل، تشرين الأول (أكتوبر) 2014: يتيح الإصدار 39 من Chrome استخدام عدة طرق إضافية متعلّقة بالتحكم في التشغيل، مثل play()
وpause()
وreverse()
. وتتيح أيضًا الانتقال إلى نقطة معيّنة في المخطط الزمني للحركة من خلال السمة currentTime
. يمكنك الاطّلاع على هذه الوظيفة في هذا العرض التوضيحي الجديد.
نشكر "أدي عثماني" و"ماكس هاينريتز" على مساعدتهما في إنشاء هذا المنشور.