การปรับปรุง 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'});

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

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

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

เมื่อสร้างภาพเคลื่อนไหวตามเหตุการณ์ เช่น 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 ในอนาคต

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