如何停止requestAnimationFrame递归/循环? [英] How to stop a requestAnimationFrame recursion/loop?

查看:1064
本文介绍了如何停止requestAnimationFrame递归/循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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 函数时,事情就会中断!没有报告的错误,虽然...



设置基本上是这样的:


  • 页面上有一个 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是一个空的div
}

game.start();
}

以下是开始

  self.start =函数  ()
{
self.container.appendChild(game.renderer.domElement); //将渲染器的domElement添加到空的div
THREEx.FullScreen.request(self.container); //请求全屏div
self.renderer.setSize(screen.width,screen.height); //调整屏幕大小

self.startAnimating();
}

self.stop = function()
{
self.container.removeChild(game.renderer.domElement); //从div
self.renderer.setSize(0,0)中移除渲染器; //我猜这不是必须的,但welp

self.stopAnimating();
}

这和工作版本的唯一区别在于 start 和<方法调用> startAnimating stopAnimating code> stop 方法被注释掉了。

解决方案

,我发现它确实是我的其他代码造成了问题,而不是动画停止(毕竟这是一个简单的递归)。问题在于动态添加和从页面中移除渲染器的元素。在我停止这样做之后,因为没有理由这样做,并且在初始化发生时将其包括在内,所有事情都开始正常工作。


I'm using Three.js with the WebGL renderer to make a game which fullscreens when a play link is clicked. For animation, I use requestAnimationFrame.

I initiate it like this:

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;
}

When I want to, I call the startAnimating method, and yes, it does work as intended. But, when I call the stopAnimating function, things break! There are no reported errors, though...

The setup is basically like this:

  • There is a play link on the page
  • Once the user clicks the link, a renderer's domElement should fullscreen, and it does
  • The startAnimating method is called and the renderer starts rendering stuff
  • Once escape is clicked, I register an fullscreenchange event and execute the stopAnimating method
  • The page tries to exit fullscreen, it does, but the entire document is completely blank

I'm pretty sure my other code is OK, and that I'm somehow stopping requestAnimationFrame in a wrong way. My explanation probably sucked, so I uploaded the code to my website, you can see it happening here: http://banehq.com/Placeholdername/main.html.

Here is the version where I don't try to call the animation methods, and fullscreening in and out works: http://banehq.com/Correct/Placeholdername/main.html.

Once play is clicked the first time, the game initializes and it's start method is executed. Once the fullscreen exits, the game's stop method is executed. Every other time that play has been clicked, the game only executes it's start method, because there is no need for it to be initialized again.

Here's how it looks:

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

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

    game.start();
}

And here's how the start and stop methods look like:

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();
}

The only difference between this and the working version is that startAnimating and stopAnimating method calls in start and stop methods are commented out.

解决方案

So, after doing some more testing, I've found out that it was, indeed, my other code that posed a problem, not the animation stopping (it was a simple recursion after all). The problem was in dynamically adding and removing the renderer's domElement from the page. After I've stopped doing that, for there was really no reason to do so, and included it once where the initialization was happening, everything started working fine.

这篇关于如何停止requestAnimationFrame递归/循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆