如何使用HTML5 Canvas为轨道中的对象设置动画?

时间:2011-05-11 12:30:05

标签: html5 canvas physics game-physics

让我们说我已经绘制了所有的物体,中间的太阳和行星的几个圆圈。有人可以告诉我如何让这些物体以循环方式移动吗?我不需要任何重力等但我想这可能是一个很好的奖励!

谢谢:)

2 个答案:

答案 0 :(得分:5)

这是一个粗略的解决方案:

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

您可以找到演示here。根据需要扩展。 :)

答案 1 :(得分:3)

为了旋转空间中的一个点(在这种情况下,点是行星的位置),您需要将点的坐标与2D变换矩阵相乘,幸运的是,您不必担心学习如何构建此矩阵或如何将点与矩阵相乘。 html5画布上下文有一个rotate()方法,它会在你调用这个函数后绘制的每个点上为你做。 rotate()方法允许您传入一个旋转角度的unic参数,但此角度需要转换为Radians。要将角度X转换为Radians,请执行以下操作:

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

好的,现在您知道如何在画布中旋转一个点,只是不要忘记执行保存和恢复操作以不影响场景中的其他对象。

现在你想要的是围绕另一个点(太阳)旋转一个点,当你在画布上旋转一些东西时它会围绕(0,0)点进行轨道运动,如果你的太阳不在(0) ,0)位置,然后你需要翻译(移动)你想要旋转的点,使太阳的位置在(0,0)位置。要做到这一点,你只需要从旋转点的位置减去太阳的位置。然后应用旋转,然后通过添加之前从中减去的太阳位置将点移动(移动)到原始位置。

要翻译你的观点,你将使用画布上下文的translate()方法,所以我们走了(只是不要介意我的星球和太阳是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();

好吧,你可能已经注意到一个尴尬的事情:我说你需要首先从行星位置减去太阳位置并在旋转后添加它,但是在上面的代码中我显然首先添加了太阳位置并进行了减法之后,但这仅仅是因为在引擎盖下进行矩阵乘法的顺序,使其反转...

不,我希望我很清楚,但几何变换确实是一个很大的主题,可以在如此短的答案中解释......