29

First of all,check out this image
wink
Gmail uses this image to display the animated emoticon.
How can we show such animation using a png image?

Community
  • 1
  • 1
Rakesh Juyal
  • 35,919
  • 68
  • 173
  • 214

6 Answers6

71

I leave you a rough example so you can get a starting point:

I will use a simple div element, with the width and height that the animated image will have, the png sprite as background-image and background-repeat set to no-repeat

CSS Needed:

#anim {
  width: 14px; height: 14px;
  background-image: url(https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png);
  background-repeat: no-repeat; 
}

Markup needed:

<div id="anim"></div>

The trick is basically to scroll the background image sprite up, using the background-position CSS property.

We need to know the height of the animated image (to know how much we will scroll up each time) and how many times to scroll (how many frames will have the animation).

JavaScript implementation:

var scrollUp = (function () {
  var timerId; // stored timer in case you want to use clearInterval later

  return function (height, times, element) {
    var i = 0; // a simple counter
    timerId = setInterval(function () {
      if (i > times) // if the last frame is reached, set counter to zero
        i = 0;
      element.style.backgroundPosition = "0px -" + i * height + 'px'; //scroll up
      i++;
    }, 100); // every 100 milliseconds
  };
})();

// start animation:
scrollUp(14, 42, document.getElementById('anim'))

EDIT: You can also set the CSS properties programmatically so you don't have to define any style on your page, and make a constructor function from the above example, that will allow you to show multiple sprite animations simultaneously:

Usage:

var wink = new SpriteAnim({
  width: 14,
  height: 14,
  frames: 42,
  sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png",
  elementId : "anim1"
});

var monkey = new SpriteAnim({
  width: 18,
  height: 14,
  frames: 90,
  sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/monkey1.png",
  elementId : "anim4"
});

Implementation:

function SpriteAnim (options) {
  var timerId, i = 0,
      element = document.getElementById(options.elementId);

  element.style.width = options.width + "px";
  element.style.height = options.height + "px";
  element.style.backgroundRepeat = "no-repeat";
  element.style.backgroundImage = "url(" + options.sprite + ")";

  timerId = setInterval(function () {
    if (i >= options.frames) {
      i = 0;
    }
    element.style.backgroundPosition = "0px -" + i * options.height + "px";
     i++;
  }, 100);

  this.stopAnimation = function () {
    clearInterval(timerId);
  };
}

Notice that I added a stopAnimation method, so you can later stop a specified animation just by calling it, for example:

monkey.stopAnimation();

Check the above example here.

LightMan
  • 3,517
  • 31
  • 31
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • 8
    +1 For one of the most indepth responses to a fairly simple question – Ben Shelock Nov 16 '09 at 03:13
  • Great answer, great implementation. As a site note: if your animation stuff is getting more complex: http://www.spritely.net seems to be a nice and small lib for all things related to sprite animation. – bitbonk May 29 '13 at 20:55
  • Thanks for this, however I don't understand the use of the two anonymous functions in the first example (why "return function" ?). – kursus Jul 12 '13 at 15:48
  • 1
    Image location has changed, new image url http://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png – deepakmodak Sep 09 '14 at 09:43
  • 1
    I would just like to add that it is also possible to use this technique without JS for simple animations using the steps() funciton in CSS: http://blog.teamtreehouse.com/css-sprite-sheet-animations-steps – bernk Feb 19 '15 at 14:32
3

Take a look at this:
http://www.otanistudio.com/swt/sprite_explosions/ and http://www.alistapart.com/articles/sprites The answer lies within.

roufamatic
  • 18,187
  • 7
  • 57
  • 86
3

CMS's answer is fine, but there's also the APNG (animated PNG) format that you may want to use instead. Of course the first frame (the one displayed even by browsers that don't support APNG) should be the "ending" frame and just specify to skip the first frame in the file.

Eli Grey
  • 35,104
  • 14
  • 75
  • 93
1

Set the background image of an element to the first image, then use javascript to change the image by altering the style every x milliseconds.

klaaspieter
  • 2,665
  • 1
  • 27
  • 32
0

You can do it with TweenMax and steppedEase easing : http://codepen.io/burnandbass/pen/FfeAa or http://codepen.io/burnandbass/pen/qAhpj whatever you choose :)

Chris Panayotoff
  • 1,744
  • 21
  • 24
0

CSS @keyframes can be used in this case

@keyframes smile {
    0% { background-postiion: 0 -16px;}
    5% { background-postiion: 0 -32px;}
    10% { background-postiion: 0 -48px;}
    /*...etc*/
}
Undefitied
  • 747
  • 5
  • 14
  • I've thought of that, do you think it may show some glitch? like half of the first image and half of the second image? – shunz19 Jul 06 '17 at 17:05