2013-10-19 29 views
1

所以我想創建一個「動畫」模塊,基本上可以很容易地啓動和停止requestAnimationFrame循環requestAnimationFrame,非全局?

define(function(require, exports, module) { 
    var a = require('js/lib/stats.min.js' ); 

    function Animator(){ 

    this.stats = new Stats(); 
    this.stats.domElement.style.position = 'absolute'; 
    this.stats.domElement.style.bottom = '0px'; 
    this.stats.domElement.style.right  = '0px'; 
    this.stats.domElement.style.zIndex = '999'; 

    this.requestAnimationFrame = requestAnimationFrame; 

    document.body.appendChild(this.stats.domElement); 


    } 

    Animator.prototype.start = function(){ 
    this.animate(this); 
    } 

    Animator.prototype.stop = function(){ 

    if (requestId) { 
     cancelAnimationFrame(this.requestId); 
     this.requestId = undefined; 
    } 

    } 

    Animator.prototype.animate = function(){ 

    this.update(); 

    this.requestId = this.requestAnimationFrame(this.animate); 

} 


// Empty function, because it will be user defined 
Animator.prototype.update = function(){ 

} 

    return Animator 

}); 

正如你可以告訴我在這裏做一些違法的事情:

第一關我想將requestAnimationFrame分配給this.requestAnimationFrame。這是因爲在原型的.animate函數中,我希望能夠訪問此對象的更新函數。問題是,當我這樣做時,像這樣:

Animator.prototype.animate = function(){ 

    whichAnimator.update(); 

    whichAnimator.requestId = requestAnimationFrame(whichAnimator.animate(whichAnimator)); 

} 

我得到超過最大堆棧調用。

我想我想最好的辦法就是要做到這一點,因爲在這一點上我顯然不知道我在做什麼。

如果你有你的時間有任何疑問請詢問,並在此先感謝!

+1

可能要看看使用['bind'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/綁定)。這會讓你訪問'this'。 – kalley

+0

完美!直到今天,我甚至都不知道綁定,但它正是我所期待的! – Cabbibo

回答

1

.bind做到了!

感謝@kalley

Animator.prototype.start = function(){ 
    this.running = true; 
    this.animate(); 
} 

Animator.prototype.stop = function(){ 
    this.running = false; 
} 

Animator.prototype.animate = function(){ 

    this.stats.update(); 
    this.update(); 

    if(this.running == true){ 
    window.requestAnimationFrame(this.animate.bind(this)); 
    } 

} 
1

​​並不像setInterval工作,requestID將每個呼叫不同。所以把它分配給上下文是沒有任何意義的。

我覺得它更容易喘氣如果你只是運行一個單一的全球​​,然後調用你在循環中運行任何動畫。下面是一些粗略代碼:

var animations = {}; // holder for animation functions 

(function loop() { 
    for(var id in animations) { 
     animations[id](); 
    } 
    requestAnimationFrame(loop); 
}()); 

function start(fn) { 
    var id = +new Date(); 
    animations[id] = fn; 
    return id; 
} 
function stop(id) { 
    if (animations.hasOwnProperty(id)) { 
     delete animations[id]; 
    } 
}