التحكّم في تشغيل الصور المتحركة على الويب في Chrome 39

في وقت سابق من هذا العام، طرح Chrome 36 أسلوب element.animate كجزء من مواصفات Web Animations الأوسع نطاقًا. يتيح ذلك إنشاء صور متحركة فعّالة وتلقائية مكتوبة بشكل إلزامي، ما يمنح المطوّرين خيار إنشاء صورهم المتحركة وعمليات النقل باستخدام النهج الأنسب لهم.

في ما يلي كيفية إضافة حركة إلى سحابة على الشاشة، مع إضافة استدعاء عند الانتهاء:

var player = cloud.animate([
    {transform: 'translateX(' + start + 'px)'},
    {transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
    console.info('Cloud moved across the screen!');
    startRaining(cloud);
};

هذه الطريقة سهلة للغاية، وتستحق الاهتمام بها كجزء من صندوق الأدوات الخاص بك عند إنشاء رسوم متحركة أو انتقالات لازمة. ومع ذلك، في الإصدار 39 من Chrome، تمت إضافة ميزات التحكّم في التشغيل إلى عنصر AnimationPlayer الذي يعرضه element.animate. في السابق، بعد إنشاء صورة متحركة، لم يكن بإمكانك سوى الاتصال بـ "cancel()" أو الاستماع إلى حدث الانتهاء.

توفّر إضافات التشغيل هذه إمكانيات جديدة لتأثيرات Web Animations، إذ تحوّلها إلى أداة للأغراض العامة بدلاً من أن تكون أداة لإنشاء الانتقالات، أي: الرسومات المتحركة "الثابتة" أو المحدّدة مسبقًا

الإيقاف المؤقت أو الترجيع أو تغيير معدل التشغيل

لنبدأ بتعديل المثال أعلاه لإيقاف الصورة المتحركة مؤقتًا في حال النقر على السحابة:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

يمكنك أيضًا تعديل السمة playbackRate:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

يمكنك أيضًا استدعاء طريقة reverse()، والتي تكون عادةً مساوية لعكس playbackRate الحالية (الضرب في -1). في المقابل، هناك حالتان خاصتان:

  • إذا كان التغيير الذي تسبّبت به طريقة reverse() سيؤدي إلى إنهاء الحركة المتحركة الجارية بشكل فعّال، سيتم أيضًا عكس currentTime.على سبيل المثال، إذا تم عكس حركة متحركة جديدة تمامًا، سيتم تشغيل الحركة المتحركة بأكملها بشكل عكسي.

  • إذا تم إيقاف المشغّل مؤقتًا، سيبدأ تشغيل الصورة المتحركة.

التقديم والترجيع في المشغّل

يسمح AnimationPlayer الآن بتعديل currentTime أثناء تشغيل صورة متحركة. ستزداد هذه القيمة عادةً بمرور الوقت (أو تنخفض إذا كانت playbackRate سالبة). قد يسمح هذا بالتحكم في موضع الرسوم المتحركة خارجيًا، ربما من خلال تفاعل المستخدم. يُشار إلى ذلك عادةً باسم المحو.

على سبيل المثال، إذا كانت صفحة HTML تمثل السماء، وتريد إيماءة السحب لتغيير موضع السحابة قيد التشغيل حاليًا، فيمكنك إضافة بعض المعالِجات إلى المستند:

var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
    startEvent = event;
    startEventTime = players.currentTime;
    player.pause();
});
document.addEventListener('touchmove', function(event) {
    if (!startEvent) return;
    var delta = startEvent.touches[0].screenX -
        event.changedTouches[0].screenX;
    player.currentTime = startEventTime + delta;
});

أثناء السحب فوق المستند، سيتم تغيير currentTime لتعكس المسافة من الحدث الأصلي. يمكنك أيضًا استئناف تشغيل الصورة المتحرّكة عند انتهاء الإيماءة:

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

ويمكن أيضًا دمج هذا السلوك مع سلوك العكس، استنادًا إلى المكان الذي تم رفع الماوس منه من الصفحة (العرض التقديمي المجمّع).

بدلاً من تقديم AnimationPlayer استجابةً لتفاعل مستخدم، يمكن أيضًا استخدام currentTime لعرض مستوى التقدّم أو الحالة: على سبيل المثال، لعرض حالة عملية تنزيل.

تكمن الأداة هنا في أنّ AnimationPlayer تسمح بضبط قيمة وجعل التنفيذ الأصلي الأساسي يتولى عرض مستوى التقدّم. في حالة التنزيل، يمكن ضبط مدة الصورة المتحركة على إجمالي حجم التنزيل، وضبط currentTime على الحجم الذي تم تنزيله حاليًا (الإصدار التجريبي).

انتقالات واجهة المستخدم والإيماءات

لطالما كانت المنصات المتوافقة مع الأجهزة الجوّالة هي المكان الذي تُستخدم فيه الإيماءات الشائعة، مثل السحب والانزلاق والرمي وما إلى ذلك. تميل هذه الإيماءات إلى أن تتضمّن موضوعًا شائعًا: مكوّن واجهة مستخدم قابل للسحب، مثل "السحب لإعادة التحميل" في طريقة العرض بتنسيق قائمة أو شريط جانبي يتم إنشاؤه من الجانب الأيسر من الشاشة.

باستخدام ميزة "رسومات الويب المتحركة"، من السهل جدًا تكرار تأثير مشابه هنا على الويب، سواء على الكمبيوتر المكتبي أو على الأجهزة الجوّالة. على سبيل المثال، عند اكتمال إيماءة للتحكّم في currentTime:

var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);

var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
    var srcTime = player.currentTime;
    var dstTime = findNearest(setpoints, srcTime);
    var driftDuration = dstTime - srcTime;

    if (!driftDuration) {
    runCallback(dstTime);
    return;
    }

    var driftPlayer = target.animate(steps, {
    duration: duration,
    iterationStart: Math.min(srcTime, dstTime) / duration,
    iterations: Math.abs(driftDuration) / duration,
    playbackRate: Math.sign(driftDuration)
    });
    driftPlayer.onfinish = function() { runCallback(dstTime); };
    player.currentTime = dstTime;
});

ويؤدي هذا إلى إنشاء رسم متحرك إضافي يؤدي "انحراف". يتم تشغيل هذا الإجراء بين نقطة اكتمال اللفتة ونقطة الاستهداف المعروفة والناجحة.

ويعمل هذا الإجراء لأنّ الصور المتحركة لها الأولوية استنادًا إلى ترتيب إنشائها: في هذه الحالة، سيكون لعنصر driftPlayer الأولوية على لاعب. عند اكتمال driftPlayer، ستختفي هذه الميزة وتأثيراتها. ومع ذلك، سيتطابق الوقت النهائي مع currentTime الخاص بالوسيط، وبالتالي سيظل واجهة المستخدم متسقة.

أخيرًا، إذا كنت من محبّي القطط الصغيرة، يمكنك الاطّلاع على تطبيق ويب تجريبي يعرض هذه الإيماءات. وهو متوافق مع الأجهزة الجوّالة ويستخدم polyfill للتوافق مع الإصدارات القديمة، لذا جرِّب تحميله على جهازك الجوّال.

انتقل وitem.animate

إنّ الطريقة element.animate مذهلة في الوقت الحالي، سواء كنت تستخدمها لإنشاء صور متحركة بسيطة، أم تستفيد منها AnimationPlayer التي تم عرضها بطرق أخرى.

وتتم أيضًا إتاحة هاتَين الميزتَين بالكامل في المتصفّحات الحديثة الأخرى عبر رمز polyfill خفيف. ويعمل هذا العنصر البديل أيضًا على رصد الميزات، لذا كلما نفّذ مورّدو المتصفّحات المواصفات، ستتحسن هذه الميزة بشكلٍ أكبر بمرور الوقت.

وسيستمر أيضًا تطوير مواصفات Web Animations. إذا كنت مهتمًا بالتجربة مع الميزات القادمة، يمكنك أيضًا استخدامها الآن في مجموعة polyfill أكثر تفصيلاً: web-animations-next.