1

cancelAnimationFrame()在對象方法內部調用時似乎不起作用。我試圖將this的值綁定到回調函數(as demonstrated on MDNsetTimeout),但在使用cancelAnimationFrame()時收到TypeError。然後我嘗試將this值設置爲局部變量_this,並再次調用cancelAnimationFrame()。那一次,我沒有收到錯誤,但動畫本身仍在播放。我如何取消動畫?對象方法內部的cancelAnimationFrame不起作用

我重新創建了我在下面的問題。如果您打開控制檯窗口,您將看到動畫仍在運行。

function WhyWontItCancel() { 
 
    this.canvas = document.createElement("canvas"); 
 
    this.canvas.width = 200; 
 
    this.canvas.height = 10; 
 
    document.body.appendChild(this.canvas); 
 
    this.draw = this.canvas.getContext("2d"); 
 
    this.draw.fillStyle = "#f00"; 
 
    this.position = 0; 
 
}; 
 

 
WhyWontItCancel.prototype.play = function() { 
 
    if (this.position <= 190) { 
 
    this.draw.clearRect(0, 0, 400, 10); 
 
    this.draw.fillRect(this.position, 0, 10, 10); 
 
    this.position += 2; 
 
    } else { 
 
    //window.cancelAnimationFrame(this.animation.bind(this)); 
 
    var _this = this; 
 
    window.cancelAnimationFrame(_this.animation); 
 
    console.log("still running"); 
 
    } 
 

 
    this.animation = window.requestAnimationFrame(this.play.bind(this)); 
 
}; 
 

 
var animation = new WhyWontItCancel(); 
 
animation.play();

回答

1

看來你在這裏錯過兩樣東西。首先,this.animation = window.requestAnimationFrame(this.play.bind(this));行被調用總是play()被調用。與您可能認爲的相反,cancelAnimationFrame僅刪除先前請求的RAF呼叫。嚴格來說,這裏甚至沒有必要。其次,您不必綁定每個RAF電話;你可以這樣做只是一次:

function AnimatedCanvas() { 
    this.canvas = document.createElement("canvas"); 
    this.canvas.width = 200; 
    this.canvas.height = 10; 
    document.body.appendChild(this.canvas); 
    this.draw = this.canvas.getContext("2d"); 
    this.draw.fillStyle = "#f00"; 
    this.position = 0; 

    this.play = this.play.bind(this); // takes `play` from prototype object 
}; 

AnimatedCanvas.prototype.play = function() { 
    if (this.position <= 190) { 
    this.draw.clearRect(0, 0, 400, 10); 
    this.draw.fillRect(this.position, 0, 10, 10); 
    this.position += 2; 
    this.animationId = window.requestAnimationFrame(this.play); 
    } 
}; 

您可能要取消添加到您的原型可以停止你的動畫,例如:

AnimatedCanvas.prototype.cancel = function() { 
    if (this.animationId) { 
    window.cancelAnimationFrame(this.animationId); 
    } 
}; 

...但問題是,它的在問題描述的用例中沒有用處。

相關問題