1

I'm rotating an image by dragging using canvas rotate() function. Obviously the image gets cut during rotation.

cropped image

To tackle this problem I followed some stackoverflow instructions and implemented something like this:

//Resizing Canvas - this part is creating problem
var w = imgW;
var h = imgH;

var newWidth,newHeight;
var c = Math.cos(15*rot*0.0174532925);
var s = Math.sin(15*rot*0.0174532925);

if (s < 0) { s = -s; }
if (c < 0) { c = -c; }
newWidth = h * s + w * c;
newHeight = h * c + w * s ;

cnv2.width = newWidth;
cnv2.height= newHeight;

translateX = cnv2.width/axisFactor;
translateY = cnv2.height/axisFactor
ctx2.clearRect(0,0,cnv2.width,cnv2.height);
ctx2.save();
ctx2.translate(translateX,translateY);
ctx2.rotate(15*rot*0.0174532925);
ctx2.drawImage(img,-translateX,-translateY);
ctx2.restore();

Though I'm able to get the correct size of the canvas the redraw of the image still gets cut.

enter image description here

What am I missing?

Heres the fiddle:http://jsfiddle.net/anubhabB/wwas5jag/

EDIT: Problem solved by correcting

ctx2.drawImage(img,-translateX,-translateY);

with

ctx2.drawImage(img,-img.width/axisFactor,-img.height/axisFactor);

But this doesn't work for any axis which is not 1/2 of the image, say axis factor 3!

How to tackle this?

Community
  • 1
  • 1
Anubhab
  • 741
  • 1
  • 9
  • 20

1 Answers1

0

Comments below were in regards to my first edit, that was not what the OP wanted solved.

EDIT I had missunderstood the question and provided something that wasn't a good solution. New try:

This fiddle re-sizes the canvas to the maximum width/height needed to freely rotate the image without clipping. The canvas only re-sizes once though. The rotation axis is in the center of the canvas and the image is moved to coinside with the rotation axis at the point of the axisFactor.

I hope this either completely or partially solves your problem.

http://jsfiddle.net/Niddro/wwas5jag/8/

var cntx = document.getElementById('cnvSampl').getContext('2d');
cntx.fillStyle = '#fc0';
cntx.fillRect(0,0,95,95);
var canv = document.getElementById('cnv');
var ctx  = canv.getContext('2d');
var canv2= document.getElementById('cnv2');
var ctx2  = canv2.getContext('2d');

var img = new Image();
var imgW, imgH;
var translateX, translateY;
var axisFactor = 5;
var newCanvasSize;
var rot = 0;

function rotate(){
    rot++;
    //This is without resize
    translateX = cnv.width/axisFactor;
    translateY = cnv.height/axisFactor
    ctx.clearRect(0,0,imgW,imgH);
    ctx.save();
    ctx.translate(translateX,translateY);
    ctx.rotate(15*rot*0.0174532925);
    ctx.drawImage(img,-translateX,-translateY);
    ctx.restore();
    //Resizing Canvas - this part is creating problem
    var w = imgW;
    var h = imgH;
    
    var newWidth,newHeight;
    var c = Math.cos(15*rot*0.0174532925);
    var s = Math.sin(15*rot*0.0174532925);
    
    if (s < 0) { s = -s; }
    if (c < 0) { c = -c; }
    newWidth = h * s + w * c;
    newHeight = h * c + w * s ;
    
    cnv2.width = newCanvasSize*2;
    cnv2.height= newCanvasSize*2;
    
    translateX = cnv2.width/2;
    translateY = cnv2.height/2;
    ctx2.clearRect(0,0,cnv2.width,cnv2.height);
    ctx2.save();
    ctx2.translate(translateX,translateY);
    ctx2.rotate(15*rot*0.0174532925);
    ctx2.drawImage(img,-img.width/axisFactor,-img.height/axisFactor);
    ctx2.restore();
}

function init(){
    img.onload = function(){
        imgW = img.width;
        imgH = img.height;
        ctx.drawImage(img,0,0,imgW,imgH);
        ctx2.drawImage(img,0,0,imgW,imgH);
        newCanvasSize = Math.sqrt(Math.pow(img.width,2)+Math.pow(img.height,2))*(1-1/axisFactor);
    }
    img.src = document.getElementById('cnvSampl').toDataURL();
    document.getElementById('rotate').onclick = function(){
         rotate(); 
    };
}
init();
#cnv,#cnv2{
    border:1px solid #ccc
}
<button id="rotate">Rotate 15deg</button><br />
<canvas width="95" height="95" id="cnv"></canvas>
<canvas width="95" height="95" id="cnv2"></canvas>

<canvas width="95" height="95" id="cnvSampl" hidden></canvas>
Niddro
  • 1,705
  • 2
  • 12
  • 24
  • Even with the old code it works when the rotation axis is at the center i.e img.width/2 or axisFactor = 2. I need dynamic rotation axis, i.e the axisFactor can be anything. Thats where translation back crops an image out. – Anubhab Mar 07 '15 at 19:30
  • @Anubhab, Explain again what the axisFactor represents. – Niddro Mar 07 '15 at 19:33
  • axisFactor is basically the factor of height and width by which the axis is defined so lets say if axisFactor is 2 then the axis of rotation is the center of image at x=img.width/2,y=img.height/2. In any other case the rotation axis can be x=img.width/3,y=img.height/3 This will give a rotation axis closer to the top-left. I dont know if I'm making sense :) – Anubhab Mar 07 '15 at 19:42
  • I understand now, that's indeed a challange. I'll give it a try. – Niddro Mar 07 '15 at 19:55
  • Thanks,I'm trying a couple of things too, will update if I come upon something. – Anubhab Mar 07 '15 at 19:56
  • It would be quite easy to accomplish a canvas with the maximum size, where the rotation-axis is centered in the canvas. Would that be acceptable? – Niddro Mar 07 '15 at 20:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72484/discussion-between-niddro-and-anubhab). – Niddro Mar 07 '15 at 20:10