How can I animate an object in orbit using HTML5 Canvas?
Lets say I've already drawn all my objects, a sun in the middle and a couple of circl开发者_运维技巧es for planets. Can someone enlighten me as to how I make these objects move around in a circular fashion? I don't need any gravity etc but I suppose that could be a sweet bonus!
Thanks :)
Here's a crude solution:
var canvas = document.getElementById('scene');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var circle = function(color, r) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(0, 0, r, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.fill();
}
var i = 0;
var redraw = function() {
ctx.save();
// paint bg
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, w, h);
// set origin to center
ctx.translate(w / 2, h / 2);
// draw sun
circle('yellow', 20);
// rotate + move along x
ctx.rotate(i / 100);
ctx.translate(100, 0);
// draw planet
circle('green', 10);
ctx.restore();
i++;
window.requestAnimationFrame(redraw);
};
window.requestAnimationFrame(redraw);
You can find a demo here. Extend as needed. :)
in order to rotate a point in space (the point in this case is the position of the planet) you need to multiply the point's coordinates with a 2D transformation matrix, luckly, you don't need to worry about learning how to build this matrix or how to multiply a point with a matrix. The html5 canvas context has a rotate()
method which is gonna do it for you in every point that you draw after calling this function. The rotate()
method allows you to pass in an unic parameter which is the angle of rotation, but this angle needs to be converted into Radians. To converte an angle X into Radians you do the following:
var X = 10; // 10 degrees
var X_Radians = Math.PI / 180 * X;
// Now you pass this angle to the rotate method
context.rotate(X_Radians);
Ok, so now you know how to rotate a point in you canvas just don't forget to do the save and restore thing to not affect the others objects in the scene.
Now what you want here is to rotate a point around another point (the sun), when you rotate something on the canvas it is gonna orbitate around the (0,0) point, if your sun is not at the (0,0) position, then you need to translate (move) the point that you want to rotate in a way that the position of the sun is gonna be at the (0,0) position. To do this you only have to subtract the position of the sun from the position of the rotating point. Then apply the rotation, and then, translate (move) your point back to it's original position by adding the sun position that you subtracted from it before.
To translate your point you gonna use the translate()
method of the canvas context, so here we go (just don't mind that my planet and sun are rects):
var Planet_Position = {X: 400, Y: 250};
var Sun_Position = {X: 250, Y: 250};
// First, let's draw our sun and our planet
context.fillStyle = "#ffff00";
context.fillRect(Sun_Position.X, Sun_Position.Y, 10, 10);
context.fillStyle = "#0000ff";
context.fillRect(Planet_Position.X, Planet_Position.Y, 10, 10);
// Ok, so now we are going to rotate our planet around the sun and draw it again
context.save();
context.translate(Sun_Position.X, Sun_Position.Y);
context.rotate(-Math.PI / 180 * 10);
context.translate(-Sun_Position.X, -Sun_Position.Y);
context.fillRect(Planet_Position.X, Planet_Position.Y, 10, 10);
context.restore();
Ok, you might have noticed one awkward thing: That I said you needed to subtract the sun position from the planet position first and add it after rotating, but in the code above I apparentely added the sun position first and did the subtraction after, but that is just because of the order of the matrix multiplications that are going on under the hood, makes it reversed...
Nah, I hope I was clear, but geometric transformation is really a big subject to explain in such a short answer...
精彩评论