การจัดระเบียบภาพเคลื่อนไหวด้วย Promise, การเพิ่มประสิทธิภาพด้วยภาพเคลื่อนไหวที่เปลี่ยนทดแทนได้, ภาพเคลื่อนไหวที่ราบรื่นขึ้นด้วยโหมดคอมโพสิต และอื่นๆ
เผยแพร่: 27 พฤษภาคม 2020
เมื่อใช้อย่างถูกต้อง ภาพเคลื่อนไหวจะช่วยปรับปรุงการรับรู้และความทรงจำของผู้ใช้เกี่ยวกับแบรนด์ แนะนําการดําเนินการของผู้ใช้ และช่วยให้ผู้ใช้ไปยังส่วนต่างๆ ของแอปพลิเคชันได้โดยให้บริบทในสภาพแวดล้อมดิจิทัล
Web Animations API เป็นเครื่องมือที่ช่วยให้นักพัฒนาซอฟต์แวร์เขียนภาพเคลื่อนไหวแบบบังคับด้วย JavaScript ได้ มาตรฐานนี้เขียนขึ้นเพื่อรองรับทั้งการใช้งานภาพเคลื่อนไหวและการเปลี่ยน CSS รวมถึงช่วยให้พัฒนาเอฟเฟกต์ในอนาคตได้ ตลอดจนจัดเรียงและกำหนดเวลาเอฟเฟกต์ที่มีอยู่
แม้ว่า Firefox และ Safari จะมีฟีเจอร์ข้อกำหนดครบชุดอยู่แล้ว แต่ Chromium 84 ยังได้นำฟีเจอร์จำนวนมากที่ก่อนหน้านี้ไม่รองรับมาไว้ใน Chrome และ Edge ซึ่งช่วยให้เกิดความสามารถในการทำงานร่วมกันระหว่างเบราว์เซอร์ต่างๆ ได้
เริ่มต้นใช้งาน
การสร้างภาพเคลื่อนไหวโดยใช้ Web Animations API นั้นคุ้นเคยมากหากคุณเคยใช้กฎ @keyframe
ก่อนอื่น คุณจะต้องสร้างออบเจ็กต์เฟรมหลัก ลักษณะของโค้ด CSS อาจมีลักษณะเช่นนี้
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
จะมีลักษณะเช่นนี้ใน JavaScript
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
ตำแหน่งที่คุณตั้งค่าพารามิเตอร์สำหรับภาพเคลื่อนไหวใน CSS
.modal {
animation: openAnimation 1s 1 ease-in;
}
คุณจะตั้งค่าใน JS ดังนี้
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
จำนวนโค้ดก็ใกล้เคียงกัน แต่เมื่อใช้ JavaScript คุณจะได้รับพลังพิเศษ 2-3 อย่างที่คุณไม่มีใน CSS เพียงอย่างเดียว ซึ่งรวมถึงความสามารถในการจัดลำดับเอฟเฟกต์และการควบคุมสถานะการเล่นที่มากขึ้น
เกิน element.animate()
อย่างไรก็ตาม การอัปเดตนี้ทำให้ Web Animations API ไม่จํากัดเฉพาะภาพเคลื่อนไหวที่สร้างโดยใช้ element.animate()
อีกต่อไป นอกจากนี้ เรายังจัดการภาพเคลื่อนไหวและการเปลี่ยนภาพ CSS ได้ด้วย
getAnimations()
เป็นเมธอดที่แสดงผลภาพเคลื่อนไหวทั้งหมดในองค์ประกอบ ไม่ว่าจะสร้างโดยใช้ element.animate()
หรือใช้กฎ CSS (ภาพเคลื่อนไหวหรือการเปลี่ยน CSS) ตัวอย่างลักษณะของการดำเนินการมีดังนี้
ก่อนอื่น ให้"get"
คีย์เฟรมของทรานซิชันเพื่อกำหนดจุดเริ่มต้นของทรานซิชัน จากนั้นสร้างภาพเคลื่อนไหวแบบทึบแสงใหม่ 2 รายการเพื่อเปิดใช้เอฟเฟกต์การเฟด เมื่อการเฟดเสียงเสร็จสิ้นแล้ว ให้ลบสำเนา
วิธีเรียบเรียงภาพเคลื่อนไหวแบบมีคำสัญญา
ใน Chromium 84 คุณจะมี 2 วิธีที่ใช้กับ Promise ได้ ได้แก่ animation.ready
และ animation.finished
animation.ready
ช่วยให้คุณรอให้การเปลี่ยนแปลงที่รอดำเนินการมีผล (นั่นคือ การสลับระหว่างวิธีการควบคุมการเล่น เช่น เล่นและหยุดชั่วคราว)animation.finished
มีวิธีเรียกใช้โค้ด JavaScript ที่กําหนดเองเมื่อภาพเคลื่อนไหวเสร็จสมบูรณ์
ต่อจากตัวอย่างของเราและสร้างเชนภาพเคลื่อนไหวที่ประสานกันด้วย animation.finished
ในตัวอย่างนี้คุณมีการเปลี่ยนรูปแบบแนวตั้ง (scaleY
) ตามด้วยการเปลี่ยนรูปแบบแนวนอน (scaleX
) ตามด้วยการเปลี่ยนแปลงความทึบแสงในองค์ประกอบย่อย
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
เราได้เชื่อมโยงภาพเคลื่อนไหวเหล่านี้โดยใช้ animation.finished.then()
ก่อนที่จะเรียกใช้ชุดภาพเคลื่อนไหวถัดไปในเชน วิธีนี้จะทำให้ภาพเคลื่อนไหวปรากฏตามลำดับ และคุณยังใช้เอฟเฟกต์กับองค์ประกอบเป้าหมายต่างๆ ด้วยการตั้งค่าตัวเลือกที่แตกต่างกันได้ด้วย (เช่น ความเร็วและความนุ่มนวล)
ใน CSS การสร้างภาพเคลื่อนไหวนี้ขึ้นมาใหม่จะยุ่งยากมาก โดยเฉพาะเมื่อใช้ภาพเคลื่อนไหวที่ไม่ซ้ำกันแต่เรียงต่อกันกับองค์ประกอบหลายรายการ คุณต้องใช้ @keyframe
จัดเรียงเปอร์เซ็นต์เวลาที่ถูกต้องเพื่อวางภาพเคลื่อนไหว และใช้ animation-delay
ก่อนเรียกใช้ภาพเคลื่อนไหวตามลำดับ
ตัวอย่างเช่น เล่น หยุดชั่วคราว และย้อนกลับ
สิ่งที่เปิดได้ควรปิด แต่โชคดีที่ตั้งแต่ Chromium 39 เป็นต้นไป Web Animations API ช่วยให้เราสามารถเล่น หยุดชั่วคราว และเล่นภาพเคลื่อนไหวย้อนกลับได้
คุณสามารถใช้ภาพเคลื่อนไหวที่แสดงก่อนหน้านี้และทำให้ภาพเคลื่อนไหวย้อนกลับอย่างราบรื่นเมื่อคลิกปุ่มอีกครั้งโดยใช้ .reverse()
วิธีนี้ช่วยให้คุณสร้างการโต้ตอบที่ราบรื่นและตรงกับบริบทมากขึ้นสําหรับโมดัล
สิ่งที่คุณทำได้คือสร้างภาพเคลื่อนไหวที่รอเล่น 2 รายการ (openModal
และการเปลี่ยนความทึบในบรรทัด) จากนั้นหยุดภาพเคลื่อนไหวรายการใดรายการหนึ่งชั่วคราวเพื่อรอจนกว่าอีกรายการหนึ่งจะเล่นเสร็จ จากนั้นคุณจะใช้สัญญาได้ว่ารอให้แต่ละรายการเสร็จก่อนแล้วค่อยเล่น สุดท้าย ให้ตรวจสอบว่ามีการตั้งค่า Flag หรือไม่ จากนั้นจึงเล่นภาพเคลื่อนไหวแต่ละรายการย้อนกลับ
ตัวอย่าง: การโต้ตอบแบบไดนามิกกับเฟรมหลักบางส่วน
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
ในตัวอย่างนี้ มีเพียงคีย์เฟรมเดียวและไม่มีตำแหน่งเริ่มต้นที่ระบุ นี่เป็นตัวอย่างการใช้คีย์เฟรมบางส่วน แฮนเดิลเมาส์จะทํางาน 2 อย่าง ได้แก่ ตั้งค่าตําแหน่งสิ้นสุดใหม่และเรียกให้ภาพเคลื่อนไหวใหม่แสดง ระบบจะอนุมานตำแหน่งเริ่มต้นใหม่จากตำแหน่งพื้นฐานปัจจุบัน
คุณเรียกใช้ทรานซิชันใหม่ได้ในขณะที่ทรานซิชันที่มีอยู่ยังทำงานอยู่ ซึ่งหมายความว่าการเปลี่ยนปัจจุบันจะหยุดชะงัก และจะมีการสร้างใหม่ขึ้น
การปรับปรุงประสิทธิภาพด้วยภาพเคลื่อนไหวที่เปลี่ยนได้
เมื่อสร้างภาพเคลื่อนไหวตามเหตุการณ์ เช่น on 'mousemove'
ระบบจะสร้างภาพเคลื่อนไหวใหม่ทุกครั้ง ซึ่งอาจทำให้หน่วยความจำหมดลงอย่างรวดเร็วและประสิทธิภาพลดลง ในการแก้ปัญหานี้ เราจึงได้เปิดตัวภาพเคลื่อนไหวที่เปลี่ยนทดแทนได้ใน Chromium 83 ซึ่งจะเปิดใช้การล้างข้อมูลอัตโนมัติ โดยระบบจะแจ้งว่าภาพเคลื่อนไหวที่เสร็จแล้วสามารถเปลี่ยนทดแทนได้และนำออกโดยอัตโนมัติหากมีภาพเคลื่อนไหวที่เสร็จแล้วรายการอื่นมาแทนที่ ลองพิจารณาตัวอย่างต่อไปนี้
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
ทุกครั้งที่เลื่อนเมาส์ เบราว์เซอร์จะคํานวณตําแหน่งของลูกบอลแต่ละลูกในร่องรอยของหางดาวอีกครั้งและสร้างภาพเคลื่อนไหวไปยังจุดใหม่นี้ ตอนนี้เบราว์เซอร์จะรู้วิธีนำภาพเคลื่อนไหวเก่าออก (เปิดใช้การเปลี่ยนทดแทน) ในกรณีต่อไปนี้
- ภาพเคลื่อนไหวเสร็จแล้ว
- มีภาพเคลื่อนไหวตั้งแต่ 1 ภาพขึ้นไปในลำดับผสมซึ่งทำเสร็จแล้วเช่นกัน
- ภาพเคลื่อนไหวใหม่แสดงภาพเคลื่อนไหวของพร็อพเพอร์ตี้เดียวกัน
คุณสามารถดูจํานวนภาพเคลื่อนไหวที่แทนที่ได้โดยนับจํานวนภาพเคลื่อนไหวที่นําออกแต่ละรายการโดยใช้ anim.onremove
เพื่อเรียกใช้ตัวนับ
ยังมีวิธีอื่นๆ อีก 2-3 วิธีที่จะช่วยให้คุณควบคุมภาพเคลื่อนไหวได้มากยิ่งขึ้น ดังนี้
animation.replaceState()
มีไว้เพื่อติดตามว่าภาพเคลื่อนไหวทำงานอยู่ คงอยู่ หรือถูกนำออกanimation.commitStyles()
จะอัปเดตสไตล์ขององค์ประกอบตามสไตล์พื้นฐานพร้อมกับภาพเคลื่อนไหวทั้งหมดในองค์ประกอบในคำสั่งคอมโพสิทanimation.persist()
ทําเครื่องหมายภาพเคลื่อนไหวว่าไม่สามารถแทนที่
ภาพเคลื่อนไหวที่ราบรื่นยิ่งขึ้นด้วยโหมดคอมโพสิต
เมื่อใช้ Web Animations API ตอนนี้คุณตั้งค่าโหมดคอมโพสิตของภาพเคลื่อนไหวได้แล้ว ซึ่งหมายความว่าภาพเคลื่อนไหวจะเพิ่มหรือสะสมได้ นอกเหนือจากโหมดเริ่มต้นของ "แทนที่" โหมดผสมช่วยให้นักพัฒนาซอฟต์แวร์เขียนภาพเคลื่อนไหวที่แตกต่างกันและสามารถควบคุมวิธีรวมเอฟเฟกต์ได้ ขณะนี้รองรับโหมดผสม 3 โหมด ได้แก่ 'replace'
(โหมดเริ่มต้น), 'add'
และ 'accumulate'
เมื่อคุณคอมโพสภาพเคลื่อนไหว นักพัฒนาแอปจะเขียนเอฟเฟกต์สั้นๆ ที่ต่างกันและดูเอฟเฟกต์เหล่านั้นรวมกัน ในตัวอย่างต่อไปนี้ เราใช้เฟรมคีย์การหมุนและการปรับขนาดกับแต่ละกล่อง โดยมีการปรับเพียงโหมดคอมโพสิตเท่านั้น ซึ่งเพิ่มเป็นตัวเลือก
ในโหมดผสม 'replace'
เริ่มต้น ภาพเคลื่อนไหวสุดท้ายจะแทนที่พร็อพเพอร์ตี้ Transform และสิ้นสุดที่ rotate(360deg) scale(1.4)
สำหรับ 'add'
คอมโพสิตจะเพิ่มการหมุนเวียนและคูณสเกลเพื่อให้ได้สถานะสุดท้ายเป็น rotate(720deg) scale(1.96)
'accumulate'
รวมการเปลี่ยนรูปแบบเข้าด้วยกัน ผลลัพธ์ที่ได้คือ rotate(720deg) scale(1.8)
ดูข้อมูลเพิ่มเติมเกี่ยวกับความซับซ้อนของโหมดคอมโพสิทเหล่านี้ได้ที่การแจกแจง CompositeOperation และ CompositeOperationOrAuto จากข้อกำหนดของ Web Animations
ดูตัวอย่างองค์ประกอบ UI ต่อไปนี้
ในตัวอย่างนี้มีการผสมภาพเคลื่อนไหว top
2 รายการ อย่างแรกเป็นภาพเคลื่อนไหวแบบมาโคร ซึ่งย้ายเมนูแบบเลื่อนลงตามความสูงสูงสุดของเมนูเป็นเอฟเฟ็กต์แบบเลื่อนเข้าจากด้านบนของหน้า และอย่างที่ 2 เป็นภาพเคลื่อนไหวขนาดเล็กที่จะตีกลับเล็กน้อยเมื่อไปถึงด้านล่าง การใช้'add'
โหมดคอมโพสิตช่วยให้การเปลี่ยนเป็นไปอย่างราบรื่น
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
การพัฒนา Web Animations API ในอนาคต
ทั้งหมดนี้เป็นการเพิ่มความสามารถที่น่าสนใจให้กับภาพเคลื่อนไหวในเบราว์เซอร์ในปัจจุบัน และเรายังมีการเพิ่มฟีเจอร์อื่นๆ อีกมากมายในเร็วๆ นี้ โปรดอ่านข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่จะเกิดขึ้นในอนาคตจากข้อกำหนดต่อไปนี้