可以說,我已經畫出了所有的物體,中間有一個太陽和行星的幾個圈。有人能夠啓發我如何讓這些物體以循環方式移動嗎?我不需要任何重力等,但我想這可能是一個甜蜜的獎金!如何使用HTML5 Canvas在軌道上對物體進行動畫處理?
謝謝:)
可以說,我已經畫出了所有的物體,中間有一個太陽和行星的幾個圈。有人能夠啓發我如何讓這些物體以循環方式移動嗎?我不需要任何重力等,但我想這可能是一個甜蜜的獎金!如何使用HTML5 Canvas在軌道上對物體進行動畫處理?
謝謝:)
這裏有一個粗液:
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。根據需要擴展。 :)
爲了旋轉空間中的一個點(這種情況下的點是行星的位置),您需要將點的座標與2D變換矩陣相乘,幸運的是,您不必擔心學習如何構建這個矩陣或者如何將一個點與一個矩陣相乘。 html5 canvas上下文有一個rotate()
方法,它會在你調用這個函數之後繪製的每一點上爲你做。方法rotate()
允許你傳入一個單一的參數,這是一個旋轉角度,但是這個角度需要被轉換成弧度。要轉換器具的角度X爲弧度您執行以下操作:
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();
好吧,你可能有注意到一件尷尬的事情:我說你需要首先從行星位置減去太陽位置並在旋轉後添加它,但在上面的代碼中,我明確地首先添加了太陽位置並在之後進行了減法,但那只是因爲在引擎蓋下進行的矩陣乘法的順序使其反轉...
那麼,我希望我很清楚,但幾何變換真的是一個很大的問題,在這樣一個簡短的答案中解釋...
你爲什麼要做'i/100'而不是'Math.PI/180 * i' ?? – Delta 2011-05-11 19:27:56
我剛剛在那裏發現了一些似乎運作良好的因素。沒有真正的原因。 :) – 2011-05-11 19:44:19
該解決方案是非常不理想的順便說一句。重繪可能更有效(重繪僅修改位)。它的結構也可能更好(根據conf定義行星+可能的衛星等)。我可能會考慮稍後修復這些問題。 – 2011-05-11 19:46:26