שיפורים בממשק ה-API של אנימציות באינטרנט ב-Chromium 84

תיאום אנימציות עם הבטחות, שיפורי ביצועים עם אנימציות להחלפה, אנימציות חלקות יותר עם מצבים מרוכבים ועוד.

Kevin Ellis
Kevin Ellis

כשמשתמשים נכון, אנימציות משפרות את דימויים של המשתמשים ואת הזיכרון שלהם לגבי המותג, מניעות אותם לפעולות המשתמש ועוזרות למשתמשים לנווט באפליקציה – ומספקות הקשר במרחב הדיגיטלי.

Web Animations API הוא כלי שמאפשר למפתחים לכתוב אנימציות ציוויות באמצעות JavaScript. היא נכתבה כדי לתמוך בהטמעות של אנימציית CSS ובמעברים, ולאפשר פיתוח של אפקטים עתידיים וגם להלחנת אפקטים קיימים ולתזמון.

בעוד ש-Firefox ו-Safari כבר הטמיעו את כל תכונות המפרטים של המפרט, Chromium 84 כולל מגוון רחב של תכונות שלא היו נתמכות בעבר ב-Chrome ו-Edge ומאפשרות פעולה הדדית בדפדפנים שונים.

ה-Web Animations API הגיע לראשונה ל-Chromium בגרסה 36, יולי 2014. המפרט יהיה מוכן במלואו בגרסה 84, שתושק ביולי 2020.
ההיסטוריה הארוכה של API לאנימציות באינטרנט ב-Chromium.

איך מתחילים

אם השתמשתם בכללים של @keyframe, תהליך היצירה של אנימציה באמצעות ממשק ה-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()

עם זאת, לאחר העדכון, ה-API של האנימציות באינטרנט כבר לא מוגבל לאנימציות שנוצרו דרך element.animate(). כמו כן, אנחנו יכולים לטפל באנימציות ומעברים של CSS.

getAnimations() היא שיטה שמחזירה את כל האנימציות ברכיב מסוים, לא משנה אם היא נוצרה באמצעות element.animate() או באמצעות כללי CSS (אנימציית CSS או מעבר). לדוגמה:

כדי לקבוע מאיפה אנחנו מבצעים את המעבר, קודם צריך "get" את תמונות המפתח של המעבר. לאחר מכן, אתם יוצרים שתי הנפשות אטימות חדשות, שמאפשרות את אפקט העמעום המוצלב. לאחר הסיום של תהליך העמעום, מוחקים את העותק.

תזמור אנימציות עם הבטחות

ב-Chromium 84 יש עכשיו שתי שיטות שבהן אפשר להשתמש בהבטחות: 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, ממשק ה-API של 'אנימציות באינטרנט' מאפשר לנו להפעיל, להשהות ולשנות את האנימציות שלנו.

אפשר להשתמש באנימציה שלמעלה וליצור אנימציה חלקה הפוכה כשלוחצים שוב על הלחצן באמצעות .reverse(). כך ניתן ליצור אינטראקציה חלקה והקשרית יותר עבור חלון העזר שלנו.

דוגמה לפתיחה וסגירה של חלון עזר בעקבות לחיצה על לחצן. לצפייה בהדגמה של תקלה

ניתן ליצור שתי אנימציות בהמתנה להפעלה (openModal, ושינוי אטימות בתוך השורה), ולאחר מכן להשהות אחת מהאנימציות ולעכב אותה עד שהשנייה מסתיימת. לאחר מכן, אפשר להשתמש בהבטחות כדי להמתין לסיום של כל אחת מהן לפני ההפעלה. לסיום, אפשר לבדוק אם הוגדר סימון ואז להפוך כל אנימציה.

דוגמה: אינטראקציות דינמיות עם תמונות מפתח חלקיות

דוגמה לטירגוט מחדש, שבה לחיצה על עכבר מתאימה את האנימציה למיקום חדש. לצפייה בהדגמה של תקלה
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

בדוגמה הזו, יש רק תמונת מפתח אחת ולא צוין מיקום התחלה. בהמשך תוכלו לראות דוגמה לשימוש בתמונות מפתח חלקיות. הגורם המטפל בעכבר מבצע כאן כמה פעולות: הוא מגדיר מיקום סיום חדש ומפעיל אנימציה חדשה. המערכת מסיקה את מיקום ההתחלה החדש מהמיקום הבסיסי הנוכחי.

אפשר להפעיל מעברים חדשים בזמן שהמעברים הקיימים עדיין פועלים. המשמעות היא שהמעבר הנוכחי נקטע ונוצר מעבר חדש.

שיפורי ביצועים עם אנימציות להחלפה

כשיוצרים אנימציות שמבוססות על אירועים, כמו ב-'mousemove', נוצרת אנימציה חדשה בכל פעם, והיא יכולה לצרוך במהירות זיכרון ולפגוע בביצועים. כדי לטפל בבעיה הזו, הוספנו ב-Chromium 83 אנימציות הניתנות להחלפה. האנימציות הניתנות להחלפה הופעלו ב-Chromium 83 ושיאפשרו ניקוי אוטומטי, שבו האנימציות הסופיות מסומנות כניתנות להחלפה ומוסרות באופן אוטומטי אם הן מוחלפות באנימציה אחרת הסתיימה. לדוגמה:

האנימציה של שובל שביט מתבצעת כשהעכבר זז. לצפייה בהדגמה של תקלה
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

בכל פעם שהעכבר זז, הדפדפן מחשב מחדש את המיקום של כל כדור בכוכב השביט ויוצר אנימציה לנקודה חדשה זו. הדפדפן יודע עכשיו להסיר אנימציות ישנות (הפעלת החלפה) כאשר:

  1. האנימציה הסתיימה.
  2. קיימת אנימציה אחת או יותר בסדר מורכב גם הן ברמת הסיום.
  3. האנימציות החדשות כוללות אנימציה של אותם מאפיינים.

אפשר לראות בדיוק כמה אנימציות מוחלפות על ידי סיכום המונה לאחר כל אנימציה שהוסרה, באמצעות anim.onremove כדי להפעיל את המונה.

יש כמה שיטות נוספות לשיפור השליטה באנימציה:

  • animation.replaceState() מאפשר לבדוק אם אנימציה פעילה, מתמשכת או הוסרה.
  • animation.commitStyles() מעדכן את הסגנון של אלמנט על סמך הסגנון הבסיסי, יחד עם כל האנימציות ברכיב לפי הסדר המרוכב.
  • animation.persist() מסמן אנימציה כלא ניתנת להחלפה.

אנימציות חלקות יותר עם מצבים מורכבים

באמצעות ממשק ה-API של 'אנימציות באינטרנט', תוכל כעת להגדיר את המצב המרוכב של האנימציות, כלומר שהן יכולות להיות מצטברות או מצטברות, בנוסף למצב ברירת המחדל של 'החלפה'. מצבים מורכבים מאפשרים למפתחים לכתוב אנימציות ייחודיות ולשלוט באופן השילוב של האפקטים. עכשיו יש תמיכה בשלושה מצבים מרוכבים: 'replace' (מצב ברירת המחדל), 'add' ו-'accumulate'.

כשמשלבים אנימציות, המפתח יכול לכתוב אפקטים קצרים וברורים ולראות אותם יחד. בדוגמה הבאה, אנחנו מחילים תמונת מפתח של סיבוב וקנה מידה של פריים מפתח לכל תיבה, כאשר ההתאמה היחידה היא המצב המרוכב, והיא נוספה כאפשרות:

הדגמה שמציגה את ברירת המחדל, הוספה וצבירה של מצבים מרוכבים. לצפייה בהדגמה של תקלה

במצב המרוכב המוגדר כברירת מחדל של 'replace', האנימציה הסופית מחליפה את מאפיין הטרנספורמציה ומסתיימת ב-rotate(360deg) scale(1.4). עבור הפונקציה 'add', הרכיב 'מרוכב' מוסיף את הסיבוב ומכפיל את קנה המידה, וכתוצאה מכך מתקבל מצב סופי של rotate(720deg) scale(1.96). 'accumulate' משלב את הטרנספורמציות, והתוצאה היא rotate(720deg) scale(1.8). למידע נוסף על המורכבות של המצבים המרוכבים האלה, ניתן לעיין בהסכומים של CompositeOperation ו-CompositeOperationOrAuto במפרט של אנימציות באינטרנט.

הנה דוגמה לאלמנט בממשק המשתמש:

תפריט נפתח קופצני שהופעלו בו שתי אנימציות מורכבות. לצפייה בהדגמה של תקלה

בדוגמה הזו מורכבת שתי אנימציות של top. הראשונה היא אנימציה של מאקרו, שמזיזה את התפריט הנפתח בגובה המלא של התפריט עצמו כאפקט החלקה מהחלק העליון של הדף, והשנייה, מיקרו אנימציה, מחילה עזיבה מהדף הראשון כשהיא מגיעה לתחתית הדף. השימוש במצב המרוכב של '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

אלו הן תוספות מלהיבות ליכולות האנימציות בדפדפנים של ימינו, ובעתיד יתווספו עוד תוספות. עיין במפרטים העתידיים האלה כדי לקבל מידע נוסף על מה שצפוי בקרוב: