I'm working on a CSS3-based animation, where I have a div that has a linear-gradient as the background, and then I use a PNG as the mask using the -webkit-mask-image property.
To make it animated, I want to move the mask on top of the gradient. It's working fine and looks gorgeous, but my issue is it kinda kills the CPU.
Here's the animation:
#keyframes moveMask {
0% { -webkit-mask-position: 0px 0px;}
100% { -webkit-mask-position: 2000px 0px; }
}
And I'm calling it using this:
animation: moveMask 200s linear infinite alternate;
I've tried to add the following trick, but it didn't change anything:
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
Any idea on how I can optimize it?
As Rich Bradshaw pointed out, I think you will find that it's just not very well optimized. To achieve a similar sort of effect though, you could create an animated GIF, double the canvas size, and then place a static version of the GIF on every frame of the other half of the canvas. That way, the animation would always be playing invisibly in the background and you'd just switch to it by changing the position of the image whenever you wanted to show the animated version.
A problem with this technique is that the animation won't necessarily start at the beginning when you trigger it. That may or may not be important for your particular animation.
Related
I have realized that CSS animations with keyframes are really hungry for resources.
I've already eliminated the shadows, which increased performance by almost 50% in my case. I've also heard that I should include a rotateZ(360deg) to trick the browser into using GPU acceleration. But even with those "tricks" applied, my star background is really resource-hungry. As soon as you open my website, CPU and GPU usage goes up drastically and remains at a pretty high level.
I'm wondering if there is a better way to perform my desired animation without wasting so much CPU or GPU power.
I wanted a background of moving stars on my website. My solution to this was to create a div for each star, giving it a size, background colour and CSS animation with keyframes. The opacity, x and y position, as well as the speed of the animation are randomized.
The keyframes are the following:
#keyframes linear-translate {
0% {
left: -10%;
transform: rotateZ(360deg); /* rotateZ tricks the browser to use GPU acceleration for better performance */
}
100% {
left: 110%;
}
}
#keyframes linear-translate-initial {
0% {
transform: translateX(0) rotateZ(360deg);
}
100% {
left: 110%;
}
}
Here is an example for one of the div elements (with tailwind CSS classes):
<div class="absolute block bg-gray-200 rounded-full"
style="left: 1%; top: 8%; width: 3px; height: 3px; opacity: 0.381289;
animation: 90.0069s linear 0s 1 normal none running linear-translate-initial,
110.007s linear 90.0069s infinite normal none running linear-translate;"></div>
Link to codesandbox with a working example:
https://codesandbox.io/s/starbackgroundreacttailwindcss-wzers?file=/src/Starfield.tsx
Any ideas on why those animations are consuming so much power and on how to make them more efficient? It's just a horizontal translation after all...
Update:
I tried to layer the stars in div elements of different speeds as suggested by Marco.
My result can be found here:
https://codesandbox.io/s/layeredstarbackgroundreacttailwindcss-wj71q?file=/src/App.tsx:392-445
Unfortunately, the "improvement" is not that great. The CPU usage went a little down, but the GPU usage increased drastically.
I've played around a bit with your sandbox and yes the solution is that simple - there are just to many / different animations / items to handle for the CPU you can see that easily when opening the task manager and checkout the CPU usage while the sandbox is idle with your page. On my "small" machine Firefox uses up to 53% CPU. when i decrease the amount of stars in your script (down to 10) it goes down to around 18%.
I had a similar problem with a "moving div" background with shadows / gradient colors and rotations while moving from left to right...
Interesting project so far.
An idea might be to have a limited amount of layers with multiple stars fixed there and then to move the whole layer (even if you have 10 layers then there are just 10 objects that moves)...
Yes you will not have the same strong effect like calculating / moving each star by its own but with 10 layers as a background (i think its a Background right?) it should not make any markable difference to the viewer...
I am currently faced with a situation, for which I need to constantly render a flickering animation within a web page. This is currently done by means of CSS, using animation: 0.05s step-end infinite keyframe_name. The keyframe changes the button's background-color at 0% and 50%. As can be expected, using Chrome's Dev tools, this area is constantly being re-painted by the browser, which is leading to an overall poor performance.
I am aware that the use of certain properties, such as the will-change property, or even using the transform: translate3d(0, 0, 0) hack, will enable hardware accelerated rendering. However, opting for either of these options, still hasn't resulted in the desired performance improvement.
The following shows some basic code for what I am trying to achieve (optimizations are not included in code snippet):
#keyframes keyframe_name
{
0% { background-color: red; }
50% { background-color: blue; }
}
button
{
animation: 0.05s step-end infinite keyframe_name;
}
According to a number of online resources, it seems that only the transform and opacity CSS properties make it possible for the browser to optimize compositing. Since neither of these properties can be used to achieve my desired goals, which other approach/es could possibly lead to a performance enhancement, when it comes to the in-browser rendering of such a resource-intensive graphic?
i'm trying to apply a css animation to the root element of a page and it's behaving strangely. you can see it here: http://dinakelberman.com/bucket/circle-test.html
html {
display:block;
transition-duration:1.5s;
background:#E3DCB1;
background-image:url(http://vignette.wikia.nocookie.net/leapfrog/images/b/be/Yellow_Circle.png/revision/latest?cb=20180115233859);
background-size:100%;
animation:rotate 0.5s linear infinite;
}
#keyframes rotate {
0% {transform:rotateY(0deg) rotateX(0deg);}
100% {transform:rotateY(360deg) rotateX(360deg);}
}
in chrome & opera the animation progresses only when the mouse moves
in safari it animates on its own as expected
in firefox it doesn't animate at all
i don't need a solution as to how to make this animation visible by using other elements, i know this is a weird and wrong way to do things.
i'm doing some experimental work where i'm trying to deal exclusively with the root element. i don't really dislike the behaviors but ideally i'd like the results to be the same across browsers so i'm curious about how they're handling this differently.
I created a path in illustrator and then used some CSS in order to animate it. The svg animation works just fine in Chrome and Firefox, However, for a strange reason in safari it's animated backwards! The site is http://www.rw.limdez.eu and is located on the very top banner of the website. You can see it as soon as you click the link! You can only see this on desktop since for mobile it redirects you to the mobile version of the page! This is the CSS I used:
.smallline
{
stroke-dasharray:692;
stroke-dashoffset:-692;
animation-delay: 1s!important;
animation: draw-smallline 8s 1 forwards;
}
#-webkit-keyframes draw-smallline
{
0%{
stroke-dashoffset: -692;
}
100%
{
stroke-dashoffset:0;
}
}
Note1: I also tried it without #-webkit- but i have the exact same results!
Note2: I have seen other very similar questions to mine in stack-overflow but none of them were answered. Not in a way that solves my problem at least! Thank you.
Negative works fine in Safari.
Instead of:
stroke-dasharray:692;
You should use:
stroke-dasharray:692 692;
This was fixed by changing the 0% dashoffset from -692 to 692! If i am not mistaken this occurred because safari does not deal efficiently with negative values!
I have a background image set in HTML, using CSS, the image is a full size background image, covering all of the web page. What I'd like to do is have the image zoom in and out automatically in the backround without any user interaction.
Here's a gif explaining what I'd like to achieve;
Image Link: (As it is a .gif)
Any ideas on how I would do this? I'm imagining it would be some sort of JQuery Plugin, I'm not the greatest at JQuery though so any and all help would be greatly appreciated!
Thanks!
First of all, please don't do this, it's a sure fire way of driving people away from your site!
Having said that, you can achieve what you're looking to do with CSS alone, without any JavaScript, by applying an animation to the background-size property of your body tag (or whichever element you're using), like so:
body{
-webkit-animation:zoom 5s infinite;
animation:zoom 5s infinite;
background:url(https://picsum.photos/1900/1900/?random) center center fixed no-repeat;
}
#-webkit-keyframes zoom{
0%,100%{
background-size:100%;
}
50%{
background-size:125%;
}
}
#keyframes zoom{
0%, 100%{
background-size:100%;
}
50%{
background-size:125%;
}
}
You can tweak the animation settings to suit your needs and you may also need to use more vendor prefixes than I've provided, depending on the level of browser support you're aiming for. See caniuse.com for browser compatibility tables.