การจัดระเบียบภาพเคลื่อนไหวด้วย 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 จะช่วยให้คุณมีความสามารถพิเศษบางอย่างที่ CSS เพียงอย่างเดียวไม่มี ซึ่งรวมถึงความสามารถในการจัดลำดับเอฟเฟกต์และการควบคุมสถานะการเล่นที่มากขึ้น
มากกว่า element.animate()
อย่างไรก็ตาม การอัปเดตนี้ทำให้ Web Animations API ไม่จํากัดเฉพาะภาพเคลื่อนไหวที่สร้างโดยใช้ element.animate()
อีกต่อไป นอกจากนี้ เรายังจัดการภาพเคลื่อนไหวและการเปลี่ยนภาพ CSS ได้ด้วย
getAnimations()
เป็นเมธอดที่แสดงผลภาพเคลื่อนไหวทั้งหมดในองค์ประกอบ ไม่ว่าจะสร้างโดยใช้ element.animate()
หรือใช้กฎ CSS (ภาพเคลื่อนไหวหรือการเปลี่ยน CSS) ตัวอย่างลักษณะของการดำเนินการมีดังนี้
ก่อนอื่น ให้"get"
คีย์เฟรมของทรานซิชันเพื่อกำหนดจุดเริ่มต้นของทรานซิชัน จากนั้นสร้างภาพเคลื่อนไหวแบบทึบแสงใหม่ 2 รายการเพื่อเปิดใช้เอฟเฟกต์การเฟด เมื่อการค่อยๆ จางลงเสร็จแล้ว ให้ลบสำเนา
วิธีจัดระเบียบภาพเคลื่อนไหวด้วย Promise
ใน 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
และการเปลี่ยนความทึบในบรรทัด) จากนั้นหยุดภาพเคลื่อนไหวรายการใดรายการหนึ่งชั่วคราวเพื่อรอจนกว่าอีกรายการหนึ่งจะเล่นเสร็จ จากนั้นคุณสามารถใช้ Promise เพื่อรอให้แต่ละรายการเสร็จสิ้นก่อนที่จะเล่น สุดท้าย ให้ตรวจสอบว่ามีการตั้งค่า Flag หรือไม่ จากนั้นจึงเล่นภาพเคลื่อนไหวแต่ละรายการย้อนกลับ
ตัวอย่าง: การโต้ตอบแบบไดนามิกกับเฟรมหลักบางส่วน
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
ในตัวอย่างนี้ มีเพียงคีย์เฟรมเดียวและไม่มีตำแหน่งเริ่มต้นที่ระบุ นี่เป็นตัวอย่างการใช้คีย์เฟรมบางส่วน ตัวแฮนเดิลเมาส์มีการทำงานหลายอย่างที่นี่ โดยจะกำหนดตำแหน่งสิ้นสุดใหม่และทริกเกอร์ภาพเคลื่อนไหวใหม่ ระบบจะอนุมานตำแหน่งเริ่มต้นใหม่จากตำแหน่งพื้นฐานปัจจุบัน
คุณเรียกใช้ทรานซิชันใหม่ได้ในขณะที่ทรานซิชันที่มีอยู่ยังทำงานอยู่ ซึ่งหมายความว่าทรานซิชันปัจจุบันจะหยุดชะงักและระบบจะสร้างทรานซิชันใหม่
การปรับปรุงประสิทธิภาพด้วยภาพเคลื่อนไหวที่เปลี่ยนได้
เมื่อสร้างภาพเคลื่อนไหวตามเหตุการณ์ เช่น 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 ในอนาคต
ทั้งหมดนี้เป็นการเพิ่มความสามารถที่น่าสนใจให้กับภาพเคลื่อนไหวในเบราว์เซอร์ในปัจจุบัน และเรายังมีการเพิ่มฟีเจอร์อื่นๆ อีกมากมายในเร็วๆ นี้ โปรดอ่านข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่จะเกิดขึ้นในอนาคตจากข้อกำหนดต่อไปนี้