How to stop a requestAnimationFrame recursion/loop?

fullscreen, html, javascript, three.js, webgl

Solution

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.

Problem

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.

Original source