• About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us
AimactGrow
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing
No Result
View All Result
AimactGrow
No Result
View All Result

Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)

Admin by Admin
May 9, 2025
Home Coding
Share on FacebookShare on Twitter


I not too long ago up to date my portfolio at johnrhea.com. (If you happen to’re trying so as to add a CSS or front-end engineer with storytelling and animation abilities to your group, I’m your man.) I appreciated the look of a sequence of planets I’d created for one more private undertaking and determined to reuse them on my new website. A part of that was additionally reusing an animation I’d constructed circa 2019, the place a moon orbited across the planet.

Initially, I simply plopped the animations into the brand new website, solely altering the items (em items to viewport items utilizing some difficult math that I used to be very, very happy with) in order that they might scale correctly as a result of I’m… environment friendly with my time. Nonetheless, on cell, the planet would transfer up a number of pixels and down a number of pixels because the moons orbited round it. I suspected the plopped-in animation was the offender (it wasn’t, however at the least I acquired some optimized animation and an article out of the deal).

Right here’s the unique animation:

My preliminary animation for the moon ran for 60 seconds. I’m folding it inside a disclosure widget as a result of, at 141 traces, it’s silly lengthy (and, as we’ll see, emphasis on the silly). Right here it’s in all its “glory”:

Open code
#moon1 {
  animation: moon-one 60s infinite;
}

@keyframes moon-one {
  0% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  5% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  9.9% {
    z-index: 2;
  }
  10% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  15% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  19.9% {
    z-index: -1;
  }
  20% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  25% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  29.9% {
    z-index: 2;
  }
  30% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  35% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  39.9% {
    z-index: -1;
  }
  40% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  45% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  55% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  59.9% {
    z-index: -1;
  }
  60% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  65% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  69.9% {
    z-index: 2;
  }
  70% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  75% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  79.9% {
    z-index: -1;
  }
  80% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  85% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  89.9% {
    z-index: 2;
  }
  90% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  95% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  99.9% {
    z-index: -1;
  }
  100% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
}

If you happen to take a look at the keyframes in that code, you’ll discover that the 0% to 20% keyframes are precisely the identical as 20% to 40% and so forth up via 100%. Why I made a decision to repeat the keyframes 5 instances infinitely as a substitute of simply repeating one set infinitely is a call misplaced to antiquity, like six years in the past in net time. We are able to additionally drop the length to 12 seconds (one-fifth of sixty) if we had been doing our due diligence.

I might thus delete the whole lot from 20% on, immediately dropping the code right down to 36 traces. And sure, I understand positive aspects like this are unlikely to be attainable on most websites, however this is step one for optimizing issues.

#moon1 {
  animation: moon-one 12s infinite;
}

@keyframes moon-one {
  0% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  5% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  9.9% {
    z-index: 2;
  }
  10% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  15% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  19.9% {
    z-index: -1;
  }
  20% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
}

Now that we’ve gotten rid of 80% of the overwhelming bits, we are able to see that there are 5 essential keyframes and two extra ones that set the z-index near the center and finish of the animation (these stop the moon from dropping behind the planet or coming out from behind the planet too early). We are able to change these 5 factors from 0%, 5%, 10%, 15%, and 20% to 0%, 25%, 50%, 75%, and 100% (and because the 0% and the previous 20% are the identical, we are able to take away that one, too). Additionally, because the 10% keyframe above is switching to 50%, the 9.9% keyframe can transfer to 49.9%, and the 19.9% keyframe can change to 99.9%, giving us this:

#moon1 {
  animation: moon-one 12s infinite;
}

@keyframes moon-one {
  0%, 100% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  25% {
    rework: translate(-3.51217391vw, 3.50608696vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    rework: translate(-5.01043478vw, 6.511304348vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  75% {
    rework: translate(1.003478261vw, 2.50608696vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  99.9% {
    z-index: -1;
  }
}

Although I used to be very happy with myself for my math wrangling, numbers like -3.51217391vw are actually, actually pointless. If a display was one thousand pixels extensive, -3.51217391vw can be 35.1217391 pixels. Nobody ever must go right down to the precision of a ten-millionth of a pixel. So, let’s spherical the whole lot to the tenth place (and if it’s a 0, we’ll simply drop it). We are able to additionally skip z-index within the 75% and 25% keyframes because it doesn’t change.

Right here’s the place that will get us within the code:

#moon1 {
  animation: moon-one 12s infinite;
}

@keyframes moon-one {
  0%, 100% {
    rework: translate(0, 0) scale(1);
    z-index: 2;
    animation-timing-function: ease-in;
  }
  25% {
    rework: translate(-3.5vw, 3.5vw) scale(1.5);
    z-index: 2;
    animation-timing-function: ease-out;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    rework: translate(-5vw, 6.5vw) scale(1);
    z-index: -1;
    animation-timing-function: ease-in;
  }
  75% {
    rework: translate(1vw, 2.5vw) scale(0.25);
    z-index: -1;
    animation-timing-function: ease-out;
  }
  99.9% {
    z-index: -1;
  }
}

In spite of everything our modifications, the animation nonetheless seems fairly near what it was earlier than, solely means much less code:

One of many issues I don’t like about this animation is that the moon form of turns at its zenith when it crosses the planet. It will be significantly better if it traveled in a straight line from the higher proper to the decrease left. Nonetheless, we additionally want it to get a bit of bigger, as if the moon is coming nearer to us in its orbit. As a result of each translation and scaling had been finished within the rework property, I can’t translate and scale the moon independently.

If we skip both one within the rework property, it resets the one we skipped, so I’m pressured to guess the place the mid-point must be in order that I can set the dimensions I would like. A method I’ve solved this up to now is so as to add a wrapping component, then apply scale to at least one component and translate to the opposite. Nonetheless, now that now we have particular person scale and translate properties, a greater means is to separate them from the rework property and use them as separate properties. Separating out the interpretation and scaling shouldn’t change something, until the unique order they had been declared on the rework property was totally different than the order of the singular properties.

#moon1 {
  animation: moon-one 12s infinite;
}

@keyframes moon-one {
  0%, 100% {
    translate: 0 0;
    scale: 1;
    z-index: 2;
    animation-timing-function: ease-in;
  }
  25% {
    translate: -3.5vw 3.5vw;
    z-index: 2;
    animation-timing-function: ease-out;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    translate: -5vw 6.5vw;
    scale: 1;
    z-index: -1;
    animation-timing-function: ease-in;
  }
  75% {
    translate: 1vw 2.5vw;
    scale: 0.25;
    animation-timing-function: ease-out;
  }
  99.9% {
    z-index: -1;
  }
}

Now that we are able to separate the scale and translate properties and use them independently, we are able to drop the translate property within the 25% and 75% keyframes as a result of we don’t need them positioned exactly in that keyframe. We wish the browser’s interpolation to deal with that for us in order that it interprets easily whereas scaling.

#moon1 {
  animation: moon-one 12s infinite;
}

@keyframes moon-one {
  0%, 100% {
    translate: 0 0;
    scale: 1;
    z-index: 2;
    animation-timing-function: ease-in;
  }
  25% {
    scale: 1.5;
    animation-timing-function: ease-out;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    translate: -5vw 6.5vw;
    scale: 1;
    z-index: -1;
    animation-timing-function: ease-in;
  }
  75% {
    scale: 0.25;
    animation-timing-function: ease-out;
  }
  99.9% {
    z-index: -1;
  }
}

Lastly, these totally different timing features don’t make numerous sense anymore as a result of we’ve acquired the browser working for us, and if we use an ease-in-out timing operate on the whole lot, then it ought to do precisely what we wish.

#moon1 {
  animation: moon-one 12s infinite ease-in-out;
}

@keyframes moon-one {
  0%, 100% {
    translate: 0 0;
    scale: 1;
    z-index: 2;
  }
  25% {
    scale: 1.5;
  }
  49.9% {
    z-index: 2;
  }
  50% {
    translate: -5vw 6.5vw;
    scale: 1;
    z-index: -1;
  }
  75% {
    scale: 0.25;
  }
  99.9% {
    z-index: -1;
  }
}

And there you go: 141 traces down to twenty-eight, and I feel the animation seems even higher than earlier than. It would definitely be simpler to keep up, that’s for certain.

However what do you suppose? Was there an optimization step I missed? Let me know within the feedback.

Tags: AnimationCSSKeyframesMechanicsOptimizedOrbital
Admin

Admin

Next Post
THPS 3+4 Devs Clarify Why They Eliminated 4’s OG Profession Mode

THPS 3+4 Devs Clarify Why They Eliminated 4's OG Profession Mode

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended.

Samsung Teases Extremely-Grade Foldable Cellphone With a ‘Highly effective Digital camera,’ AI Instruments

Samsung Teases Extremely-Grade Foldable Cellphone With a ‘Highly effective Digital camera,’ AI Instruments

June 4, 2025
Open Supply devs say AI crawlers dominate visitors, forcing blocks on whole nations

Open Supply devs say AI crawlers dominate visitors, forcing blocks on whole nations

March 26, 2025

Trending.

Industrial-strength April Patch Tuesday covers 135 CVEs – Sophos Information

Industrial-strength April Patch Tuesday covers 135 CVEs – Sophos Information

April 10, 2025
Expedition 33 Guides, Codex, and Construct Planner

Expedition 33 Guides, Codex, and Construct Planner

April 26, 2025
How you can open the Antechamber and all lever places in Blue Prince

How you can open the Antechamber and all lever places in Blue Prince

April 14, 2025
Important SAP Exploit, AI-Powered Phishing, Main Breaches, New CVEs & Extra

Important SAP Exploit, AI-Powered Phishing, Main Breaches, New CVEs & Extra

April 28, 2025
Wormable AirPlay Flaws Allow Zero-Click on RCE on Apple Units by way of Public Wi-Fi

Wormable AirPlay Flaws Allow Zero-Click on RCE on Apple Units by way of Public Wi-Fi

May 5, 2025

AimactGrow

Welcome to AimactGrow, your ultimate source for all things technology! Our mission is to provide insightful, up-to-date content on the latest advancements in technology, coding, gaming, digital marketing, SEO, cybersecurity, and artificial intelligence (AI).

Categories

  • AI
  • Coding
  • Cybersecurity
  • Digital marketing
  • Gaming
  • SEO
  • Technology

Recent News

Yoast AI Optimize now out there for Basic Editor • Yoast

Replace on Yoast AI Optimize for Traditional Editor  • Yoast

June 18, 2025
You’ll at all times keep in mind this because the day you lastly caught FamousSparrow

You’ll at all times keep in mind this because the day you lastly caught FamousSparrow

June 18, 2025
  • About Us
  • Privacy Policy
  • Disclaimer
  • Contact Us

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved

No Result
View All Result
  • Home
  • Technology
  • AI
  • SEO
  • Coding
  • Gaming
  • Cybersecurity
  • Digital marketing

© 2025 https://blog.aimactgrow.com/ - All Rights Reserved