Responsive sprite animation with ImageMagick and GreenSock

Original author: Tom Bennet
  • Transfer
CSS sprites are not new. From the moment they were popularized on A List Apart in 2004, simple sprites have become the main technique in the toolkit of most web developers. But, despite the fact that the advantages of sprite speed are understandable, their use in modern web development is rarely discussed. The principle remains the same: it is a combination of several images into one “main” graphic element, from which only certain parts are displayed at any given time.

In this article, we will look at a simple way to create responsive CSS sprite animations that are lightweight, display well on mobile devices, and even interactively. You do not need any special graphical editors, but only a little understanding of CSS and JavaScript. Let's get started.

Sprite creation

Sprites have left the world of video games, so we will pay tribute to the legacy and animate Ryu from Street Fighter. Of course, the original belongs to Capcom.

We need to combine each frame of our animation into one image. There are dozens of tools that can help you create sprites, most of which can even generate helper stylesheets. Compass’s built-in sprite features are extremely efficient, and SpritePad is a great example of a web-based generator. For our purposes, however, a simple command line is enough.

ImagemagickThe Swiss Knife for Image Processing is a free, publicly available image management tool that is great for automating tasks that can be quite time-consuming, such as combining images. ImageMagick is also available for almost every operating system. Mac users can install it through Homebrew , Windows adherents can download the installer from the official site, and Linux fans probably know what to do without me.

Save frames of your animation that have the same size to a folder as a sequence of PNG files. Call the command line terminal, change (cd) to the directory where your images are saved, and run the following command:

convert *.png -append result-sprite.png

This command instructs ImageMagick to vertically link all .PNG files in our directory (since “*” is a special character) into one full sprite called “result-sprite.png”. This is a graphic element that will be used as a background-image in CSS for the element we want to animate, changing its position to loop all frames in order.

Pure CSS Animation

We'll start simple and animate our sprite using CSS3 keyframe animation. If you are unfamiliar with the basic syntax, the Louis Lazaris article on Smashing Magazine is a good introduction. We are going to animate the vertical positioning of the background (background-position) of our element from 0% to 100% (top to bottom), using each frame in turn.

If we let animations run in one continuous sequence as standard behavior, our sprite will be used between frames, which will break the illusion. Nevertheless, using the steps () function, we can control the number of displayed key frames. Due to the fact that the background-position acts when determined as a percentage, we need to set the number of steps one less than the total number of frames in our animation.

Experiment with this code in CodePen to make sense.

Please note that we have determined the width and height of our element so that they clearly correspond to the overall frame, and to avoid the release of previous or subsequent frames. We used abbreviations to set the number of iterations of the animation (animation-iteration-count) to “infinite” and the duration of the animation (animation-duration) to 3.5 seconds, and so it turned out that Ryu throws his combo “hit” Throw-Haden before the time runs out.

Yes, he is far from ideal. Try changing the height of our Ryu element or applying background-size to our sprite, and the effect will break. Our animated element is not yet responsive and depends on clear pixel-based sizes.

Making it responsive

If we want to freely resize our animated sprite, we have two options. The key to both options is the dependence of our sprite on the exact aspect ratio, and not on a specific size. We must maintain its proportions so that it increases and decreases correctly.

The first option is to set the background size of our sprite to 100% of the width of our element, convert the width and height of our element from pixels to em, and then change the base font size (font-size) accordingly. This will help to achieve the desired effect and may work in most cases, but will not give real fluidity.

Our second option is to use Mark Hinze’s fixed-CSS fixed-aspect ratio technique, which uses percent indentation in a pseudo-element that preserves element proportions at any size. This approach is used in the demo below and gives our sprite a flowing width at 70%. Responsive Ryu .

This is a lightweight and mobile-friendly way to achieve a responsive frame-by-frame animation effect. Browsers have great support for CSS animation, so the only limiting factor is the CSS3 keyframe. Include the appropriate provider prefix -webkit-, and the effect will work in all modern browsers, including IE10 and higher.

Javascript animation

And if we want more precise control over our animation, which is basically possible when using CSS3 keyframe syntax? Suppose that instead of one looping animation, we want to include several sprites in one complex scene and bind the trigger and time functions to the position of the scroll bar.

To make this possible, we need to animate our sprites using JavaScript, using the full power of the GreenSock animation platform and the excellent ScrollMagic Jan Pepke library . For those who are not familiar with this great combination, the official ScrollMagic demos will be a great start .

These are powerful tools for writing a whole series of lessons. As an example, in order not to go into detail about how ScrollMagic works , we will demonstrate some of the time functions available to us. The basic principles of sprites remain the same as in our CSS animation.

To get started, let's call a 2-second animation at a certain scroll position. It should end with the last frame and play in the reverse order when scrolling back (even if at the same time it will play halfway). We will continue to stick to the theme of video games and use the sprite from the classic Westwood Studios strategy - Red Alert, which is now released for free.


Please note that we are using the above em-based sizing method; try resizing the font by decreasing or increasing the sprite. We defined the double by setting the vertical position of the background of our element to 100%, and used the SteppedEase method to achieve the desired frame-by-frame effect.

Let's go one step further. We synchronize our animation with the scroll position using the scroll bar as the playback slider.


The sprite remains in a fixed position for the duration of the animation, which is now controlled by the user's scroll behavior. To achieve this effect, we set our ScrollMagic.Scene property to a length of 1,500 pixels and used the setPin method to fix the parent element to complete the picture. A more detailed description of these techniques is provided in the documentation on the ScrollMagic website.

Browser support for JavaScript-based sprite animations is even better than our CSS-only version. ScrollMagic and GreenSock are supported by all modern browsers, including IE 9+, with automatic handling of browser prefixes and shortcomings. Mobile support is also good; these techniques work on iOS 8+ without special workarounds, including redrawing on the go, and without losing scroll speed.


We have outlined rather superficially what possibilities a combination of responsive CSS sprites with advanced scroll animation provides, but I hope that we inspired the rest to start experimenting.

And in the end, as Rachel Seths said, “animate responsibly.” If something can be animated, it does not have to be animated. And if you really chose animation, do it consciously, beautifully and rationally.

Also popular now: