setTimeout动画不起作用

时间:2013-12-26 08:32:28

标签: javascript

我试图将一个正方形的动画渐变为画布元素。当我为我的动画使用setInterval时,一切正常,但如果我尝试使用setTimeout,一切都会崩溃。这是我的代码: http://jsbin.com/OyiRIVa/1/edit

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
                              window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
/*class canvasUiElement*/
function canvasUiElement() {}
canvasUiElement.prototype = {
    canvas: document.getElementById("canvas"),
    context: canvas.getContext("2d")
}
/* ---------------------*/
function rectangle(x,y,length,width){
    this.x = x;
    this.y = y;
    this.opacity = 0  ;
    this.length = length;
    this.width = width;
}
rectangle.prototype = new canvasUiElement();
rectangle.prototype.renderSelf = function(){
    this.context.clearRect(this.x,this.y,this.length,this.width);
    this.context.fillStyle = "rgba(0,0,255,".concat(this.opacity.toString().concat(")"));
    this.context.fillRect(this.x,this.y,this.length,this.width);
}
rectangle.prototype.drawFrame = function(){
    this.opacity += .01;
    this.renderSelf();
    x = this.drawFrame;
    setTimeout(function(){x()}, 5); 
}
rect = new rectangle(20,10,50,50);
rect.drawFrame();
/*window.setInterval(function() {
    rect.drawFrame();
}, 1); */

1 个答案:

答案 0 :(得分:3)

问题可能在于this中的drawFrame关键字。当setTimeout触发时,this一侧不再是rect

解决方案正在使用applycallf.apply(self)将函数this中的f关键字绑定到第一个参数f

所以改变这种方式:

rectangle.prototype.drawFrame = function draw(){
  var self = this;
  this.opacity += 0.005;
  this.renderSelf();
  if (this.opacity < 1) {
    requestAnimationFrame(function(){
      draw.call(self)
    });
  }
};

看看这个JSBin。 http://jsbin.com/OwaHALUF/4/edit

========================

根据有效评论进行编辑:

    原始代码中的
  • x不是语义的,并且错过了var声明。固定的。
  • 首选requestAnimationFramesetTimeout
  • 如果不透明度&gt; = 1,则停止调用drawFrame(如果requestAnimationFrame不可用,则有用)
  • 更喜欢命名函数表达式而不是重新赋值。它减少了闭包开销。(如果动画持续时间足够长,这个开销可能不会被忽略)。更简洁的代码就是奖金。