0

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();
    });

}
2
  • Can you share relevant code for creating and handling the webview? Commented Sep 20, 2017 at 13:47
  • @amacf I've added the relevant code examples Commented Sep 20, 2017 at 14:07

1 Answer 1

2

I've solved it after I narrowed it down to my canvas-resizing method. window.innerWidth and window.innerHeight are not set when window.onload is called, having an initial value of 0. They're only properly set after the window.onresize event is called, so listening for that and then scaling the canvas gives the proper result.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.