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.
Related
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); }
}
I have a spritesheet (9170px x 350px) that has 70 frames of a single character. Here's my code.
#-webkit-keyframes play {
100% {
background-position: -9170px;
}
}
#keyframes play {
100% {
background-position: -9170px;
}
}
.character-one {
width: 131px;
height: 350px;
border: 1px solid #ddd;
margin-left: 20px;
background: url('http://i.imgur.com/gK3C2VZ.png') left center;
-webkit-animation: play 2s steps(70) infinite;
animation: play 2s steps(70) infinite;
}
<div class="character-one"></div>
When I open it in the browser, I see the character getting animated, but the spritesheet moves from right to left inside the div that's there. What could the reason be? I figured that normally happens when the steps() are fewer than the number of frames, but in my case everything seems to be OK. Could it be that the frames are not evenly spaced?
Here's the link to the JSFiddle
Though your actual sprite-sheet is 9170px wide, the individual sprites within it actually have a margin on either side. This is what is causing the sliding effect.
As per your code, there are 70 steps and the background moves by 9170px (which is 131px for each step). But each 131px of the sprite don't seem to exactly overlap one another. In the below image, we can see how the first 131px of the spritesheet and the last 131px look like (background added just for visual distinction).
Changing the background-position like in the below snippet seems to produce a much better output.
#-webkit-keyframes play {
100% {
background-position: -9144px;
}
}
#keyframes play {
100% {
background-position: -9144px;
}
}
.character-one {
width: 131px;
height: 350px;
border: 1px solid #ddd;
margin-left: 20px;
background: url('http://i.imgur.com/gK3C2VZ.png');
background-position: -28px center;
-webkit-animation: play 2s steps(70) infinite;
animation: play 2s steps(70) infinite;
}
<div class="character-one"></div>
In the below sprite-sheet, we can see how there is equal spacing on all sides for each sprite image. It is taken from the Tree House blog on CSS Sprite Sheet Animations.
Sprite images are wrong sliced, distance is vary in all images. Please update sprite images then problem is solved.
I have the following code:
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('/media/anim.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
#keyframes bganim {
from { background-position: 0px 0px; }
to { background-position: 0px -72px; }
}
But the animation is only playing once. What am I doing wrong?
EDIT: Note that the animation plays out once, so there is a visual difference. But I want the animation to loop.
Btw: Here is the picture I used: http://i.imgur.com/fA80qQc.png
2nd EDIT: Here is the code snippet
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
#keyframes bganim {
from { background-position: 0px 0px; }
to { background-position: 0px -72px; }
}
<div class="dangerous_b"></div>
3rd EDIT: It's working now with the following code:
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 100ms steps(1, start) infinite;
}
#keyframes bganim {
50% { background-position: 0px -72px; }
}
Reason:
Problem is because of the animation-timing-function. A value of steps(1,start) means that the animation has only one step and it happens right at the start of the animation itself.
As per MDN (picked from definition for step-start but it is same as steps(1, start)):
Using this timing function, the animation jumps immediately to the end state and stay in that position until the end of the animation.
First step of the first iteration happens as soon as the page is loaded (or class is added) and due to it, the background image immediately moves to the position indicated inside the to frame. For the 2nd iteration, the move back to its original position (from frame) and then to the final position (to frame) again happens instantaneously meaning that you don't get to see any visual difference and it looks as though the element is staying at its place without any animation.
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(1, start) infinite;
}
#keyframes bganim {
from {
background-position: 0px 0px;
}
to {
background-position: 0px -72px;
}
}
<div class='dangerous_b'></div>
The same behavior can be seen in this fiddle also. This is not my creation but is an adaptation of the demo present as designmodo. The first car never actually moves (or is never actually seen to move) because the step happens right at the start.
Solution 1: Use two steps and double the ending background position
When the no. of steps is set to two, the animation happens as a two step process where the first step again happens at the start of the animation (because of start parameter). This means:
During the first step, the background moves to half distance between the start and the end state.
Since 1st step happens right at the start, background-position is never 0px 0px. (Do note that, I have doubled the end background-position).
In the 2nd step, the background moves to the final position. Because the background images are repeated, 0px -144px is equal to 0px 0px. This creates an illusion of the background moving to its original position.
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(2, start) infinite;
}
#keyframes bganim {
from {
background-position: 0px 0px;
}
to {
background-position: 0px -144px;
}
}
<div class='dangerous_b'></div>
Solution 2: Use just one step but change the end position to half way
For some reason, this seems to mimic a two step animation.
In the first half, the background moves to the position indicated within 50% frame.
During second half, it seems to go back to the original position (or 100% position, both of which are the same). Thus when next iteration starts and the image jumps, it moves from 0% or 100% position to 50% position and ends up producing the required animation effect.
.dangerous_b {
width: 636px;
height: 72px;
background-image: url('http://i.imgur.com/fA80qQc.png');
float: left;
background-color: black;
animation: bganim 1s steps(1, start) infinite;
}
#keyframes bganim {
0% {
background-position: 0px 0px;
}
50% {
background-position: 0px -72px;
}
100% {
background-position: 0px 0px;
}
}
<div class='dangerous_b'></div>
If I understand it correctly, it now takes 1 frame to run your animation.
Since your background image is moving out of sight, you won't see it.
https://developer.mozilla.org/nl/docs/Web/CSS/timing-function#The_steps()_class_of_timing-functions
trying to follow the blog post treehouse tutorial and coded everything pretty much like the tutorial said but my animation wont start or work. My little image shows up fine and its a 490 x 110 sprite sheet. The code im using is the following:
.ken {
width: 70px;
height: 110px;
background: url('/imgs/ken-shoryuken.png') left center;
animation: play 1.5s steps(7) infinite;
}
#keyframes play {
100% { background-position:-490; }
}
And it is positioned by a simple dive which is showing up fine, its just the animation wont work for some reason, any thoughts?
You need to specify an absolute length unit, keyword or percentage for background-position:
#keyframes play {
100% { background-position:-490px; }
}
[Background position] Syntax
background-position: top;
background-position: bottom;
background-position: left;
background-position: right;
background-position: center;
background-position: 25% 75%;
background-position: 0px 0px, center;
I have a background which exists of 3 images in total. However the middle background image (wrapper2) is visually 'between' two background images (wrapper1 and wrapper2).
When I try to rotate that middle image (wrapper2), the top-most image (wrapper3) also moves.
How can I prevent this, so that only the middle background-image (wrapper2) can rotate and not also the other one (wrapper3)?
<div id="wrapper1">
<div id="wrapper2">
<div id="wrapper3">
<!-- blabla -->
</div>
</div>
</div>
#wrapper1 {
background-image: url("../media/bg1.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper2 {
background-image: url("../media/bg2.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper3 {
background-image: url("../media/bg3.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper2:hover
{
animation: TestAnim;
animation-iteration-count: infinite;
animation-duration: 10s;
}
#keyframes TestAnim
{
0% { transform:rotate(0deg); }
25% { transform:rotate(-4deg); }
100% { transform:rotate(0deg); }
}
}
ok, wasn't possible the way I worked.
I could either position the divs (absolute/relative) and make them siblings instead of childs.
But i've choosen to create a sprite image of all the rotations that I wanted and using an css3 animation.
In the CSS keyframes animation I move the background position every time:
0% { background-position: 0 0; width: 300px; height: 200px; }
1% { background-position: 0 -200px; width: 300px; height: 200px; }
...
Important is that you have to define the step-start!
animation-timing-function: step-start;
This step-start works fine in Internet Explorer 10.
Remark: For older browsers, the animation will not work (CSS3 is not known or step-start is not known) and your first sprite will be displayed, so make sure your first sprite is your initial state.
For your information: I used The GIMP to create my animation and used a plugin called CSS WebSprites to automatically generate my sprites and CSS code:
The GIMP CSS WebSprites plugin