การปรับปรุง Web Animations API ใน Chromium 84

การจัดระเบียบภาพเคลื่อนไหวด้วย Promise, การเพิ่มประสิทธิภาพด้วยภาพเคลื่อนไหวที่เปลี่ยนทดแทนได้, ภาพเคลื่อนไหวที่ราบรื่นขึ้นด้วยโหมดคอมโพสิต และอื่นๆ

เผยแพร่: 27 พฤษภาคม 2020

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

Web Animations API เป็นเครื่องมือที่ช่วยให้นักพัฒนาซอฟต์แวร์เขียนภาพเคลื่อนไหวแบบบังคับด้วย JavaScript ได้ มาตรฐานนี้เขียนขึ้นเพื่อรองรับทั้งการใช้งานภาพเคลื่อนไหว CSS และการเปลี่ยน และช่วยให้พัฒนาเอฟเฟกต์ในอนาคต รวมถึงจัดเรียงและกำหนดเวลาเอฟเฟกต์ที่มีอยู่ได้

แม้ว่า Firefox และ Safari จะใช้ฟีเจอร์ตามข้อกำหนดครบชุดแล้ว แต่ Chromium 84 ก็มีฟีเจอร์จำนวนมากที่ก่อนหน้านี้ไม่รองรับใน Chrome และ Edge ซึ่งช่วยให้เบราว์เซอร์ต่างๆ ทำงานร่วมกันได้

Web Animations API เปิดตัวครั้งแรกใน Chromium เวอร์ชัน 36 เมื่อเดือนกรกฎาคม 2014 ตอนนี้ข้อกำหนดจะสมบูรณ์แล้วในเวอร์ชัน 84 ซึ่งจะเปิดตัวในเดือนกรกฎาคม 2020
ประวัติอันยาวนานของ Web Animations API ใน Chromium

เริ่มต้นใช้งาน

การสร้างภาพเคลื่อนไหวโดยใช้ 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) ตามด้วยการเปลี่ยนแปลงความทึบขององค์ประกอบย่อย

การใช้การเปลี่ยนรูปแบบและความทึบขององค์ประกอบแบบโมดัลที่เปิดอยู่ ดูการสาธิตใน Codepen
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() วิธีนี้ช่วยให้คุณสร้างการโต้ตอบที่ราบรื่นและตรงกับบริบทมากขึ้นสําหรับโมดอล

ตัวอย่างการเปิดและปิดโมดัลเมื่อคลิกปุ่ม ดูการสาธิตใน Glitch

สิ่งที่คุณทำได้คือสร้างภาพเคลื่อนไหวที่รอเล่น 2 รายการ (openModal และการเปลี่ยนความทึบในบรรทัด) จากนั้นหยุดภาพเคลื่อนไหวรายการใดรายการหนึ่งชั่วคราวเพื่อรอจนกว่าอีกรายการหนึ่งจะเล่นเสร็จ จากนั้นคุณสามารถใช้ Promise เพื่อรอให้แต่ละรายการเสร็จสิ้นก่อนที่จะเล่น สุดท้าย ให้ตรวจสอบว่ามีการตั้งค่า Flag หรือไม่ จากนั้นจึงเล่นภาพเคลื่อนไหวแต่ละรายการย้อนกลับ

ตัวอย่าง: การโต้ตอบแบบไดนามิกกับเฟรมหลักบางส่วน

ตัวอย่างการกำหนดเป้าหมายใหม่ เมื่อคลิกเมาส์จะปรับภาพเคลื่อนไหวไปยังตำแหน่งใหม่ ดูการสาธิตใน Glitch
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

ในตัวอย่างนี้ มีเพียงคีย์เฟรมเดียวและไม่มีตำแหน่งเริ่มต้นที่ระบุ นี่เป็นตัวอย่างการใช้คีย์เฟรมบางส่วน แฮนเดิลเมาส์จะทํางาน 2 อย่าง ได้แก่ ตั้งค่าตําแหน่งสิ้นสุดใหม่และเรียกให้ภาพเคลื่อนไหวใหม่แสดง ระบบจะอนุมานตำแหน่งเริ่มต้นใหม่จากตำแหน่งพื้นฐานปัจจุบัน

คุณเรียกใช้ทรานซิชันใหม่ได้ในขณะที่ทรานซิชันที่มีอยู่ยังทำงานอยู่ ซึ่งหมายความว่าทรานซิชันปัจจุบันจะหยุดชะงักและระบบจะสร้างทรานซิชันใหม่

การปรับปรุงประสิทธิภาพด้วยภาพเคลื่อนไหวที่เปลี่ยนได้

เมื่อสร้างภาพเคลื่อนไหวตามเหตุการณ์ เช่น on 'mousemove' ระบบจะสร้างภาพเคลื่อนไหวใหม่ทุกครั้ง ซึ่งอาจทำให้หน่วยความจำหมดลงอย่างรวดเร็วและประสิทธิภาพลดลง ในการแก้ปัญหานี้ เราจึงได้เปิดตัวภาพเคลื่อนไหวที่เปลี่ยนทดแทนได้ใน Chromium 83 ซึ่งจะเปิดใช้การล้างข้อมูลอัตโนมัติ โดยระบบจะแจ้งว่าภาพเคลื่อนไหวที่เสร็จแล้วสามารถเปลี่ยนทดแทนได้และนำออกโดยอัตโนมัติหากมีภาพเคลื่อนไหวที่เสร็จแล้วรายการอื่นมาแทนที่ ลองพิจารณาตัวอย่างต่อไปนี้

หางดาวจะเคลื่อนไหวเมื่อเมาส์เคลื่อนไหว ดูการสาธิตใน Glitch
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

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

  1. ภาพเคลื่อนไหวเสร็จแล้ว
  2. มีภาพเคลื่อนไหวอย่างน้อย 1 รายการที่สูงกว่าในลําดับคอมโพสิตซึ่งเสร็จสมบูรณ์แล้ว
  3. ภาพเคลื่อนไหวใหม่แสดงภาพเคลื่อนไหวของพร็อพเพอร์ตี้เดียวกัน

คุณสามารถดูจำนวนภาพเคลื่อนไหวที่แทนที่ได้อย่างแม่นยำโดยการนับตัวนับที่มีภาพเคลื่อนไหวแต่ละรายการที่นําออก โดยใช้ anim.onremove เพื่อเรียกใช้ตัวนับ

พร็อพเพอร์ตี้และเมธอดเพิ่มเติมอีก 2-3 รายการที่จะช่วยควบคุมภาพเคลื่อนไหวได้มากขึ้น

  • animation.replaceState มีไว้เพื่อติดตามว่าภาพเคลื่อนไหวทำงานอยู่ คงอยู่ หรือถูกนำออก
  • animation.commitStyles() จะอัปเดตสไตล์ขององค์ประกอบตามสไตล์พื้นฐานพร้อมกับภาพเคลื่อนไหวทั้งหมดในองค์ประกอบในคำสั่งคอมโพสิท
  • animation.persist() ทําเครื่องหมายภาพเคลื่อนไหวว่าไม่สามารถแทนที่

ภาพเคลื่อนไหวที่ราบรื่นยิ่งขึ้นด้วยโหมดคอมโพสิต

เมื่อใช้ Web Animations API ตอนนี้คุณตั้งค่าโหมดคอมโพสิตของภาพเคลื่อนไหวได้แล้ว ซึ่งหมายความว่าภาพเคลื่อนไหวจะเพิ่มหรือสะสมได้ นอกเหนือจากโหมดเริ่มต้นของ "แทนที่" โหมดคอมโพสิตช่วยให้นักพัฒนาแอปเขียนภาพเคลื่อนไหวที่โดดเด่นและควบคุมวิธีรวมเอฟเฟกต์ได้ ตอนนี้ระบบรองรับโหมดคอมโพสิต 3 โหมด ได้แก่ 'replace' (โหมดเริ่มต้น), 'add' และ 'accumulate'

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

การสาธิตโหมดคอมโพสิตเริ่มต้น เพิ่ม และสะสม ดูการสาธิตใน Glitch

ในโหมดคอมโพสิท 'replace' เริ่มต้น ภาพเคลื่อนไหวสุดท้ายจะแทนที่พร็อพเพอร์ตี้ transform และสิ้นสุดที่ rotate(360deg) scale(1.4) สำหรับ 'add' คอมโพสิทจะเพิ่มการหมุนและคูณด้วยมาตราส่วน ซึ่งส่งผลให้สถานะสุดท้ายเป็น rotate(720deg) scale(1.96) 'accumulate' รวมการเปลี่ยนรูปแบบเข้าด้วยกัน ผลที่ได้คือ rotate(720deg) scale(1.8) ดูข้อมูลเพิ่มเติมเกี่ยวกับความซับซ้อนของโหมดคอมโพสิทเหล่านี้ได้ที่การแจกแจง CompositeOperation และ CompositeOperationOrAuto จากข้อกำหนดของ Web Animations

โปรดดูตัวอย่างองค์ประกอบ UI ต่อไปนี้

เมนูแบบเลื่อนลงที่เด้งขึ้นและมีภาพเคลื่อนไหวแบบคอมโพสิต 2 รายการ ดูการสาธิตใน Glitch

ที่นี่มีการคอมโพสภาพเคลื่อนไหว 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 ในอนาคต

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