CSS animation using sprites in a grid image (not in a row)

I am trying to animate a sprite image and found this great example:

Blog: http://simurai.com/blog/2012/12/03/step-animation/ (succumbed to linkrot).
Wayback Machine: http://web.archive.org/web/20140208085706/http://simurai.com/blog/2012/12/03/step-animation/
Fiddle Code: https://codepen.io/simurai/pen/tukwj

JSFiddle: http://jsfiddle.net/simurai/CGmCe/

.hi { width: 50px; height: 72px; background-image: url("http://s.cdpn.io/79/sprite-steps.png"); -webkit-animation: play .8s steps(10) infinite; -moz-animation: play .8s steps(10) infinite; -ms-animation: play .8s steps(10) infinite; -o-animation: play .8s steps(10) infinite; animation: play .8s steps(10) infinite; } 

@ - webkit-keyframes play {from {background-position: 0px; } to {background-position: -500px; }}

@ - moz-keyframes play {from {background-position: 0px; } to {background-position: -500px; }}

@ - ms-keyframes play {from {background-position: 0px; } to {background-position: -500px; }}

@ - o-keyframes play {from {background-position: 0px; } to {background-position: -500px; }}

@keyframes play {from {background-position: 0px; } to {background-position: -500px; }}

I would like to do the same, but use a square (power or two size) image atlas instead of an animation strip. For example, this:

square image atlas

+6
source share
3 answers

Since this can be a difficult debugging task, I would like to start with the same problem, but in an easier debugging environment.

I decided to do this as an animation of the rectangle above the full image.

 .hi { width: 320px; height: 315px; background-image: url("http://i.stack.imgur.com/CjMscm.jpg"); position: relative; border: solid 1px black; } .hi:before { content: ""; position: absolute; width: 100%; height: 53px; left: 0px; top: 0px; border: solid 1px red; -webkit-animation: playv 18s steps(6) infinite; } @-webkit-keyframes playv { 0% { top: 0px; } 100% { top: 315px; } } .hi:after { content: ""; position: absolute; width: 53px; height: 100%; left: 266px; top: 0px; border: solid 1px red; -webkit-animation: playh 3s steps(6) infinite; } @-webkit-keyframes playh { 0% { left: 0px; } 100% { left: 320px; } } 
 <div class="hi"> </div> 

In the image, I show 2 pseudo elements, one is a row selector and the other is a column selector. And I tweak the animation until they are ok


Now let's verify that setting both animations at the same time works:

 .hi { width: 320px; height: 315px; background-image: url("http://i.stack.imgur.com/CjMscm.jpg"); position: relative; border: solid 1px black; } .hi:before { content: ""; position: absolute; width: 53px; height: 53px; left: 0px; top: 0px; border: solid 1px red; -webkit-animation: playv 18s steps(6) infinite, playh 3s steps(6) infinite; } @-webkit-keyframes playv { 0% { top: 0px; } 100% { top: 315px; } } @-webkit-keyframes playh { 0% { left: 0px; } 100% { left: 320px; } } 
 <div class="hi"> </div> 


And here is the final draft:

 .hi { width: 53px; height: 53px; background-image: url("http://i.stack.imgur.com/CjMscm.jpg"); position: relative; border: solid 1px black; -webkit-animation: playv 1s steps(6) infinite, playh 0.1667s steps(6) infinite; animation: playv 1s steps(6) infinite, playh 0.1667s steps(6) infinite; } @-webkit-keyframes playv { 0% { background-position-y: 0px; } 100% { background-position-y: -315px; } } @-webkit-keyframes playh { 0% { background-position-x: 0px; } 100% { background-position-x: -320px; } } @keyframes playv { 0% { background-position-y: 0px; } 100% { background-position-y: -315px; } } @keyframes playh { 0% { background-position-x: 0px; } 100% { background-position-x: -320px; } } 
 <div class="hi"> </div> 

All this for the webkit browser, remove the prefixes for IE and FF. In addition, in this approach, it is impossible to avoid displaying two blank images in the lower left corner. If you do not have a full grid and you do not want to display blank images, you will need to specify all key frames one at a time

+21
source

Use the background-position-x and background-position-y properties instead.

For this image

preview

size 710 × 355 pixels

The size of the sprite frame is 118.333px X 118.333px, and we need to move 6 frames horizontally and 3 frames vertically.

This means that we need to create two separate animations of key frames to go through each direction. When the animation in the x direction is turned on, others should freeze until it completes.

Also, the animation duration should be 3 times.

Here is the code

 <div class="hi"></div> .hi { width: 118.333px; height: 118.333px; background-image: url("http://www.fore6.com/wp-content/uploads/2011/09/henson11-hp-1g.png"); animation: playX 1s steps(6) infinite, playY 3s steps(3) infinite; } @keyframes playX { from {background-position-x: 0px;} to {background-position-x: -710px;} } @keyframes playY { from {background-position-y: 0px;} to {background-position-y: -355px;} } 

the violin is here

+2
source

To understand how this works, here is a general solution with SCSS in addition to the answer given by @vals: jsfiddle link

SCSS:

 // Variables to edit $imgUrl: 'https://mrbubblewand.files.wordpress.com/2009/08/magic_001.png'; $imageWidth: 960px; $imageHeigth: 1152px; $itemNbColumns: 5; $itemNbLines: 6; $spriteAnimationTime: 1s; // ======================================= $squareWidth: $imageWidth / $itemNbColumns; $squareHeigth: $imageHeigth / $itemNbLines; // ======================================== .square { width: $squareWidth; height: $squareHeigth; background-image: url($imgUrl); position: relative; border: solid 1px black; -webkit-animation: playvsquare $spriteAnimationTime*$itemNbColumns*$itemNbLines steps($itemNbLines) infinite, playhsquare $spriteAnimationTime*$itemNbColumns steps($itemNbColumns) infinite; } @-webkit-keyframes playvsquare { 0% { background-position-y: 0px; } 100% { background-position-y: -$imageHeigth; } } @-webkit-keyframes playhsquare { 0% { background-position-x: 0px; } 100% { background-position-x: -$imageWidth; } } // ======================================= .sprite { width: $imageWidth; height: $imageHeigth; background-image: url($imgUrl); position: relative; border: solid 1px black; } .sprite:before { content: ""; position: absolute; width: 100%; height: $squareHeigth; /* taille du carré */ left: 0px; top: 0px; border: solid 1px red; -webkit-animation: playvsprite$spriteAnimationTime*$itemNbColumns*$itemNbLines steps($itemNbLines) infinite; } .sprite:after { content: ""; position: absolute; width: $squareWidth; height: 100%; left: $squareWidth; top: 0px; border: solid 1px red; -webkit-animation: playhsprite $spriteAnimationTime*$itemNbColumns steps($itemNbColumns) infinite; } // Déplacement @-webkit-keyframes playvsprite { 0% { top: 0px; } 100% { top: $imageHeigth; } } // Déplacement @-webkit-keyframes playhsprite { 0% { left: 0px; } 100% { left: $imageWidth; } } 

HTML:

 <p>Square :</p> <div class="square"></div> <p>Entire sprite :</p> <div class="sprite"></div> 
0
source

All Articles