Как остановить рекурсию/цикл 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, и визуализатор начинает рендеринг материала
  • После нажатия escape я регистрирую fullscreenchangeсобытие и выполните метод stopAnimating
  • Страница пытается выйти из полноэкранного режима, но весь документ полностью пуст

Я почти уверен, что мой другой код в порядке, и что я m каким-то образом остановил 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();
}

А вот как выглядят методы 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закомментированы.

63
задан corazza 24 May 2012 в 10:44
поделиться