דוגמאות לאנימציות CSS עם ביצועים גבוהים

בפוסט הזה נסביר איך נוצרו כמה אנימציות פופולריות ב-CodePen. כל האנימציות האלה משתמשות בשיטות היעילות שמתוארות במאמרים אחרים בקטע הזה.

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

אנימציה של טעינת האשף

צפייה באנימציית הטעינה של Wizard ב-CodePen

האנימציה הזו של הטעינה נוצרה לגמרי באמצעות CSS. התמונה וכל האנימציה נוצרו ב-CSS וב-HTML, בלי תמונות או JavaScript. כדי להבין איך הוא נוצר ומה רמת הביצועים שלו, אתם יכולים להשתמש בכלי הפיתוח ל-Chrome.

בדיקת האנימציה באמצעות כלי הפיתוח ל-Chrome

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

סיכום בכלי הפיתוח
הסיכום אחרי יצירת פרופיל של האנימציה של האשף.

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

חלונית האנימציות שבה מוצגים החלקים השונים של האנימציה.
צפייה בפריטים ובחירת פריטים בחלונית האנימציה של כלי הפיתוח ל-Chrome.

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

סרטון שמראה איך אפשר לעקוב אחרי הנתיב של המשולש בכלי הפיתוח ל-Chrome.

כשהרכיב עדיין מסומן, מסתכלים על חלונית הסגנונות. שם אפשר לראות את ה-CSS שיוצר את צורת המשולש, ואת האנימציה שבה נעשה שימוש.

איך זה עובד

המשולש נוצר באמצעות הרכיב המדומה ::after כדי להוסיף תוכן שנוצר, באמצעות גבולות ליצירת הצורה.

.triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
}

.triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
}

האנימציה נוספת באמצעות שורת ה-CSS הבאה,

animation: path_triangle 10s ease-in-out infinite;

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

@keyframes path_triangle {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
  }
  55% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  58% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  63% {
    transform: rotate(-360deg);
  }
}

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

עיגול פועם

הצגת עיגול פועם ב-CodePen

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

בדיקת האנימציה באמצעות כלי הפיתוח של Firefox

כשהאנימציה פועלת, פותחים את הכרטיסייה Performance ב-Firefox DevTools ומקליטים כמה שניות מהאנימציה. עוצרים את ההקלטה. בתרשים המפל לא אמורות להופיע רשומות של Recalculate Style. עכשיו אתם יודעים שהאנימציה הזו לא גורמת לחישוב מחדש של הסגנון, ולכן גם לא לפעולות של פריסה וצביעה.

פרטי האנימציה ב-Firefox Waterfall
‫Waterfall בכלי הפיתוח של Firefox.

נשארים ב-Firefox DevTools ובודקים את העיגול כדי לראות איך האנימציה הזו פועלת. ה-<div> עם מחלקה של pulsating-circle מסמן את מיקום המעגל, אבל לא מצייר מעגל בעצמו.

.pulsating-circle {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 30px;
    height: 30px;
}

העיגול והאנימציות שרואים נוצרים באמצעות הרכיבים המדומים ::before ו-::after.

הרכיב ::before יוצר את הטבעת האטומה שמתרחבת מחוץ לעיגול הלבן, באמצעות אנימציה שנקראת pulse-ring, שמנפישה את transform: scale ואת opacity.

.pulsating-circle::before {
    content: '';
    position: relative;
    display: block;
    width: 300%;
    height: 300%;
    box-sizing: border-box;
    margin-left: -100%;
    margin-top: -100%;
    border-radius: 45px;
    background-color: #01a4e9;
    animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%, 100% {
    opacity: 0;
  }
}

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

כשהרכיב המדומה ‎ ::before נבחר, אפשר לראות אילו מאפיינים מונפשים.

העיגול הלבן עצמו נוצר ומונפש באמצעות הרכיב המדומה ::after. האנימציה pulse-dot משתמשת ב-transform: scale כדי להגדיל ולהקטין את הנקודה במהלך האנימציה.

.pulsating-circle::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

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

כדור תלת-ממדי ב-CSS טהור

הצגת כדור תלת-ממדי ב-CSS טהור ב-CodePen

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

פותחים את כלי הפיתוח ל-Chrome ובוחרים באחד מהרכיבים עם מחלקה של plane. הכדור מורכב מקבוצה של מישורים וחישורים מסתובבים.

נראה שהמטוס מסתובב.

המישורים והחישורים האלה נמצאים בתוך רכיב wrapper‏ <div>, והרכיב הזה מסתובב באמצעות transform: rotate3d.

.sphere-wrapper {
  transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  position: relative;
  animation: rotate3d 10s linear infinite;
}

@keyframes rotate3d {
  0% {
    transform: rotate3d(1, 1, 1, 0deg);
  }
  25% {
    transform: rotate3d(1, 1, 1, 90deg);
  }
  50% {
    transform: rotate3d(1, 1, 1, 180deg);
  }
  75% {
    transform: rotate3d(1, 1, 1, 270deg);
  }
  100% {
    transform: rotate3d(1, 1, 1, 360deg);
  }
}

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

הנקודה מסתובבת עם הכדור ומהבהבת.
.spoke-15 .dot,
.spoke-21 .dot {
  animation: pulsate 0.5s infinite 0.83333333s alternate both;
  background-color: #55ffee;
}

@-webkit-keyframes pulsate {
  0% {
    transform: rotateX(90deg) scale(0.3) translateZ(20px);
  }
  100% {
    transform: rotateX(90deg) scale(1) translateZ(0px);
  }
}

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

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

סיכום

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