Search code examples
csscss-animations

CSS animations with Spritesheets in a grid image (not in a row)


I'm trying to animate a sprite image, and found this great example:

Blog: http://simurai.com/blog/2012/12/03/step-animation/ (has succumbed to linkrot).
Wayback Machine: http://web.archive.org/web/20140208085706/http://simurai.com/blog/2012/12/03/step-animation/
Code Fiddle: 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'd like to do the same thing, but using a square (power-or-two sized) image atlas instead of an animation strip. For example, this one:

square image atlas


Solution

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

    I chose to do it as a rectangle animation over the full image.

    .hi {
        width: 320px;
        height: 315px;
        background-image: url("https://i.sstatic.net/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>

    Over the image, I display 2 pseudo elements, one is the row selector and the other the column selector. And I adjust the animations until they are ok


    Now, lets verify that setting both animations at the same time works:

    .hi {
        width: 320px;
        height: 315px;
        background-image: url("https://i.sstatic.net/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 now the final project:

    .hi {
      width: 53px;
      height: 53px;
      background-image: url("https://i.sstatic.net/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 a webkit browser, remove prefixes for IE and FF. Also, in this approach it is imposible to avoid displaying the 2 blank images at the lower left corner. If you don't have a full grid, and don't want to display the empty images, you will need to specify all the keyframes one by one