Flip a sprite in canvas

James Dawson picture James Dawson · Oct 27, 2011 · Viewed 15.8k times · Source

I'm using canvas to display some sprites, and I need to flip one horizontally (so it faces left or right). I can't see any method to do that with drawImage, however.

Here's my relevant code:

this.idleSprite = new Image();
this.idleSprite.src = "/game/images/idleSprite.png";
this.idleSprite.frameWidth = 28;
this.idleSprite.frameHeight = 40;
this.idleSprite.frames = 12;
this.idleSprite.frameCount = 0;

this.draw = function() {
        if(this.state == "idle") {
            c.drawImage(this.idleSprite, this.idleSprite.frameWidth * this.idleSprite.frameCount, 0, this.idleSprite.frameWidth, this.idleSprite.frameHeight, this.xpos, this.ypos, this.idleSprite.frameWidth, this.idleSprite.frameHeight);
            if(this.idleSprite.frameCount < this.idleSprite.frames - 1) { this.idleSprite.frameCount++; } else { this.idleSprite.frameCount = 0; }
        } else if(this.state == "running") {
            c.drawImage(this.runningSprite, this.runningSprite.frameWidth * this.runningSprite.frameCount, 0, this.runningSprite.frameWidth, this.runningSprite.frameHeight, this.xpos, this.ypos, this.runningSprite.frameWidth, this.runningSprite.frameHeight);
            if(this.runningSprite.frameCount < this.runningSprite.frames - 1) { this.runningSprite.frameCount++; } else { this.runningSprite.frameCount = 0; }
        }
    }

As you can see, I'm using the drawImage method to draw my sprites to the canvas. The only way to flip a sprite that I can see is to flip/rotate the entire canvas, which isn't what I want to do.

Is there a way to do that? Or will I need to make a new sprite facing the other way and use that?

Answer

Simon Sarris picture Simon Sarris · Oct 27, 2011

While Gaurav has shown the technical way to flip a sprite in canvas...

Do not do this for your game.

Instead make a second image (or make your current image larger) that is a flipped version of the spite-sheet. The performance difference between "flipping the context and drawing an image" vs "just drawing an image" can be massive. In Opera and Safari flipping the canvas results in drawing that is ten times slower, and in Chrome it is twice as slow. See this jsPerf for an example.

Pre-computing your flipped sprites will always be faster, and in games canvas performance really matters.