如何停止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(); }
以下是start
和stop
方法的样子:
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(); }
这个和工作版本的唯一区别在于startAnimating
和stopAnimating
方法在start
和stop
方法中的调用被注释掉了。
一种开始/停止的方式就是这样
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元素。 在我停止这样做之后,因为没有理由这样做,并且在初始化发生的地方包括了一次,一切都开始正常工作。