
Posted on • Originally published atcodinhood.com
Animate an Octocat Sprite Swimming with CSS
Animating DOM and SVG elements with CSS using the@keyframes
rule andanimation
property is usually pretty straightforward. Elements generally animate smoothly from a starting value to an ending value and all the values in between. While this works great for DOM and SVG elements, sprite images animate by displaying different images quickly in succession rather than slowly transitioning from one value to another. This article will demonstrate one technique to animate sprites with CSS by animating an Octocat sprite swimming in the ocean. Checkout the Codepen below to see the completed project.
Using Sprites with CSS
Sprite images are a collection of smaller images within a single image. To show any particular image within the collection of images, you need to specify the position and size of that particular image. For example, to show Octocat going to the right (the third image) in the following sprite image we need to specify the width of the image as200px
, the height as300px
, and the position on the image asx: 400
andy: 0
.
In CSS, we can achieve this by setting the image as a background image on an element. If we set the height and width to size of the whole sprite image then we'll see all the frames.
.Octocat{height:300px;width:800px;background:url(./octocat.png)leftcenter;}
But we only want to show one frame at a time, so change the width to size of one frame.
.Octocat{height:300px;width:200px;background:url(./octocat.png)leftcenter;}
This shows the first frame because the position of the sprite image is atx: 0
andy: 0
. If we want to show the third frame we can change the sprite image position using the CSS propertybackground-position
. The position of the third frame isx: 400px
on the sprite image, but a positive value forbackground-position
pushes an image toright which means the position on the image will be-400px
. Flipping the value around to-400px
will push the image to theleft and reach position400px
on the sprite image.
.Octocat{height:300px;width:200px;background:url(./octocat.png)leftcenter;background-position:-400px0px;}
Animating One Step Sprites with CSS
Animating sprites in CSS, at its core, is simply changing thebackground-position
to the appropriate frame within the sprite image at the appropriate time. The problem is that normal CSS animation animates the transition from one value to another rather than immediately switching to a new value. For example, say we want to animate Octocat from frame one to frame two with a normalease
orlinear
animation.
.Octocat{height:300px;width:200px;background:url(./octocat.png)leftcenter;animation:upAndDown5seaseinfinite;}@keyframesupAndDown{0%{background-position:0px;}50%{background-position:-200px;}100%{background-position:0px;}}
To animate sprites we need to use thesteps()
animation-timing-function instead. Essentially we need to jump from one frame to another and that's exactly what thesteps
function does in CSS. The value passed intosteps()
represents how many steps the animation should show on the way to the provided value. For example, if we animate from0
to100
and pass 2 tosteps
, then the animation will show the element at50
and100
. Sprite animations with more frames require more steps, in our case we only have two frames, for showing up and down movement, so we only need one step to transition between the two frames.
.Octocat{height:300px;width:200px;background:url(./octocat.png)leftcenter;animation:upAndDown2ssteps(1)infinite;}@keyframesupAndDown{0%{background-position:0px;}50%{background-position:-200px;}100%{background-position:0px;}}
Moving Sprites Around the Page with CSS
Thesteps()
function is great for animating sprites but if we want to move the image around the screen smoothly then we need to use another timing function likeease
orlinear
. We will need to define another@keyframes
rule and add a second animation to the element to use different timing function.
First, we want to animate the sprite up and down using a transform. The sprite will start below the middle position,
transform:translate(0px,100px);
and then animate up pass the midpoint,
transform:translate(0px,-100px);
and finally animate back down to the starting position:
transform:translate(0px,100px);
To give the illusion of sinking slowly we animate quickly up, from0%
to40%
, and animate slower downwards, from40%
to100%
.
@keyframesswim{0%{transform:translate(0,100px);}40%{transform:translate(0,-100px);}100%{transform:translate(0,100px);}}
We also need to update the sprite transtion animation. At the start, Octocat is at the very bottom of the animation which means he needs to be the first frame. But theswim
animation above will immediately start animating him straight up to-100px
, which means we need to immediately switch the frame to the up frame, frame 2. To do this we set thebackground-position
to-200px
at1%
.
When Octocat is at the very top of the animation, which is at40%
, we need to switch his frame back to the original frame. Again we want to do thisafter he's reached the end of the movement so we reset his frame at41%
, instead of40%
. Next, we need to make sure he stays at his first frame all the way back down to the original position by setting100%
to the same position.
@keyframesupAndDown{0%{background-position:0;}1%{background-position:-200px;}41%{background-position:0;}100%{background-position:0;}}
Finally, we can update the element with both animations by comma separating them.
#octocat{height:300px;width:200px;background:url("./octocat.png")leftcenter;animation:upAndDown5ssteps(1)infinite,swim5seaseinfinite;}
Extending this pattern further we can create more complicated animations like the one in the Codepen at the top of the article or even tie these sprites to keyboard input.
Conclusion
Animating sprite images in CSS, while not exceedingly difficult, requires a few tricks to get working correctly. If you'd like to play around with sprites in CSS you can download the Octocat sprite my friend made below or search online for thousands of free sprite images.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse