They are using delays and parts of images such as this one (look at the bottom part of the image):

and specify what (rectangular) part of each image renders when, making it look like an animation.
It's a typical texture atlas.
This is the list of the images:
"anim/rename2_packed.png",
"anim/days_169_packed.png",
"anim/command_palette_packed.png",
"anim/goto_anything_packed.png",
"anim/goto_anything2_packed.png",
"anim/regex_packed.png"
And this is how they specify the delay and the image pieces
{"delay":1811,"blit":[[0,0,800,450,0,0]]},
{"delay":48,"blit":[[0,450,400,344,200,36],[66,982,63,15,0,36]]},
{"delay":798,"blit":[]}, etc...
As you see, delay
is the time in milliseconds, and blit
looks like parameters for drawImage
- srcX, srcY, width, height, destX, destY.
Each of the "screens" is kept as a separate variable, like command_palette_timeline
, days_169_timeline
, goto_anything_timeline
, etc. Each containing delay/blit array of objects like the one from the paragraph above.
The actual render code is pretty straightforward, they follow each step in each timeline, with delays between them, and each step is rendered like this:
for (j = 0; j < blits.length; ++j)
{
var blit = blits[j]
var sx = blit[0]
var sy = blit[1]
var w = blit[2]
var h = blit[3]
var dx = blit[4]
var dy = blit[5]
ctx.drawImage(img, sx, sy, w, h, dx, dy, w, h)
}