2012-06-13 3 views
0

Я установил demo illustrating animation on a circle shape, и круг, кажется, дрогнул при рендеринге. Что заставляет анимацию быть лагги? Как я могу сделать его гладким?Моя анимация с использованием Рафаэля отстает, почему?

Я попытался заменить использование setInterval() звонком на animate(), что видно из прокомментированного кода, но безрезультатно.

var WINDOW_HEIGHT = 400; 
var WINDOW_WIDTH = 600; 

var paper = Raphael(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); 

Circle = function(paper, x, y, r, color) { 
    this.paper = paper; 
    this.x = x; 
    this.y = y; 
    this.r = r; 
    this.color = color; 
    this.xd = 1; 
    this.yd = 1; 
    this.elem; 
} 

Circle.prototype.create = function() { 
    this.elem = this.paper.circle(this.x, this.y, this.r); 
    this.elem.attr("fill", this.color); 
    this.elem.attr("stroke", this.color); 
} 

Circle.prototype.move = function() { 

    if (this.x < 0 || this.x > WINDOW_WIDTH) { 
     this.xd = -this.xd; 
    } 
    if (this.y < 0 || this.y > WINDOW_HEIGHT) { 
     this.yd = -this.yd; 
    } 
    this.x += this.xd; 
    this.y += this.yd; 

    this.elem.attr("cx", this.x); 
    this.elem.attr("cy", this.y); 
} 

Circle.prototype.animate = function(x, y) { 
    this.elem.animate({ 
     cx: x, 
     cy: y 
    }, 1000, "linear"); 
} 

var circle = new Circle(paper, 0, 0, 30, "#f00"); 

circle.create(); 

window.setInterval(function() { 
    circle.move(); 
}, 1); 

//circle.animate(300, 300);​​ 

ответ

3

Это побочный эффект вашего setInterval с интервалом в 1 миллисекунду. Браузеры не могут справиться с этим. Вместо этого, вычислить положение в зависимости от времени, и только запросить новый кадр, когда последний делается:

var _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function(f) { setTimeout(f, 16); }; 

var lastUpdate = new Date().getTime(); 

var update = function() { 
    // How many milliseconds has it been since the last update? 
    var now = new Date().getTime(); 
    var d = now - lastUpdate; 
    lastUpdate = now; 

    // Now, move the ball based on the difference. 
    // Looping is not the right way to go about this, mind. 
    var amountBallMoved = d/33; 

    for(var i = 0; i < amountBallMoved; i++) 
     circle.move(); 

    // And finally, request the next animation frame. 
    _requestAnimationFrame(update); 
}; 

update();​​​ 

Here's an updated jsFiddle.

Смежные вопросы