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

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

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

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 ข้อ ก่อนอื่น คุณจะต้องสร้างออบเจ็กต์ 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 อย่างที่ไม่มีใน CSS เพียงอย่างเดียว ซึ่งรวมถึงความสามารถในการจัดลำดับเอฟเฟกต์และการควบคุมสถานะการเล่นที่มากขึ้น

เกิน element.animate()

อย่างไรก็ตาม การอัปเดตนี้ทำให้ Web Animations API ไม่ถูกจำกัดไว้สำหรับภาพเคลื่อนไหวที่สร้างผ่าน element.animate() อีกต่อไป เราสามารถจัดการภาพเคลื่อนไหวและการเปลี่ยนของ CSS ได้เช่นกัน

getAnimations() คือเมธอดที่แสดงผลภาพเคลื่อนไหวทั้งหมดในองค์ประกอบหนึ่งๆ โดยไม่คำนึงว่าจะสร้างผ่าน element.animate() หรือผ่านกฎ CSS (ภาพเคลื่อนไหวหรือการเปลี่ยนของ CSS) ซึ่งมีลักษณะดังนี้

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

การจัดเรียงภาพเคลื่อนไหวพร้อมคำสัญญา

ใน Chromium 84 ตอนนี้คุณสามารถใช้กับสัญญาได้ 2 วิธี ได้แก่ 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 และการเปลี่ยนรูปแบบความทึบแสงในบรรทัด) จากนั้นหยุดภาพเคลื่อนไหวหนึ่งไว้ชั่วคราวโดยหน่วงเวลาไว้จนกว่าอีกภาพเคลื่อนไหวหนึ่งจะเสร็จสิ้น จากนั้นใช้คำสัญญาเพื่อรอให้แต่ละคลิปเล่นจบก่อนที่จะเล่นได้ สุดท้าย คุณสามารถตรวจสอบว่ามีการตั้งค่าสถานะแล้วหรือไม่ แล้วย้อนกลับภาพเคลื่อนไหวแต่ละภาพ

ตัวอย่าง: การโต้ตอบแบบไดนามิกที่มีคีย์เฟรมบางส่วน

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

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

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

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

เมื่อสร้างภาพเคลื่อนไหวตามเหตุการณ์ เช่น ในวันที่ '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' ภาพเคลื่อนไหวขั้นสุดท้ายจะแทนที่คุณสมบัติการเปลี่ยนรูปแบบและสิ้นสุดที่ rotate(360deg) scale(1.4) สำหรับ 'add' ค่าคอมโพสิตจะเพิ่มการหมุนและคูณสเกลเพื่อให้ได้สถานะสุดท้ายเป็น rotate(720deg) scale(1.96) 'accumulate' จะรวมการเปลี่ยนรูปแบบเข้าด้วยกันซึ่งทําให้ได้ rotate(720deg) scale(1.8) ดูข้อมูลเพิ่มเติมเกี่ยวกับความซับซ้อนของโหมดผสมเหล่านี้ได้ที่การแจงนับ CompositeOperating และ CompositeOpsOrAuto จากข้อกำหนดของ Web Animations

มาดูตัวอย่างองค์ประกอบ UI กัน

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

ตรงนี้จะมีการนำภาพเคลื่อนไหว top 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

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