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

في وقت سابق من هذا العام، طرح Chrome 36 طريقة item.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 على الحجم الذي تم تنزيله حاليًا (عرض توضيحي).

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

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

وباستخدام Web Animations، يكون من السهل جدًا تكرار تأثير مماثل على الويب وعلى أجهزة الكمبيوتر المكتبي أو الأجهزة الجوّالة. على سبيل المثال، عند اكتمال إيماءة تتحكّم في 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، ستختفي هي وتأثيراتها. ومع ذلك، سيتطابق الوقت الأخير مع الوقت الحالي للّاعب الأساسي، وبالتالي تبقى واجهة المستخدم متّسقة.

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

الانتقال للأمام وElement.animate

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

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

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