2

所以我只是用 Raphael JS 做一个基本的轨道模拟器,我画一个圆圈作为“星”,另一个圆圈作为“行星”。它似乎工作得很好,一个障碍是随着模拟的继续,它的帧速率逐渐减慢,直到轨道运动不再显得流畅。这是代码(注意:仅使用 jQuery 来初始化页面):

$(function() {
    var paper = Raphael(document.getElementById('canvas'), 640, 480);
    var star = paper.circle(320, 240, 10);
    var planet = paper.circle(320, 150, 5);
    var starVelocity = [0,0];
    var planetVelocity = [20.42,0];
    var starMass = 3.08e22;
    var planetMass = 3.303e26;
    var gravConstant = 1.034e-18;
    function calculateOrbit() {
        var accx = 0;
        var accy = 0;
        accx = (gravConstant * starMass * ((star.attr('cx') - planet.attr('cx')))) / (Math.pow(circleDistance(), 3));
        accy = (gravConstant * starMass * ((star.attr('cy') - planet.attr('cy')))) / (Math.pow(circleDistance(), 3));
        planetVelocity[0] += accx;
        planetVelocity[1] += accy;
        planet.animate({cx: planet.attr('cx') + planetVelocity[0], cy: planet.attr('cy') + planetVelocity[1]}, 150, calculateOrbit);
        paper.circle(planet.attr('cx'), planet.attr('cy'), 1); // added to 'trace' orbit
    }
    function circleDistance() {
        return (Math.sqrt(Math.pow(star.attr('cx') - planet.attr('cx'), 2) + Math.pow(star.attr('cy') - planet.attr('cy'), 2)));
    }
    calculateOrbit();
});

无论如何,对我来说,该代码的任何部分都不会导致动画逐渐减慢到爬行,因此任何解决问题的帮助将不胜感激!

4

1 回答 1

3

问题在于在您的 planet.animate() 调用中对 calculateOrbit 的回调。它没有被 raphael 正确处理,导致内存泄漏或执行速度变慢。如果您将其删除并替换该行

calculateOrbit()

setInterval(calculateOrbit, 150);

它应该运行顺利。

完整代码:

$(function() {
var paper = Raphael(document.getElementById('canvas'), 640, 480);
var star = paper.circle(320, 240, 10);
var planet = paper.circle(320, 150, 5);
var starVelocity = [0,0];
var planetVelocity = [20.42,0];
var starMass = 3.08e22;
var planetMass = 3.303e26;
var gravConstant = 1.034e-18;
function calculateOrbit() {
    var accx = 0;
    var accy = 0;
    accx = (gravConstant * starMass * ((star.attr('cx') - planet.attr('cx')))) / (Math.pow(circleDistance(), 3));
    accy = (gravConstant * starMass * ((star.attr('cy') - planet.attr('cy')))) / (Math.pow(circleDistance(), 3));
    planetVelocity[0] += accx;
    planetVelocity[1] += accy;
    planet.animate({cx: planet.attr('cx') + planetVelocity[0], cy: planet.attr('cy') + planetVelocity[1]}, 150);
    paper.circle(planet.attr('cx'), planet.attr('cy'), 1); // added to 'trace' orbit
}
function circleDistance() {
    return (Math.sqrt(Math.pow(star.attr('cx') - planet.attr('cx'), 2) + Math.pow(star.attr('cy') - planet.attr('cy'), 2)));
}
setInterval(calculateOrbit, 150);
});
于 2010-05-19T18:35:02.270 回答