I have a spritesheet with a dice in it; 6 faces.
its face is 70 x 70 pixels
total sprite image is 70 x 420 pixels
now I want to make a CSS animation that goes from 1 to 6 (that's simple)
additionally I want to change the size; at 50% double it size and at 100% back to normal.
:local(.mydice)
{
width: 70px;
height: 70px;
background: url('/images/dices.png');
background-repeat: no-repeat;
background-position: 0px 0px;
background-size: 100% 600%;
animation: dicemove1 5s steps(6, end) infinite;
}
and then use keyframes to make the alterations:
#keyframes dicemove1
{
0% { background-position: 0px 0px;}
100% { background-position: 0px -420px; }
}
the above CSS snippet works.
but now adding the code to make it grows fails:
50% { width: 140px; height: 140px; margin-top: -35px; margin-left: -35px; background-position: 0px ???? }
I know background-position must be changed to support the bigger size but problem is I use steps because I don't want to scroll through the image but see it change from face to face (1,2,3,4,5,6)
dividing 100 by 6 doesn't result in a nice round integer which makes the 50% alteration a bit difficult.
Have been looking for keyframes that could handle steps as well but have not found such a thing.
Anyone knows a way to do this?
I found the solution.
transform: scale(2,2);
This will grow the dice.
Now I can use 2 animations simultaneously; 1 changing the face other resizing
animation: anim1 1s steps(6, end) infinite, anim2 1s steps(36, end) infinite;
#keyframes anim1
{
0% { background-position: 0px 0px; }
100% { background-position: 0px -600px; }
}
#keyframes anim2
{
50% { transform: scale(2,2); }
}
Related
I'm tryin to make a infinte animation but at some point it seems to hop back to the start.
Thats the code
h1 {
background: url(Pepesad.png) repeat-x;
width: 90%;
margin: 1em auto;
max-width: 600px;
height: 512px;
animation: flybirds 1s linear infinite;
}
#keyframes flybirds {
from {
background-position: 0px 0px
}
to {
background-position: 300px 0px
}
}
Some of the CSS rules you mentioned for h1 seems unnecessary for your purpose. Mentioning the width gives the animation very less space. Consider providing the h1 a container/ wrapper and set appropriate width for it.
h1 {
background: url(Pepesad.png) repeat-x;
height: 512px;
width: 5076px;
animation: flybirds 1s linear infinite;
}
Also in the keyframes you have mentioned the x-axis to 300px which cause the breaking effect during the animation. I suggest you update it
#keyframes flybirds {
from {
background-position: 0px 0px
}
to {
background-position: -100% 0px
}
}
Another alternative you could use is :
#keyframes flybirds {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-1692px, 0, 0);
}
}
Note: the reason why I suggest to use an additional at all, rather than animating background-position on h1, is so that we can use an animated transform to do the movement, which is much more performant.
I'm trying to animate a background image position smoothly with CSS over a longer period, let's say 60 seconds:
#movingbackground {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Bigsurflowers.jpg/1280px-Bigsurflowers.jpg');
overflow: hidden;
background-position: left center;
animation: zoomin 60s ease-in infinite;
}
#-webkit-keyframes zoomin {
0% { background-position: 0% center; transform: scale(1.0); }
50% {background-position: 100% center; transform: scale(1.2); }
100% { background-position: 0% center; transform: scale(1.0); }
}
#keyframes zoomin {
0% { background-position: 0% center; transform: scale(1.0); }
50% {background-position: 100% center; transform: scale(1.2); }
100% { background-position: 0% center; transform: scale(1.0); }
}
<div id="movingbackground"></div>
The small movements in the beginning and end are "jumping" a few pixel every second instead of moving slowly (may depend on screen size).
The reason for that is probably that there is not enough movement to fill the required number of frames, especially when the animation is eased. As I think I have seen this effect working smoothly somewhere I wonder how to work around this.
Here's a Fiddle as well.
Animation of background-position makes browser to do layout, paint and composite.
Re-layout and re-paint are heavy on CPU and cause "jumping".
Instead of that, you might apply your background to pseudo-element (or use <img> in your HTML) and animate its transform property using 3d transformation.
It will make browser to use GPU for the animation and animation will run in composition phase pretty smoothly.
See the snippet below:
html,
body {
margin: 0;
padding: 0
}
#movingbackground {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#movingbackground:before {
content: '';
position: absolute;
top: 0; left: 0; z-index: -1;
height: 100%;
width: 200%;
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Bigsurflowers.jpg/1280px-Bigsurflowers.jpg) 0 50% / cover;
animation: zoomin 60s ease-in infinite;
}
#keyframes zoomin {
50% {
transform: translateX(-50%) scale(1.2)
}
}
<div id="movingbackground"></div>
I did some testing and came to the conclusion that it's probably impossible. (At least with transitions or animations)
The problem is the way browsers render images on a screen. The pixels of the image apparently get lined up with those of your screen.
So the picture always "jumps" exactly one pixel at a time.
That means, that the more pixels you have in your image, the more steps it will make. But when using ease-in it will always stutter in the beginning.
As I think I have seen this effect working smoothly somewhere
That was probably not realized with css.
Im new to css animation, so I got this sequence movements picture online and want to make it walks. I follow a tutorial but it doesn't work in this case. I'm trying to make it moves. I don't know how to properly do that so I start with the first row of image. Its dimensions are 832x228.
and this is CSS code:
.sprite {
width: 130px;
height: 130px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
}
#keyframes walker {
0% {
background-position: 0 0;
}
100% {
background-position: 832px 0px;
}
}
<div class="sprite"></div>
You are on the right path but the background-position is wrong within the keyframes. Sprite images should move from the right to the left in order to produce a moving animation and so the background position should go from 0 0 to -832px 0.
.sprite {
width: 114px;
height: 114px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
/* image size is 832x228, so height is set as half of it */
}
#keyframes walker {
0% {
background-position: 0 0;
}
100% {
background-position: -832px 0px;
}
}
<div class='sprite'></div>
As mentioned in Robert C's answer, this will still not get the second row of images to show up. This is because the Y part of background-position doesn't change within the keyframes. The below snippet kindly contributed by Mishko Vladimir is one way to get them to display but problem is that if the no. of steps is increased to 16 (so as to show all sprites) then the animation doesn't work properly anymore.
Also, there will be a blink at the point where Y position changes. So, my recommendation would be to put all 16 sprites in the same row instead of two.
.sprite {
width: 114px;
height: 114px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
/*832x228*/
}
#keyframes walker {
0% {
background-position: 0 0;
}
50% {
background-position: -832px 0px;
}
51% {
background-position: 0 -114px;
}
100% {
background-position: -832px -114px;
}
}
<div class='sprite'></div>
Looks like you have the wrong background-position, it should be -832px rather than 832px. Note that with the above image you're also only going to get the top 8 frames, you'll need to edit the file to get the bottom 8 for a longer transition.
You may also want to adjust the time in your animation down to a fraction (I had a smoother walk with 0.9), and you'll want to shrink your width and height down to around 115px to avoid seeing some of the other frames.
This code is using more than 40% of my CPU on Chrome.
body {
-webkit-animation: swapwall 20s infinite;
-webkit-animation-timing-function:linear;
}
#-webkit-keyframes swapwall {
0%{background-image:url(img1.png);}
20%{background-image:url(img2.png);}
25%{background-image:url(img3.png);}
45%{background-image:url(img4.png);}
50%{background-image:url(img5.png);}
70%{background-image:url(img6.png);}
75%{background-image:url(img7.png);}
95%{background-image:url(img8.png);}
100%{background-image:url(img9.png);}
}
I don't understand why. Is there something wrong with the code? I tried adding hardware acceleration to the code but nothing changed. Is there anything I can do? Or some other way, that uses less CPU, that I can do to change background images with my css?
It seems I can just make a GIF to bypass this and use that as the background, but my images are 1920x1080 and all GIF makers are less than 500x500. I found one that created 1500x844, but it has no transition options.
Edit: I managed to create a 15 sec GIF from a video with the images, but it still consumes a huge amount of CPU and at a much lower quality.
Edit2: Possibly a Chrome issue?
body{background-color:#111111;}
#inlineContent {
pointer-events: none;
display: block !important;
}
#inlineContent:before {
position: fixed;
left: 0;
top: 0;
content: '';
width: 100%;
height: 100%;
background-image:
url(http://i.imgur.com/nncl4M8.png),
url(http://i.imgur.com/yc91VzR.png),
url(http://i.imgur.com/LjTST41.png);
animation: Falling 20s linear infinite;
-moz-animation: Falling 20s linear infinite;
-webkit-animation: Falling 20s linear infinite;
z-index: 102;
}
#keyframes Falling {
0% { background-position: 0 0, 0 0, 0 0; }
100% { background-position: 500px 1000px, 400px 400px, 300px 300px; }
}
#-moz-keyframes Falling {
0% {background-position: 0 0, 0 0, 0 0; }
100% {background-position: 500px 1000px, 400px 400px, 300px 300px;}
}
#-webkit-keyframes Falling {
0% { background-position: 0 0, 0 0, 0 0; }
100% { background-position: 500px 1000px, 400px 400px, 300px 300px; }
}
.Falling {
animation-name: Falling;
-moz-animation-name: Falling;
-webkit-animation-name: Falling;
}
http://scratchpad.io/impolite-harmony-1298
Tested on Chrome and Edge. Chrome: About 12% CPU usage, Edge: About 2% CPU usage.
It sounds as though you are just overloading it. 9 images at 1920x1080 is usually a pretty hefty weight. What is the total file size for those images? Have you compressed them? Do you have a link to a demo of your code so that I can look more closely at everything?
EDIT:
After some digging around I came across this answer: https://stackoverflow.com/a/13293044/3909886
The suggestion is to add transform: translateZ(0); to your class, which should then allow the browser you use the GPU acceleration.
EDIT2:
I believe that the issue is down to the pixel width of the images. When using the following code:
background-size: cover;
-webkit-animation: swapwall 5s infinite;
-webkit-animation-timing-function:linear;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform: translateZ(0);
margin: auto;
width: 500px;
height: 500px;
My cpu usage is down to 30%. I an only assume that the browser is struggling with the actual size of the images (number of pixels) that need updating on each swap.
I can't seem to get the animation timing right on this
http://codepen.io/anon/pen/ZYMgqE
.spinner {
width: 36px;
height: 36px;
background: url('http://i.imgur.com/CYiaWsF.png') top center;
animation: play 1s steps(10) infinite;
}
#keyframes play {
100% { background-position: 0px -2844px; }
}
I have tried numerous combinations, but it always comes out looking like a film reel.
Am I doing something wrong? Did I misunderstand CSS sprite animations?
Your math is off..I think.
The image is, apparently, 2844 px tall...so the number of steps should be the height divided by the element height
2844 / 36 = 79
.spinner {
width: 36px;
height: 36px;
background: url('http://i.imgur.com/CYiaWsF.png') top center;
-webkit-animation: play 1s steps(79) infinite;
animation: play 1s steps(79) infinite;
}
#-webkit-keyframes play {
100% {
background-position: 0px -2844px;
}
}
#keyframes play {
100% {
background-position: 0px -2844px;
}
}
<div class="spinner"></div>