1

I found this CanvasRenderingContext2D and i played around a little bit with it. I was able to scale and to rotate my Image using this context:

crop: function () {
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");

    canvas.width = this.options.width / this.scale;
    canvas.height = this.options.height / this.scale;

    var currWidth = this.imgWidth * this.scale;
    var currHeight = this.imgHeight * this.scale;
    var correctX = (currWidth - this.imgWidth) / 2;
    var correctY = (currHeight - this.imgHeight) / 2;
    var sourceX = (this.posX - correctX) / this.scale;
    var sourceY = (this.posY - correctY) / this.scale;

    context.translate(sourceX, sourceY);
    context.translate(this.imgWidth / 2, this.imgHeight / 2);
    context.rotate(this.rotate * Math.PI / 180);
    context.drawImage(this.imgFull, this.imgWidth / 2 * -1, this.imgHeight / 2 * -1);

    this.options.modal.remove();
    this.promise.resolve(canvas);
},

Unfortunately i could not find any function to flip the canvas vertically or horizontally. In code i thought i could do something like:

if(self.flipV) {
    context.rotateY(180);
}

if(self.flipH) {
    context.rotateX(180);
}

But i could not find any methods for rotating on the y- or x-axis. Is there any way i could perform my flip transformation here?

Mulgard
  • 9,877
  • 34
  • 129
  • 232
  • 1
    Although it's not obvious, you can flip using the `context.scale` method. Flip horizontally with `context.scale(-1,1)` and flip vertically with `context.scale(1,-1)`. Just like with rotation, you must set the rotation point using `context.translate` before doing your `context.scale`. :-) – markE Aug 24 '15 at 09:21
  • 1
    wow. that is the perfect solution for my situation. thank you. dont you want to make an answer out of your comment? – Mulgard Aug 24 '15 at 11:30

3 Answers3

4

Although it's not obvious, you can flip using the context.scale method.

Flip horizontally with context.scale(-1,1) and flip vertically with context.scale(1,-1).

Just like with rotation, you must set the rotation point using context.translate before doing your context.scale.

enter image description here

Here's example code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/marioRunningRight.png";
function start(){

  // original
  ctx.drawImage(img,200,200);

  // horizontal flip
  ctx.translate(200,0);
  ctx.scale(-1,1);
  ctx.drawImage(img,0,200);
  ctx.setTransform(1,0,0,1,0,0);

  // vertical flip
  ctx.translate(0,200);
  ctx.scale(1,-1);
  ctx.drawImage(img,200,0);
  ctx.setTransform(1,0,0,1,0,0);

  // labels
  ctx.font='18px verdana';
  ctx.textAlign='center';
  ctx.fillText('Original',275,375);
  ctx.fillText('scale(-1,1)',125,375);
  ctx.fillText('Horizontal Flip',125,395);
  ctx.fillText('scale(1,-1)',275,20);
  ctx.fillText('Vertical Flip',275,40);
}
<canvas id="canvas" width=400 height=425></canvas>

  
markE
  • 102,905
  • 11
  • 164
  • 176
2

Mirror an image via CanvasRenderingContext2D

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

More mirrors

If you wish to be able to mirror along an arbitrary line see the answer Mirror along line

Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136
1

I don't know if this is what you're looking for, but you can reflect images using CSS. I have this in one of my projects:

<style>
.image-reflect {
    transform: scaleX(-1);
}
</style>
.
.
.
<span class="fa fa-share-alt image-reflect"></span>

to show the FontAwesome share icon as a "merge" icon.

Actually, if you look up "CSS transform", you'll find it can rotate, scale, move, skew, etc.

Phil Cairns
  • 758
  • 4
  • 15
  • I tried this but i actually had no idea how to perform that css on my canvas object in my javascript code. The canvas only gets created inside my javascript since it is a dynamic image cropping view. Im not very familiar with html/css and javascript. Im lagging of experience. – Mulgard Aug 24 '15 at 08:23
  • @Mulgard, are you using anything like jQuery for handling your DOM? If so, it's really easy to dynamically apply styles to your elements. For instance, and this is off the top of my head, you could do something like `$("#my-canvas").css("transform", "scaleX(-1)");` – Phil Cairns Aug 24 '15 at 08:27
  • Have a look at https://developer.mozilla.org/en-US/docs/Web/API/Element ... you should be able to do something like `canvas.id = "my-canvas";` to set the ID without using jQuery. You should also be able to do `canvas.className = "image-reflect";` to set the class. – Phil Cairns Aug 24 '15 at 11:41