簡體   English   中英

如何停止 requestAnimationFrame 遞歸/循環?

[英]How to stop a requestAnimationFrame recursion/loop?

我正在使用 Three.js 和 WebGL 渲染器來制作一個點擊play鏈接時全屏顯示的游戲。 對於動畫,我使用requestAnimationFrame

我是這樣啟動的:

self.animate = function()
{
    self.camera.lookAt(self.scene.position);

    self.renderer.render(self.scene, self.camera);

    if (self.willAnimate)
        window.requestAnimationFrame(self.animate, self.renderer.domElement);
}

self.startAnimating = function()
{
    self.willAnimate = true;
    self.animate();
}

self.stopAnimating = function()
{
    self.willAnimate = false;
}

當我需要時,我會調用startAnimating方法,是的,它確實按預期工作。 但是,當我調用stopAnimating函數時,事情就stopAnimating 沒有報告錯誤,但...

設置基本上是這樣的:

  • 頁面上有play鏈接
  • 用戶單擊鏈接后,渲染器的domElement應全屏顯示,並且確實如此
  • startAnimating方法被調用,渲染器開始渲染東西
  • 單擊轉義后,我注冊一個fullscreenchange事件並執行stopAnimating方法
  • 頁面嘗試退出全屏,確實如此,但整個文檔完全空白

我很確定我的其他代碼沒問題,而且我不知何故以錯誤的方式停止requestAnimationFrame 我的解釋可能很糟糕,所以我將代碼上傳到我的網站,您可以在這里看到它發生的情況: http : //banehq.com/Placeholdername/main.html

這是我不嘗試調用動畫方法和全屏輸入和輸出工作的版本: http : //banehq.com/Correct/Placeholdername/main.html

一旦第一次點擊play ,游戲就會初始化並執行它的start方法。 一旦全屏退出,就會執行游戲的stop方法。 每隔一次點擊play ,游戲只執行它的start方法,因為不需要再次初始化它。

這是它的外觀:

var playLinkHasBeenClicked = function()
{
    if (!started)
    {
        started = true;

        game = new Game(container); //"container" is an empty div
    }

    game.start();
}

下面是startstop方法的樣子:

self.start = function()
{
    self.container.appendChild(game.renderer.domElement); //Add the renderer's domElement to an empty div
    THREEx.FullScreen.request(self.container);  //Request fullscreen on the div
    self.renderer.setSize(screen.width, screen.height); //Adjust screensize

    self.startAnimating();
}

self.stop = function()
{
    self.container.removeChild(game.renderer.domElement); //Remove the renderer from the div
    self.renderer.setSize(0, 0); //I guess this isn't needed, but welp

    self.stopAnimating();
}

此版本與工作版本之間的唯一區別是startAnimatingstopAnimating方法在startstop方法中的調用被注釋掉了。

一種啟動/停止方式是這樣的

var requestId;

function loop(time) {
    requestId = undefined;

    ...
    // do stuff
    ...

    start();
}

function start() {
    if (!requestId) {
       requestId = window.requestAnimationFrame(loop);
    }
}

function stop() {
    if (requestId) {
       window.cancelAnimationFrame(requestId);
       requestId = undefined;
    }
}

工作示例:

 const timeElem = document.querySelector("#time"); var requestId; function loop(time) { requestId = undefined; doStuff(time) start(); } function start() { if (!requestId) { requestId = window.requestAnimationFrame(loop); } } function stop() { if (requestId) { window.cancelAnimationFrame(requestId); requestId = undefined; } } function doStuff(time) { timeElem.textContent = (time * 0.001).toFixed(2); } document.querySelector("#start").addEventListener('click', function() { start(); }); document.querySelector("#stop").addEventListener('click', function() { stop(); });
 <button id="start">start</button> <button id="stop">stop</button> <div id="time"></div>

停止就像不再調用 requestAnimationFrame 一樣簡單,而重新啟動就是再次調用它。 前任)

        var pause = false;
        function loop(){
                //... your stuff;
                if(pause) return;
                window.requestionAnimationFrame(loop);
        }
       loop(); //to start it off
       pause = true; //to stop it
       loop(); //to restart it

我建議查看requestAnimationFrame polyfill gibhub 頁面。 有關於如何實施的討論。

因此,在進行了更多測試之后,我發現確實是我的其他代碼造成了問題,而不是動畫停止(畢竟這是一個簡單的遞歸)。 問題在於從頁面動態添加和刪除渲染器的 domElement。 在我停止這樣做之后,因為真的沒有理由這樣做,並且在初始化發生的地方包含它一次,一切都開始正常工作。

我玩了一個2D Breakout Game的教程,他們也使用了 requestAnimationFrame ,我用一個簡單的return停止了它。 如果省略 return 的值,則 return 語句結束函數執行。

if(!lives) {
    alert("GAME OVER");
    return;
}

// looping the draw()
requestAnimationFrame(draw);
var myAnim //your requestId
function anim()
       {
       //bla bla bla
       //it's important to update the requestId each time you're calling reuestAnimationFrame
       myAnim=requestAnimationFrame(anim)
       }

讓我們開始吧

myAnim=requestAnimationFrame(anim)

讓我們停下來

//the cancelation uses the last requestId
cancelAnimationFrame(myAnim)

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM