如何停止requestAnimationFramerecursion/循环?

我正在使用WebGL渲染器的Three.js来制作一个游戏,当点击一个play链接时,它将全屏显示。 对于animation,我使用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 。

这里是我不试图调用animation方法,并进行全屏播放的版本: http : //banehq.com/Correct/Placeholdername/main.html 。

一旦第一次点击游戏,游戏初始化并执行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) { ... // do stuff ... start(); } function start() { if (!requestId) { requestId = window.requestAnimationFrame(loop); } } function stop() { if (requestId) { window.cancelAnimationFrame(requestId); requestId = undefined; } } 

停止就像不再调用requestAnimationFrame一样简单,重新启动就是再次调用它。 EX)

  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 

我会build议看一下requestAnimationFrame polyfill gibhub页面。 有关于如何实施的讨论。

所以,在做了更多的testing之后,我发现其实我的其他代码存在问题,而不是animation停止(毕竟这是一个简单的recursion)。 问题在于dynamic添加和从页面中删除渲染器的DOM元素。 在我停止这样做之后,因为没有理由这样做,并且在初始化发生的地方包括了一次,一切都开始正常工作。