Martijn Ven van de
Martijn Ven van de

Reputation: 83

How to rotate an canvas object while the object stays on the same place

I am creating a Javascript game. It is about a guy who stands on top of the world. I already have an earth and now I need to rotate it but when I rotate it it also changes it place.

Earth Earth

As you can see the earth rotates but it also changes its place. I want it to rotate just like the rotate keyframes from css. Any thoughts?

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body onload="draw()">
    <canvas id="canvas"></canvas>
</body>
<script>
var ctx = document.getElementById("canvas").getContext('2d');
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
    
setInterval(draw, 10);
function draw() {
    var img = new Image();
    img.onload = function(){
    ctx.rotate(1*Math.PI/180);
    ctx.drawImage(img,canvas.width/2-200,canvas.height/2-100,300,300);
  };
  img.src = "earth.png";
}
</script>
</html>

The code doesn't work because it cant load the image because i have it downloaded but now you guys have the code so you can see the problem.

Upvotes: 0

Views: 1338

Answers (2)

Blindman67
Blindman67

Reputation: 54041

A quicker way that avoids having to use save and restore.

If you are drawing 100's or 1000's of images (such as for games) the use of save and restore can make the difference between playable and not. In some situations the restore call can drop the frame rate for a nice 60fps to less than 10fps.

Always be careful when using save and restore, making sure you don't have large patterns, or filters ( if supported), complex gradients, or detailed fonts when you save. You are better to remove these thing before you do the save and restore if you plan to do many of them

For single images it does not matter and the previous answer is the best solution.

General purpose sprite render with scales rotation and fade

// draws a image centered at x,y scaled by sx,sy rotate (r in radians) and faded by alpha (0-1)and 

    function drawImage(image,x,y,sx,sy,r,alpha){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.globalAlpha = alpha;
        ctx.drawImage(image,-image.width/2,-image.height/2);
    }

and without fade

    function drawImage(image,x,y,sx,sy,r){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.drawImage(image,-image.width/2,-image.height/2);
    }

or if you want to have the default transform after the call

    function drawImage(image,x,y,sx,sy,r){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.drawImage(image,-image.width/2,-image.height/2);
        ctx.setTransform(1,0,0,1,0,0);
    }

As you may want to render many images in a row you can restore the canvas context with

function restoreContext(){
    ctx.globalAlpha = 1;
    ctx.setTransform(1,0,0,1,0,0);
}

Upvotes: 1

Arg0n
Arg0n

Reputation: 8423

See this fiddle

HTML

<canvas id="canvas"></canvas>

JavaScript

var ctx = document.getElementById("canvas").getContext('2d');
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var img;

function draw() {
  img = new Image();
  img.onload = function(){
    setInterval(rotate, 10);
  };
  img.src = "https://pixabay.com/static/uploads/photo/2013/07/12/13/55/earth-147591_960_720.png";
}

draw();

var i = 0;
function rotate() {
  i += 1;
  drawRotatedImage(img, 100, 100, 200, 200, i);
}

var TO_RADIANS = Math.PI/180; 
function drawRotatedImage(image, x, y, width, height, angle) { 
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(angle * TO_RADIANS);
  ctx.drawImage(image, -width/2, -height/2, width, height);
  ctx.restore(); 
}

Upvotes: 0

Related Questions