Html5 Canvas Rotate Image

HTML5 Canvas Rotate Image

You can use canvas’ context.translate & context.rotate to do rotate your image

Sample Image

Here’s a function to draw an image that is rotated by the specified degrees:

function drawRotated(degrees){
context.clearRect(0,0,canvas.width,canvas.height);

// save the unrotated context of the canvas so we can restore it later
// the alternative is to untranslate & unrotate after drawing
context.save();

// move to the center of the canvas
context.translate(canvas.width/2,canvas.height/2);

// rotate the canvas to the specified degrees
context.rotate(degrees*Math.PI/180);

// draw the image
// since the context is rotated, the image will be rotated also
context.drawImage(image,-image.width/2,-image.width/2);

// we’re done with the rotating so restore the unrotated context
context.restore();
}

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/6ZsCz/

<!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>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>

<script>
$(function(){

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

var angleInDegrees=0;

var image=document.createElement("img");
image.onload=function(){
ctx.drawImage(image,canvas.width/2-image.width/2,canvas.height/2-image.width/2);
}
image.src="houseicon.png";

$("#clockwise").click(function(){
angleInDegrees+=30;
drawRotated(angleInDegrees);
});

$("#counterclockwise").click(function(){
angleInDegrees-=30;
drawRotated(angleInDegrees);
});

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();
}


}); // end $(function(){});
</script>

</head>

<body>
<canvas id="canvas" width=300 height=300></canvas><br>
<button id="clockwise">Rotate right</button>
<button id="counterclockwise">Rotate left</button>
</body>
</html>

How to rotate an image on an HTML5 canvas around center

You need to translate by the desired center plus half the size of the image, rotate, then translate back by half the size of the image. Otherwise your are rotating around the corner. I used save and restore instead of rotating and translating back after the draw, because it's faster.

ctx.save();
ctx.translate(x + width/2, y + height/2);
ctx.rotate(-angle);
ctx.translate(-width/2, -height/2);
ctx.strokeRect(0, 0, 150, 100);
ctx.restore();

Rotate image by 90 degrees on HTML5 Canvas

There are several ways of resetting a transformed (translated+rotated) canvas back to its original state.

Low-Pointer's answer is using context.save to save the context in is original un-transformed state and using context.restore to restore the context to its original state after the drawing is done.

The other way it to undo your transforms in the reverse order that they were performed.

Also, note that context.translate will actually move the canvas origin to the center of the canvas. Since images are drawn from their top-left (not their center), you must offset drawImage by half the image width and height if you want the image centered in the canvas.

Here's and example: http://jsfiddle.net/m1erickson/EQx8V/

// translate to center-canvas 
// the origin [0,0] is now center-canvas

ctx.translate(canvas.width/2,canvas.height/2);

// roate the canvas by +90% (==Math.PI/2)

ctx.rotate(Math.PI/2);

// draw the signature
// since images draw from top-left offset the draw by 1/2 width & height

ctx.drawImage(img,-img.width/2,-img.height/2);

// un-rotate the canvas by -90% (== -Math.PI/2)

ctx.rotate(-Math.PI/2);

// un-translate the canvas back to origin==top-left canvas

ctx.translate(-canvas.width/2,-canvas.height/2);

// testing...just draw a rect top-left

ctx.fillRect(0,0,25,10);

Sample Image

Rotate Existing Image on Canvas

You can use a second in-memory canvas to rotate the existing canvas content if you don't want to store all the commands necessary to recreate the canvas.

  • Create an second in-memory canvas.
  • Copy your main canvas onto the second canvas.
  • Clear your main canvas.
  • Set the rotation point as center of the main canvas.
  • (but you can set any rotation point you desire)
  • Rotate by 90 degrees (==PI/2).
  • Redraw the second canvas back to the (now rotated) main canvas.
  • Clean up -- unrotate and untranslate the main canvas.

Sample ImageSample Image

Example code and a Demo:

var canvas=document.getElementById("canvas");var ctx=canvas.getContext("2d");var cw=canvas.width;var ch=canvas.height;
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/multple/leftarrow.png";function start(){
ctx.drawImage(img,cw/2-img.width/2,ch/2-img.width/2);
$('#rotate').click(function(){ rotate(cw/2,ch/2,90); });
}
function rotate(rotationPointX,rotationPointY,degreeRotation){
// Create an second in-memory canvas: var mCanvas=document.createElement('canvas'); mCanvas.width=canvas.width; mCanvas.height=canvas.height; var mctx=mCanvas.getContext('2d');
// Draw your canvas onto the second canvas mctx.drawImage(canvas,0,0);
// Clear your main canvas ctx.clearRect(0,0,canvas.width,canvas.height);
// Rotate the main canvas
// set the rotation point as center of the canvas // (but you can set any rotation point you desire) ctx.translate(rotationPointX,rotationPointY);
// rotate by 90 degrees (==PI/2) var radians=degreeRotation/180*Math.PI; ctx.rotate(radians);

// Draw the second canvas back to the (now rotated) main canvas: ctx.drawImage(mCanvas,-canvas.width/2,-canvas.height/2);
// clean up -- unrotate and untranslate ctx.rotate(-radians); ctx.translate(-canvas.width/2,-canvas.height/2);
}
body{ background-color: ivory; }#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><button id=rotate>Rotate the existing image.</button><br><canvas id="canvas" width=300 height=300></canvas>

How to rotate one image in a canvas?

Use .save() and .restore() (more information):

link.onload=function(){
ctx.save(); // save current state
ctx.rotate(Math.PI); // rotate
ctx.drawImage(link,x,y,20,20); // draws a chain link or dagger
ctx.restore(); // restore original states (no rotation etc)
}

How to rotate an image in a canvas?

putImageData() and getImageData() are not affected by the context's transformation matrix.

To rotate it, the easiest is to create an ImageBitmap from it and to draw that ImageBitmap using drawImage():

(async () => {  const canvas = document.getElementById( 'canvas' );  const context = canvas.getContext( '2d' );  // make some noise  const image = new Uint8Array( Uint32Array.from(      { length: 200 * 200 },      _ => (Math.random() * 0xFFFFFFFF)    ).buffer );
const image_data = context.createImageData( 200, 200 ); image_data.data.set( image ); const center_w = canvas.width / 2; const center_h = canvas.height / 2; const bitmap = await createImageBitmap( image_data ); context.translate( center_w, center_h ); context.rotate( 60 ); context.translate( -center_w, -center_h ); context.drawImage( bitmap, center_w-100, center_h-100 ); // <---- image rotated context.lineWidth = 4; context.strokeStyle = 'green'; context.strokeRect( center_w-100, center_h-100, 200, 200 ); // <--- rectangle rotated})().catch( console.error );
<canvas id="canvas" height="300" width="300"></canvas>

Rotating image on canvas around the center of the image

You can translate the canvas to the location you wish to draw at, rotate the canvas on this point, then draw the image with the following call:

ctx.drawImage(
img,
img.width / -2, // x
img.height / -2, // y
img.width,
img.height
);

Moving the x and y away from the center by half the width and height respectively places the center of the image (width / 2, height / 2) at 0, 0 on the canvas (the rotation point).

Here's a minimal, complete example:

const degToRad = deg => deg * Math.PI / 180;const canvas = document.createElement("canvas");document.body.appendChild(canvas);canvas.width = canvas.height = 180;const ctx = canvas.getContext("2d");const player = {  x: canvas.width / 2,   y: canvas.height / 2,   angle: 0,  img: new Image()};player.img.onload = function () {  (function update() {    ctx.clearRect(0, 0, canvas.width, canvas.height);    ctx.save();    ctx.translate(player.x, player.x);    ctx.rotate(degToRad(player.angle++ % 360));    ctx.drawImage(      player.img,       player.img.width / -2,       player.img.height / -2,       player.img.width,       player.img.height    );    ctx.restore();      requestAnimationFrame(update);  })();};player.img.src = "http://placekitten.com/100/100";

Scale rotated image to fill HTML5 Canvas using JavaScript trigonometry?

+1 to Blindman67's answer for this to work.

I shortened the code and simplified for my use case. You should be able to just include function drawBestFit() into your app and use it to fill any canvas with any loaded image.

For a better understanding of how this works, view Blindman67's original answer - especially the demonstration snippet at the bottom.

var canvas = document.querySelector('canvas')var context = canvas.getContext('2d')var image = new Image()image.src = 'http://i.stack.imgur.com/7FsbT.jpg'
image.onload = function() {
var degrees = 0
loop()
function loop() { degrees += .5 drawBestFit(context, degrees * Math.PI / 180, image) requestAnimationFrame(loop) }
function drawBestFit(ctx, angle, image) { var dist = Math.sqrt(Math.pow(canvas.width, 2) + Math.pow(canvas.height, 2)) var diagAngle = Math.asin(canvas.height / dist)
var a1 = ((angle % (Math.PI * 2)) + Math.PI * 4) % (Math.PI * 2) if (a1 > Math.PI) a1 -= Math.PI if (a1 > Math.PI / 2 && a1 <= Math.PI) a1 = (Math.PI / 2) - (a1 - (Math.PI / 2)) var ang1 = Math.PI / 2 - diagAngle - Math.abs(a1) var ang2 = Math.abs(diagAngle - Math.abs(a1)) var scale1 = Math.cos(ang1) * dist / image.height var scale2 = Math.cos(ang2) * dist / image.width var scale = Math.max(scale1, scale2) var dx = Math.cos(angle) * scale var dy = Math.sin(angle) * scale ctx.setTransform(dx, dy, -dy, dx, canvas.width / 2, canvas.height / 2) ctx.drawImage(image, -image.width / 2, -image.height / 2, image.width, image.height) ctx.setTransform(1, 0, 0, 1, 0, 0) // reset transformations when done
}
}
<canvas width="350" height="200" style="border: solid 1px black"></canvas>

How to Flip & Rotate images on HTML5 Canvas

value: function drawRotatedImage(canvas, image, angle, mirrorImage) {
var context = canvas.getContext('2d');
if (angle > 0) {
context.rotate(angle * (Math.PI / 180));
}
if (mirrorImage === true) {
if (angle > 0) {
context.scale(-1, 1);
context.drawImage(image, -image.width, -image.height, image.width, image.height);
}
}

if (mirrorImage === true) {
if (angle < 1) {
context.scale(-1, 1);
context.drawImage(image, -image.width, 0, image.width, image.height);
}
} else {
context.drawImage(image, 0, angle === 0 ? 0 : -image.height);
}
return canvas;
}


Related Topics



Leave a reply



Submit