Problem
I'm using a space invaders canvas animation as my 404 not found page. It is working pretty fine when the user is redirected to it for the first time, but the animation hangs if the user is redirected a second time.
Demo
I've created a Plunker example to show the issue. The page starts at the /
location loading the home.html. If you click on "Redirect to /404", the location will be changed to /404
and 404.html will be loaded. The game animation will be running without problems.
However, if you go back to /
(clicking in the link) and back again to /404
, the animation will be hanged. Also, the frames-per-second will drop from 60fps to 10fps.
Code
This demo was built with AngularJS and I switch pages using ngRoute like the following: (nothing special in this)
$routeProvider.
when('/', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
}).
when('/404', {
templateUrl: 'partials/404.html',
controller: '404Ctrl'
});
The home.html contains just instructions and 404.html contains the canvas element:
<canvas id="game-canvas" width="600" height="400"></canvas>
The Angular Controller starts the animation calling initInvaders404();
. This function is defined inside handle-game.js. The game.js completes the canvas animation code that is executed as soon as the 404.html page is loaded.
What I've already tried
First guess: the issue may be related with the canvas being started using its ID. When I recreate the 404.html, the animation is attached with the previous ID but not with the newer ID. To test this, I've created another Plunker and tested another animation (blue rectangle moving) with a similar approach. It is working fine, so maybe that's not the problem.
Second guess: the animation code that is attached to the canvas is executed only once, that's why it does not work a second time. To test this, I've placed the game.js and handle-game.js code inside the controller. Unfortunately, same issue. Plunker
Third guess: ngRoute is messing with the canvas element. To test this, I've placed the canvas element out of the ngView and controlled the ngShow to hide/show the canvas. With this approach, the problem was solved. The initInvaders404();
can be called multiple times, but it will always focus in the same element and it will never be recreated. Plunker.
Question
Why this animation can't be executed two times?
Note1: I do not want a workaround solution (I've already found one in my third guess). I would like to keep the canvas element inside the 404.html file.
Note2: this question is not a "please, debug my code" (since game.js have 2000 lines of code). What I want to understand is if there is a canvas property or ngRoute behavior that may cause this.