How to flip images horizontally with HTML5
canvas = document.createElement('canvas');
canvasContext = canvas.getContext('2d');
canvasContext.translate(width, 0);
canvasContext.scale(-1, 1);
canvasContext.drawImage(image, 0, 0);
Here's a snippet from a sprite object being used for testing and it produces the results you seem to expect.
Here's another site with more details. http://andrew.hedges.name/widgets/dev/
I like Eschers function above. I have made it a little neater and better. I have added flop (vertically) besides flip. Also a possibility to draw/rotate around the center of the image instead of top left. Finally, the function does not require all arguments. img, x and y are required but the rest are not.
If you were using something like context.drawImage(...), you can now just use drawImage(...) and add the rotate/flip/flop functionality explained here:
function drawImage(img, x, y, width, height, deg, flip, flop, center) {
context.save();
if(typeof width === "undefined") width = img.width;
if(typeof height === "undefined") height = img.height;
if(typeof center === "undefined") center = false;
// Set rotation point to center of image, instead of top/left
if(center) {
x -= width/2;
y -= height/2;
}
// Set the origin to the center of the image
context.translate(x + width/2, y + height/2);
// Rotate the canvas around the origin
var rad = 2 * Math.PI - deg * Math.PI / 180;
context.rotate(rad);
// Flip/flop the canvas
if(flip) flipScale = -1; else flipScale = 1;
if(flop) flopScale = -1; else flopScale = 1;
context.scale(flipScale, flopScale);
// Draw the image
context.drawImage(img, -width/2, -height/2, width, height);
context.restore();
}
Examples:
var myCanvas = document.getElementById("myCanvas");
var context = myCanvas.getContext("2d"); // i use context instead of ctx
var img = document.getElementById("myImage"); // your img reference here!
drawImage(img, 100, 100); // just draw it
drawImage(img, 100, 100, 200, 50); // draw it with width/height specified
drawImage(img, 100, 100, 200, 50, 45); // draw it at 45 degrees
drawImage(img, 100, 100, 200, 50, 0, true); // draw it flipped
drawImage(img, 100, 100, 200, 50, 0, false, true); // draw it flopped
drawImage(img, 100, 100, 200, 50, 0, true, true); // draw it flipflopped
drawImage(img, 100, 100, 200, 50, 45, true, true, true); // draw it flipflopped and 45 degrees rotated around the center of the image :-)
You don't need HTML5, it can be done with CSS same as in IE:
-moz-transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
filter: FlipH;
Mirror an image or rendering using the canvas.
Note. This can be done via CSS as well.
Mirroring
Here is a simple utility function that will mirror an image horizontally, vertically or both.
function mirrorImage(ctx, image, x = 0, y = 0, horizontal = false, vertical = false){
ctx.save(); // save the current canvas state
ctx.setTransform(
horizontal ? -1 : 1, 0, // set the direction of x axis
0, vertical ? -1 : 1, // set the direction of y axis
x + (horizontal ? image.width : 0), // set the x origin
y + (vertical ? image.height : 0) // set the y origin
);
ctx.drawImage(image,0,0);
ctx.restore(); // restore the state as it was when this function was called
}
Usage
mirrorImage(ctx, image, 0, 0, true, false); // horizontal mirror
mirrorImage(ctx, image, 0, 0, false, true); // vertical mirror
mirrorImage(ctx, image, 0, 0, true, true); // horizontal and vertical mirror
Drawable image.
Many times you will want to draw on images. I like to call them drawable images. To make an image drawable you convert it to a canvas
To convert an image to canvas.
function makeImageDrawable(image){
if(image.complete){ // ensure the image has loaded
var dImage = document.createElement("canvas"); // create a drawable image
dImage.width = image.naturalWidth; // set the resolution
dImage.height = image.naturalHeight;
dImage.style.width = image.style.width; // set the display size
dImage.style.height = image.style.height;
dImage.ctx = dImage.getContext("2d"); // get drawing API
// and add to image
// for possible later use
dImage.ctx.drawImage(image,0,0);
return dImage;
}
throw new ReferenceError("Image is not complete.");
}
Putting it all together
var dImage = makeImageDrawable(image); // convert DOM img to canvas
mirrorImage(dImage.ctx, dImage, 0, 0, false, true); // vertical flip
image.replaceWith(dImage); // replace the DOM image with the flipped image
More mirrors
If you wish to be able to mirror along an arbitrary line see the answer Mirror along line