การควบคุมการเล่นภาพเคลื่อนไหวในเว็บใน Chrome 39

เมื่อต้นปีนี้ Chrome 36 ได้เปิดตัวเมธอด source.animate เป็นส่วนหนึ่งของข้อกำหนดของ Web Animations ที่กว้างขึ้น ซึ่งช่วยให้เขียนภาพเคลื่อนไหวเนทีฟที่มีประสิทธิภาพได้ ทำให้นักพัฒนาซอฟต์แวร์มีตัวเลือกในการสร้างภาพเคลื่อนไหวและการเปลี่ยนภาพด้วยวิธีการที่เหมาะสมที่สุด

เพื่อเป็นการทบทวนความจำสั้นๆ ต่อไปนี้คือวิธีสร้างภาพเคลื่อนไหวของระบบคลาวด์บนหน้าจอ โดยมี Callback เมื่อดำเนินการเสร็จสิ้น

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);
};

วิธีนี้เพียงอย่างเดียวนั้นง่ายมากและควรพิจารณาเป็นส่วนหนึ่งของกล่องเครื่องมือเมื่อคุณสร้างภาพเคลื่อนไหวหรือการเปลี่ยนฉากในจุดที่จำเป็น อย่างไรก็ตาม ใน Chrome 39 มีการเพิ่มฟีเจอร์การควบคุมการเล่นลงในออบเจ็กต์ AnimationPlayer ที่ element.animate แสดงผล ก่อนหน้านี้ เมื่อสร้างภาพเคลื่อนไหวแล้ว คุณจะเรียก cancel() หรือฟังเหตุการณ์จบได้เท่านั้น

การเล่นเพิ่มเติมเหล่านี้จะช่วยเปิดความเป็นไปได้ของสิ่งที่ Web Animations ทำได้ โดยเปลี่ยนภาพเคลื่อนไหวให้เป็นเครื่องมือทั่วไปแทนที่จะกำหนดการเปลี่ยนฉาก เช่น "แก้ไขแล้ว" หรือภาพเคลื่อนไหวที่กำหนดไว้ล่วงหน้า

หยุดชั่วคราว กรอกลับ หรือเปลี่ยนอัตราการเล่น

เริ่มด้วยการอัปเดตตัวอย่างด้านบนเพื่อหยุดภาพเคลื่อนไหวชั่วคราวหากมีการคลิกระบบคลาวด์

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

คุณยังแก้ไขพร็อพเพอร์ตี้ playbackRate ได้ด้วย โดยทำดังนี้

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

คุณยังเรียกเมธอด reverse() ได้ด้วย ซึ่งปกติจะเทียบเท่ากับการกลับ playbackRate ปัจจุบัน (คูณด้วย -1) อย่างไรก็ตาม มีกรณีพิเศษ 2 กรณีดังนี้

  • หากการเปลี่ยนแปลงที่เกิดจากเมธอด 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();
});

ซึ่งอาจรวมกับพฤติกรรมการย้อนกลับก็ได้ โดยขึ้นอยู่กับตำแหน่งที่มีการยกเมาส์ออกจากหน้า (การสาธิตแบบรวม)

คุณใช้ currentTime แทนการเลื่อน AnimationPlayer เพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ได้ด้วย เพื่อใช้แสดงความคืบหน้าหรือสถานะ เช่น เพื่อแสดงสถานะของการดาวน์โหลด

ยูทิลิตีในที่นี้คือ AnimationPlayer จะอนุญาตให้ตั้งค่าได้ และให้การใช้งานแบบเนทีฟที่พื้นฐานจัดการแสดงความคืบหน้าด้วย ในกรณีดาวน์โหลด คุณอาจตั้งค่าระยะเวลาของภาพเคลื่อนไหวเป็นขนาดการดาวน์โหลดทั้งหมด และตั้งค่า currentTime เป็นขนาดที่ดาวน์โหลดในปัจจุบัน (การสาธิต)

การเปลี่ยน UI และท่าทางสัมผัส

แพลตฟอร์มมือถือเป็นสัญลักษณ์ของท่าทางสัมผัสที่พบได้ทั่วไปมาอย่างยาวนาน ไม่ว่าจะเป็นการลาก การเลื่อน การสะบัด และอื่นๆ ท่าทางสัมผัสเหล่านี้มักจะมีธีมที่เหมือนกัน ซึ่งก็คือคอมโพเนนต์ UI ที่ลากได้ เช่น "ดึงเพื่อรีเฟรช" ของมุมมองรายการ หรือแถบด้านข้างที่สร้างขึ้นจากด้านซ้ายของหน้าจอ

เมื่อใช้ภาพเคลื่อนไหวบนเว็บ คุณจะจำลองเอฟเฟกต์ที่คล้ายกันนี้ในเว็บต่างๆ ทั้งในเดสก์ท็อปหรืออุปกรณ์เคลื่อนที่ได้ง่ายมาก ตัวอย่างเช่น เมื่อท่าทางสัมผัสการควบคุม 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 คลิปและเอฟเฟกต์จะหายไป แต่เวลาสุดท้ายจะตรงกับเวลาปัจจุบันของผู้เล่นที่เกี่ยวข้อง ดังนั้น UI ของคุณจะมีความสม่ำเสมอ

สุดท้าย หากคุณชอบลูกแมว เรามีเว็บแอปพลิเคชันสำหรับการสาธิตที่จะแสดงท่าทางสัมผัสเหล่านี้ แอปนี้เหมาะกับอุปกรณ์เคลื่อนที่และใช้ Polyfill เพื่อความเข้ากันได้แบบย้อนหลัง ดังนั้นลองโหลดในอุปกรณ์เคลื่อนที่ดูเลย

ออกไปและElement.animate

เมธอด element.animate ใช้งานได้ดีในขณะนี้ ไม่ว่าคุณจะใช้สำหรับภาพเคลื่อนไหวง่ายๆ หรือใช้ประโยชน์จาก AnimationPlayer ที่ส่งคืนมาในรูปแบบอื่นๆ

นอกจากนี้ เบราว์เซอร์สมัยใหม่อื่นๆ ยังรองรับฟีเจอร์ทั้ง 2 อย่างนี้อย่างเต็มรูปแบบ ผ่าน Polyfill ขนาดเล็กด้วย นอกจากนี้ Polyfill ยังตรวจหาฟีเจอร์ด้วย ดังนั้นเมื่อผู้ให้บริการเบราว์เซอร์ใช้ข้อกำหนด ฟีเจอร์นี้จะทำงานเร็วขึ้นและดีขึ้นเรื่อยๆ

นอกจากนี้ ข้อกำหนดของภาพเคลื่อนไหวบนเว็บยังมีการพัฒนาต่อไป หากสนใจลองใช้งานฟีเจอร์ที่กำลังจะเปิดตัว ตอนนี้มีให้บริการแล้วใน polyfill ที่ละเอียดยิ่งขึ้น: web-animations-next