التحكّم في تشغيل الصور المتحركة على الويب في 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 للتوافق مع الإصدارات القديمة، لذا جرِّب تحميله على جهازك الجوّال.

يمكنك استخدام element.animate

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

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

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