Animated gifs are brilliant…

…But they’re also kind of rubbish. We can’t pause a gif, skip to a particular point, or grab individual frames from the image element.

One way around these problems is to load the file content with JavaScript and decode it manually.

There are a bunch of different libraries that can decode gif (check out omggif, gify & gif-stream). I’m a fan of the decoder in jsgif; it’s awkward to use, pretty inefficient, a bit dated, and feels nice.

parse ( file , { hdr : ( data ) => { // handle header data } })

You provide an object with a set of callbacks for the different parts of the gif. Callbacks are fired as soon as that part of the gif is parsed and we can choose what we do with the data.

For example, we can listen out for the hdr (header) block, and pull out the global colour table for the gif.

Global colour table for example.gif

With the actual image data; each frame of the animated gif starts with a Graphics Control Extension (GCE) block which contains information about the section being drawn, followed by the actual (LZW encoded) pixel data.

I’ve skimmed over a lot of really interesting stuff here - for a really in-depth look at gif encoding, check out this blog post.

Once we’ve got those decoded pixel values back, we can map them through our colour tables to get the RGB values for each pixel, and now we’ve got something that can be drawn to a canvas.

Exported frame data

Each frame has an overwrite rule provided in its GCE block, which defines how the frame data is drawn to the existing graphic - either being appended to, or completely replacing it. This, combined with the transparency capabilities of the gif allow frames to update only the changed pixels of the image.

By implementing overwrite rules, frame delays, and probably some other stuff, it’s possible to play/pause/scrub through a gif file (see libgif-js).

Though, back to the frame data - we don’t have to settle on canvas .drawImage. If we load our data into a WebGL context, we can stack up the frames to get an overall feel for the structure of the gif:

Other gifs

Recommendation

Here’s what the original gif spec has to say about animation:

Animation : The Graphics Interchange Format is not intended as a platform for animation, even though it can be done in a limited way.

…I kind of feel for the person who wrote this; it must be hard to look around the web and see millions of people ignoring your advice . Though I hope they see the positive side - animated gifs might be a terrible hack; but they’re totally brilliant.