animated linear gradient devouring CPU usage - css

I have an animation for alternating the body and change its background color. Everything works just fine, however when the animation runs I can see that my CPU is at 100%. At first I thought it might be due to #keyframes, however when I changed the code from alternating the colors, I saw a very critic CPU overload decrease, of an overwhelming constantly 40%. So I understood it might be due to animation.
Here's my CSS code:
body {
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706);
background-size: 600% 100%;
background-repeat: repeat;
background-attachment: fixed;
animation: gradient 16s linear infinite;
animation-direction: alternate;
}
#keyframes gradient {
0% {
background-position: 0%
}
100% {
background-position: 100%
}
}
Can someone help me?

Use transformation by considering pseudo element:
html::before {
content: "";
position: fixed;
z-index:-2;
top: 0;
left: 0;
width: 600%;
bottom: 0;
background: linear-gradient(45deg, #F17C58, #E94584, #24AADB, #27DBB1, #FFDC18, #FF3706);
animation: gradient 16s linear infinite alternate;
}
#keyframes gradient {
100% {
transform: translateX(-83.33%) /* 5/6x100% */
}
}

Related

Blur filter not working as intended (blur filter does not update to match gradient animation)

I am trying to create a text with a blurred background so it looks like the text has an aura. So far the code I have is
.testRainbow {
position:fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
z-index: 9999;
}
.testRainbow::before {
content:'';
position:fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 300px;
height:100%;
background: linear-gradient(90deg, #03a9f4, #f441a4, #ffeb3b, #03a9f4);
background-size: 400%;
-moz-animation: slideRainbow 8s linear infinite;
-webkit-animation: slideRainbow 8s linear infinite;
animation: slideRainbow 8s linear infinite;
-moz-filter: blur(1em);
-webkit-filter: blur(1em);
filter: blur(1em);
z-index: -1;
}
#keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
#-webkit-keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
#-moz-keyframes slideRainbow {
0% {
background-position: 0%;
}
100% {
background-position: 400%;
}
}
<h1 class='testRainbow'>test</h1>
I tested it and it works on Chrome, but it does not work on Safari. Further, I checked that it does not work on mobile Chrome, which is interesting because it works when I open Chrome from my desktop.
The linear gradient is changing as it is supposed to for all browsers, but for the ones that don't work, it seems the blur is not being updated. I checked that while I resize or zoom in, the blur updates to the current gradient. What needs to be changed? Thanks in advance.
EDIT
I fixed the problem, and ran into another problem. I added the filter: blur inside the keyframes as follows:
#keyframes slideRainbow (
0% {
background-position: 0%;
filter: blur(1em);
}
100% {
background-position: 0%;
filter: blur(1em);
}
}
I only have the rainbow gradient here, but there are 3 more colors in the css, and which color is shown is randomized. When the same color is selected twice or more in a row, the animation stops and I have a solid gradient behind the text. When another color is selected, the animation kicks back in.
It is supposed to look like this:
But being selected twice in a row, it becomes like this:

CPU Usage high for my CSS Animation. Can I use the GPU to lessen the burden?

I made the following Animation to play while the page is loading.
HTML
<div class="skeleton"></div>
CSS
#keyframes shimmerBackground {
0% { background-position: -468px 0 }
100% { background-position: 468px 0 }
}
.skeleton:empty{
width: 500px;
height: 40px;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
background: no-repeat #e4e3e3;
background-image: linear-gradient(to right, #e4e3e3 0, #c7c6c6 20%, #e4e3e3 40%, #e4e3e3 100%);
animation: shimmerBackground 1s linear infinite;
}
Here it is in action: https://jsfiddle.net/NuccioJohn/fx1wr8e6/
The animation correctly stops itself after the element is loaded with the data. But the hit to the CPU from Painting and Rendering is absolutely absurd.
I have been able to use other methods to lower the CPU usage significantly, but these methods do not work in IE 11 and having it work in IE is a must.
My instinct is that I should be able to use the GPU to do this animation, and that will lessen the burden this animation has on the GPU.
transform: translateZ(0);
Does anyone know how to rewrite this in a more efficient manner?
Maybe something like this will work? Instead of directly animating the background image, which requires a repaint for each frame, try using transform: translate3d() on a pseudo element. The included z-axis in translate3d() will force GPU rendering too!
#keyframes shimmerBackground {
0% { transform: translate3d(-400px, 0, 0) }
100% { transform: translate3d(900px, 0, 0) }
}
.skeleton:empty{
width: 500px;
height: 40px;
position: relative;
overflow: hidden;
background-color: #e4e3e3;
}
.skeleton:empty::before {
content: "";
display: block;
width: 400px;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: no-repeat #e4e3e3;
background-image: linear-gradient(to right, #e4e3e3 0, #c7c6c6 20%, #e4e3e3 40%, #e4e3e3 100%);
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation: shimmerBackground 1s linear infinite;
}

How to infinite zoom in and out smoothly with background image in CSS

The background image isn't smooth when it comes to animate it (some kind of blink) and I can't make it zoom from the image center.
This is for my personnal website I'm trying to make.
*{margin: 0;padding: 0;}
body
{
background-color: #0C090A;
background-image: url(../abstract-bg.png);
animation: zoom 30s infinite;
-webkit-animation: zoom 30s infinite;
}
#keyframes zoom {
0% {
background-size: 100%;
}
50% {
background-size: 105%;
}
100% {
background-size: 100%;
}
}
I would like to get the background image (which is 1920*1080) zoom slowly to 105% of it's original size (or something like that), and then go back to 100%. Also, if it's possible, make it zoom from the center, and not the top left corner. Thanks for those who can help.
yes of course you can :)
just add
background-position:center center;
background-repeat:no-repeat;
in the body css
and add
html{
height: 100%;
}
full css code:
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
background-color: #0C090A;
background-image: url(https://images.pexels.com/photos/556416/pexels-photo-556416.jpeg);
animation: zoom 30s infinite;
-webkit-animation: zoom 30s infinite;
background-position: center center;
background-repeat: no-repeat;
}
#keyframes zoom {
0% {
background-size: 100%;
}
50% {
background-size: 150%;
}
100% {
background-size: 100%;
}
}
you can test the code:
https://playcode.io/358401
It's choppy because the animation duration is too long for 5% of the width of the image. either increase the size or decrease the duration of the animation or use a bigger image.
Or you can use scale() which make use of the GPU i believe, However this time we won't be using the image as a background.
body{
overflow-x:hidden;
}
img {
transform-origin: center center;
animation: zoom 30s infinite;
max-width: 100%;
}
#keyframes zoom {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
/* equals 105% */
}
100% {
transform: scale(1);
}
}
<img src="https://picsum.photos/id/238/1920/1080">

CSS3 - Animating a sprite-grid

I've been trying to understand the CSS animation property, I've got this sprite gridsheet I need to run through, I've seen examples of Animations both in row and grid style, but when I try to apply and adapt to my sprite sheet I'm having issues with the display.
Here is my current CSS & Html:
.logo {
width: 120px;
height: 100px;
margin: 2% auto;
background: url('http://res.cloudinary.com/df0nhzq7v/image/upload/v1484325835/bvd2_1024_fxwhvl.png') left top;
-webkit-animation: playv .6s steps(6) infinite, playh 1s steps(6) infinite;
}
#-webkit-keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 100%; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0px; }
100% { background-position-x: 100%; }
}
<div class="logo"></div>
Codepen: http://codepen.io/BenSagiStuff/pen/ZLOJKM
There's a couple issues at play here. The first is that your animation property has the incorrect values. You need to change it from:
animation:
playv .6s steps(6) infinite,
playh 1s steps(6) infinite;
to:
animation:
playv 5s steps(5) infinite,
playh 1s steps(7) infinite;
It's important that the steps function takes in the correct parameters, such that playv is contains the number of sprites there are in the y direction and playh contains the number of sprites there are in the x direction. The timing for playv also needs to be slow enough to animate the grid properly and is actually equivalent to being your duration multiplied by the amount of rows in the sprite grid. This can be simplified into the following formula:
animation:
playv (duration * rows) steps(rows) infinite,
playh duration steps(cols) infinite;
Secondly, the image you have provided as the sprite grid is too large. It contains blank space/padding to the right and bottom of the image. As a result of this, the following lines are calculated incorrectly:
#-webkit-keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 100%; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0px; }
100% { background-position-x: 100%; }
}
You either need to update the sprite grid so that it matches perfectly, or specify the pixels exactly like so:
#-webkit-keyframes playv {
0% { background-position-y: 0; }
100% { background-position-y: -550px; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0; }
100% { background-position-x: -903px; }
}
Here's the working codepen.

Percentage background-position working erratically (except on Chromium)

The following image is to be used in a keyframes animation by moving the background-image position 100% to the right on each frame:
The idea is that the ArrowsAnim.png has 7 frames of the same image (the set of 3 chevrons pointing to the right) in different animation states. The animation arrowAnimation (CSS below) simply skips through background-position 0% to 300% to show the first three frames of this image over 0.5 seconds, repeatedly.
What's happening is that when I resize the browser window, I can sometimes see some pixels of the next or previous frame of the animation, instead of having the background perfectly centered around whichever should be the current block, as you can see in the next picture:
So for some reason, background-position is not being calculated correctly.
I also cannot reproduce this issue on Chromium, but I can do so on Chrome, Firefox and Edge.
CSS:
#autoplay-arrow {
display: inline-block;
position: absolute;
width: 5.91549%;
top: 22.05882%;
height: 50.74627%;
margin-left: 18.30986%;
background-size: 100% 100%;
background-position: 0 0;
background-image: url(../graphics/Arrows_002.png);
}
#-moz-keyframes arrowAnimation {
from {
background-position: 300% 0%;
}
to {
background-position: 0% 0%;
}
}
#-webkit-keyframes arrowAnimation {
from {
background-position: 300% 0%;
}
to {
background-position: 0% 0%;
}
}
#keyframes arrowAnimation {
from {
background-position: 300% 0%;
}
to {
background-position: 0% 0%;
}
}
#autoplay-arrow.anim {
background-image: url(../graphics/ArrowsAnim.png);
background-size: 700% 100%;
-moz-animation: arrowAnimation 0.5s steps(3) infinite;
-webkit-animation: arrowAnimation 0.5s steps(3) infinite;
animation: arrowAnimation 0.5s steps(3) infinite;
}

Resources