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

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

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

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 Animation ทำงานได้หลากหลายมากขึ้น ซึ่งทำให้ Web Animation เป็นเครื่องมืออเนกประสงค์แทนที่จะกำหนดเฉพาะการเปลี่ยนรูปแบบ เช่น ภาพเคลื่อนไหว "คงที่" หรือที่กําหนดไว้ล่วงหน้า

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

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

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

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

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

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

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

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

ไปต่อและ element.animate

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

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

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