2
votes

I'm trying to place an html5 image inside canvas. The image is translated, rotated and scaled using the css transform property. The main problem is how to copy the properties of the image and apply them on the canvas.

You can try the jsfiddle link below: the image can be scaled, moved and rotated and whatever appears in the greenbox should be the same as the one in the red.

https://jsfiddle.net/q7y1py5f/3/. Here I can move and scale the image, but when the rotation kicks in nothing works. Here is the code that bugs me (58 line in the javascript jsfiddle) :

context.save();

context.translate(image.width / 2, image.height / 2);
context.rotate(angle * Math.PI/180);
context.translate(((-image.width) / 2), ((-image.height) / 2));

context.translate(-x, -y);
context.scale(scale, scale);

context.drawImage(image, 0, 0);

context.restore();

Here the x and y are the difference between the top left of the green container and the top left of the image. Any help would be appreciated.

I've managed to get each property to work individually, but when combining them all together it doesn't work. When I only translate and scale the image and apply to the canvas context everything is fine, but when I add the rotation with the image is not where it's supposed to be.

I tried the following - calculated the top-left of the element with the angle to get the right value and then translating and rotating with it.

1
Is there a specific browser this isn't working in for you? Unless I'm misunderstanding what you're saying, everything works fine in the Fiddle using Chrome v49 - I can move, scale & rotate the image. EDIT: I can not move the image while it is contained within the green box.Shaggy
What is in the green box should be appearing in the red box as is, sorry for misunderstanding.electrofly
Ah, my apologies, the misunderstanding was mine; I wasn't paying any attention to what was going on in the red box.Shaggy
First thing I notice, ctx.rotate() takes angle in radians as argument. You are passing degrees, you can convert them with Math.PI/180*angle. Then there is a bigger problem with your translating, not sure right now and I don't have much time to look at it, but I would say you need to get the distance between the original position and the center of your green square.Kaiido
About the radians I forgot to add it in the jsfiddle. Could you please explain how would I use the distance between the original position and the center of the green square ?electrofly

1 Answers

2
votes

In function canvasCropping you write

var left = cropper.offset().left - img.offset().left, top = cropper.offset().top - img.offset().top,

but rotating and scaling will change element offset, so you got wrong coordinats for translation. Change it to: var left = -(cropper.offset().left - transform.translate.x-initialOffset.left), top = -(cropper.offset().top -transform.translate.y-initialOffset.top),

initialOffset - initial offset of your image.

And some changes in drawRotatedImage ` var drawRotatedImage = function (context, image, x, y, angle, width, height, scale) {

    context.save();

    // Move registration point to the center of the canvas
    context.translate(x+image.width/2,y+image.height/2);
    context.rotate(angle* Math.PI / 180);// angle must be in radians
    context.scale(scale, scale);
    // Move registration point back to the top left corner of canvas
    context.translate((-image.width)/2, (-image.height)/2);

    context.drawImage(image, 0, 0);

    context.restore();
};

`