An additional suggestion to the already existing answer would be to use context.translate
to fit the entire canvas instead of setting the X
position in the image, because when using context.scale
it affects the entire canvas, (assuming you are going to use more than one) and other added elements that should also be reversed.
Example of difficulty (note that the rect is not in position x = 20):
var onload = function() {
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
var img = document.querySelector("#img");
canvas.height = img.height;
canvas.width = img.width;
ctx.scale(-1, 1);
ctx.drawImage(img, 0, 0, img.width*-1, img.height);
ctx.rect(20, 20, 100, 100);
ctx.stroke();
}
img.completed ? onload() : img.addEventListener('load', onload);
<div>Imagem original:</div>
<img src="https://i.stack.imgur.com/pA0a1.png"id="img">
<div>Resultado Canvas:</div>
<canvas id="canvas"></canvas>
So to "fix" this, so that the position x = 20 in
drawImage
is not inverted in relation to the canvas size (
drawImage
) we would have to compensate, doing something like:
ctx.rect(-(img.width - 100 - 20), 20, 100, 100);
That is, we have to add the width of the rect
to the desired position and transform the value into negative, eg:
var onload = function() {
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
var img = document.querySelector("#img");
canvas.height = img.height;
canvas.width = img.width;
ctx.scale(-1, 1);
ctx.drawImage(img, 0, 0, -img.width, img.height);
ctx.rect(-(img.width - 100 - 20), 20, 100, 100);
ctx.strokeStyle = "red";
ctx.stroke();
}
img.completed ? onload() : img.addEventListener('load', onload);
<div>Imagem original:</div>
<img src="https://i.stack.imgur.com/pA0a1.png"id="img">
<div>Resultado Canvas:</div>
<canvas id="canvas"></canvas>
Using translate
However this can be tricky, costly even for development time and certainly is something that can be simplified using <canvas width="...
, example
var onload = function() {
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
var img = document.querySelector("#img");
canvas.height = img.height;
canvas.width = img.width;
ctx.scale(-1, 1);
ctx.translate(-canvas.width, 0);
ctx.drawImage(img, 0, 0, img.width, img.height);
ctx.rect(20, 20, 100, 100);
ctx.stroke();
}
img.completed ? onload() : img.addEventListener('load', onload);
<div>Imagem original:</div>
<img src="https://i.stack.imgur.com/pA0a1.png"id="img">
<div>Resultado Canvas:</div>
<canvas id="canvas"></canvas>
Done, this way you do not need to calculate anything, you can apply more than one object or image to the canvas that it will draw like a mirror without needing adjustments, the same can be done with the axis rect
if you want to flip vertically it would look like this:
ctx.scale(1, -1);
ctx.translate(0, -canvas.height);
ctx.drawImage(img, 0, 0, img.width, img.height);