I'm developing an HTML5 canvas-based game that's running in a WebView within an existing application. On first running the game, it loads successfully in the background, and all logs suggest it's ready and running. However, nothing is displayed in the WebView. If I load something else into the WebView and then return to my game, it loads successfully as before, and then renders. What could prevent a canvas from displaying on first being run, only to work on subsequent reloads?
For detail:
- I get no console errors on loading the game for the first time.
- The game loads successfully when running in the iOS version of the application.
- The CSS applied to the canvas element doesn't render, suggesting it isn't an issue loading my assets before displaying them.
All the issues I've investigated were caused by trying to render assets before they were displayed, so subsequent reloads were fixed by these now cached images being displayed, but I can't find anything concerning the canvas failing to display at all in Android.
Here's the HTML loaded by the WebView:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>Darts</title>
<meta name="description" content="Darts GamePad Game">
<script src="js/dummy-gamepad-functions.js"></script>
<script src="js/libs/polyfill.js"></script>
<script src="js/gamepad-client.js"></script>
<script src="js/darts-boot.js"></script>
<script src="js/darts-loader.js"></script>
<link rel="stylesheet" href="css/darts.css">
</head>
<body onload=bootGame()>
<div id="darts-game-container"></div>
</body>
</html>
And this is my onload script:
var bootGame = () => {
//create canvas element
let canvas = document.createElement('canvas');
canvas.id = "darts-canvas";
canvas.width = 740;
canvas.height = 400;
let gameContainer = document.getElementById("darts-game-container");
gameContainer.appendChild(canvas);
//scale canvas to view window
let gamepadViewport = document.getElementById("darts-game-container"),
gamepadCanvas = document.getElementById("darts-canvas"),
viewportWidth = window.innerWidth,
canvasWidth = gamepadCanvas.width,
viewportHeight = window.innerHeight,
canvasHeight = gamepadCanvas.height;
let scaleRatio = Math.min(viewportWidth/canvasWidth, viewportHeight/canvasHeight);
if (scaleRatio < 1) {
gamepadViewport.style.transform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.webkitTransform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.mozTransform = `scale(${scaleRatio}, ${scaleRatio})`;
gamepadViewport.style.oTransform = `scale(${scaleRatio}, ${scaleRatio})`;
}
//initialise Loader
Darts.Loader = new Loader();
//initialise GamePad API, then initialise core classes when loaded
GamePadClient = new GamePadClient();
GamePadClient.initialise()
.then(() => {
//load all scripts
return Darts.Loader.loadScripts(LIBS_TO_LOAD, COMMON_LIB_PATH, LIB_NAME_SUFFIX)
})
.then(() => {
return Darts.Loader.loadScripts(SCRIPTS_TO_LOAD, COMMON_SCRIPT_PATH, SCRIPT_NAME_SUFFIX)
})
.then(() => {
//initalise core classes
Darts.Controller = new Controller();
Darts.Logic = new Logic();
Darts.Display = new Display();
Darts.GameProps = new GameProps();
Darts.GameState = new GameState();
//loads display elements and scripts, then inits game once complete
Darts.Controller.initGame();
});
}