Hello and good morning! Today I will be showing you how to turn a sprite sheet into an animation sequence using JavaScript. Here is the sprite sheet we will be working with and the final result.
Prerequisites
- An understanding of the HTML canvas and context
- Basic knowledge of JavaScript classes
- A bit of async and await
Things to note about this sprite sheet
- Has a total of 8 frames
- Each frame is exactly 113x79 pixels
Our First Class
class Sprite {
constructor(src, width, height, frames) {
this.image = new Image;
this.image.src = src;
this.width = width;
this.height = height;
this.frames = frames;
}
}
This class is in charge of maintaining the properties of a sprite sheet. The width and height properties belong to the expected width/height for all of the frames in the sheet (113x79).
The Animation Handler
class AnimationHandler {
constructor(sprites) {
this.sprites = sprites;
this.currentSprite = sprites[0];
this.loop = true;
this.currentSprite.image.onload = this.render();
}
...
The AnimationHandler class takes in an array of Sprite Objects and calls the render function in a looping state after the sprite loads.
The Brains
...
async render() {
for (let i = 0; i < this.currentSprite.frames; i++) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(this.currentSprite.image, (this.currentSprite.width * i), 0, this.currentSprite.width,
this.currentSprite.height, 50, 50, this.currentSprite.width, this.currentSprite.height);
await sleep(80)
}
if (this.loop) {this.render();}
}
We first define an asynchronous function named render using the async keyword. This allows us to run multiple animations at once without creating blockage.
We then create a basic for loop to loop over the number of frames. For every frame we do these things in order.
- Clear everything on the canvas
- Draw the sprite image and crop it to show the current frame
- Pause the loop for 80 milliseconds before continuing
- Use recursion to keep the animation running
Check this link out to learn about how context.drawImage works MDN
You may be asking yourself, "Where the hell is the sleep function defined?!" I decided to keep it out of this tutorial to avoid confusion. The sleep function just returns a Promise after setTimeout.
Putting It All Together
const dogIdle = new Sprite(dog_idle, 109, 79, 4);
const dogMoving = new Sprite(dog_moving, 113, 79, 8);
new AnimationHandler([dogMoving, dogIdle])
We create two Sprite instances and pass in the required parameters. Then we create an AnimationHandler instance for the sprites. This should automatically play the first sprite sheet you pass i although the class can be easily modified to jump between animations and even pause them.
Here is the idle we defined above and an attacking animation.
Thank you for reading ! I left a few things out for the sake of keeping this simple. Like defining the canvas and context and the sleep function.
Top comments (0)