Reputation: 1231
The problem: When i rotate my added image, the image does not center as i would like it to. I keep getting a white area above my picture inside the canvas.
Try with a 16:9 ratio image, and you'll see my problem after a rotate. This will be used for mobile, so the width of the picture could be max 640.
Here is a fiddle Current code:
HTML:
<div id="files">
<input type="file" id="imageLoader" name="imageLoader" />
</div>
<canvas id="imageCanvas"></canvas>
<canvas id="preview"></canvas>
<input type="button" id="saveButton" value="Save" />
<div id="rotate">
<button type="button" id="rotateLeft">Rotate -90°</button>
<button type="button" id="rotateRight">Rotate 90°</button>
</div>
JS:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var image = "";
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext("2d");
var fileName = "";
var angleInDegrees = 0;
function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var img = new Image();
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0,0);
fileName = img.name;
image = img;
};
img.src = event.target.result;
};
reader.readAsDataURL(e.target.files[0]);
}
function drawRotated(degrees) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(degrees * Math.PI / 180);
ctx.drawImage(image, -image.width / 2, -image.width / 2);
ctx.restore();
}
$("#rotateRight").click(function () {
angleInDegrees += 90;
drawRotated(angleInDegrees);
});
$("#rotateLeft").click(function () {
angleInDegrees -= 90;
drawRotated(angleInDegrees);
});
Here is my new fiddle :) What if i want it to be max 640 width?
Upvotes: 1
Views: 2417
Reputation:
Try changing this line:
ctx.drawImage(image, -image.width / 2, -image.width / 2);
to:
ctx.drawImage(image, -image.width / 2, -image.height / 2);
^^^^^^
or else width will be used as basis for the rotation both axis.
Also see this answer for one way to rotate and fit the canvas to the image based on rotation:
Rotate original Image with jQuery or JavaScript
Upvotes: 0
Reputation: 105035
You have a typo in your drawImage:
ctx.drawImage(image, -image.width / 2, -image.height / 2);
Unless your image is always square, you must resize the canvas to allow the rotated image to fit.
Demo on how to resize the canvas: http://jsfiddle.net/m1erickson/3E99A/
If you don't want to change the canvas size, you're image will be clipped. Also, if the image is in landscape orientation, you must flip the width/height in drawimage:
// flip width/height when the image is in landscape orientation
ctx.drawImage(image, -image.height/2, -image.width/2);
Code on how to resize the canvas:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
#canvas{
border: 1px solid green;
}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var imgWidth=200;
var imgHeight=300;
var size={width:imgWidth, height:imgHeight};
var rotation=0;
var deg2Rad=Math.PI/180;
var count1=0;
var count2=0;
var img=new Image();
img.onload=function(){
imgWidth=img.width;
imgHeight=img.height;
size={width:imgWidth, height:imgHeight};
draw();
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/card.png";
function draw(){
canvas.width=size.width;
canvas.height=size.height;
// calculate the centerpoint of the canvas
var cx=canvas.width/2;
var cy=canvas.height/2;
var info=document.getElementById("info");
info.innerHTML="canvas size: "+(count1++)+": "+cx+" / "+cy;
// draw the rect in the center of the newly sized canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle="rgba(216,216,150,1.0)";
ctx.translate(cx,cy);
ctx.rotate(rotation * deg2Rad);
ctx.drawImage(img,-imgWidth/2,-imgHeight/2);
}
document.getElementById("rotate").addEventListener("click", resizeClicked, false);
function resizeClicked(e){
rotation+=30;
newSize(imgWidth,imgHeight,rotation);
draw();
}
function newSize(w,h,a){
var rads=a*Math.PI/180;
var c = Math.abs(Math.cos(rads));
var s = Math.abs(Math.sin(rads));
size.width = h * s + w * c;
size.height = h * c + w * s ;
}
}); // end onload
</script>
</head>
<body>
<button id="rotate">Rotate with resize</button>
<p id=info></p>
<canvas id="canvas" width=400 height=400></canvas>
</body>
</html>
Upvotes: 4