An additional suggestion to the existing answer would be to use the context.translate
to adjust the whole canvas instead of fixing the position in the image X
, this because when using the context.scale
it affects the whole canvas, so it would have to be adjusting drawImage
for drawImage
(supposing that it will use more than one) and other added elements also that should appear reversed.
Example of difficulty (note that the rect is not at 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>
Then to "fix" this, so that the position x=20 in the rect
is not reversed in relation to canvas size (<canvas width="...
) we would have to compensate by doing something like:
ctx.rect(-(img.width - 100 - 20), 20, 100, 100);
That is, we have to add the width of the rect
with the desired position and turn the value into negative, 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.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 complicated, costly even for development time and is surely something that can be simplified using the translate
, 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>
Okay, this way you do not need to calculate anything, you can apply more of an object or image to the canvas that it will draw as if it were a mirror without needing adjustments, the same can be done with the axis Y
, if you want to flip vertically would look like this:
ctx.scale(1, -1);
ctx.translate(0, -canvas.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
Beautiful and moral. + 1
– Wallace Maxters
@Wallacemaxters Thank you! We’re here for this! :)
– bio
Just for the record
img.width*-1
would be the same as doing-img.width
, i.e., the multiplication operation is not so necessary in this use.– Guilherme Nascimento