HTML5 - 在 Android WebView 中首次加载时未呈现画布

Posted

技术标签:

【中文标题】HTML5 - 在 Android WebView 中首次加载时未呈现画布【英文标题】:HTML5 - Canvas not rendering on first load in Android WebView 【发布时间】:2018-03-01 14:21:35 【问题描述】:

我正在开发一个基于 html5 画布的游戏,该游戏在现有应用程序的 WebView 中运行。首次运行游戏时,它会在后台成功加载,所有日志都表明它已准备好并正在运行。但是,WebView 中不显示任何内容。如果我将其他内容加载到 WebView 然后返回到我的游戏,它会像以前一样成功加载,然后渲染。什么会阻止画布在第一次运行时显示,而只能在后续重新加载时工作?

详情:

第一次加载游戏时没有控制台错误。 游戏在 ios 版本的应用程序中运行时加载成功。 应用于 canvas 元素的 CSS 未呈现,这表明在显示之前加载我的资产不是问题。

我调查的所有问题都是由于在显示资产之前尝试渲染资产造成的,因此随后的重新加载通过这些现在缓存的图像被显示修复,但我找不到任何关于画布无法显示的信息在 android 中。

这是 WebView 加载的 HTML:

<!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>

这是我的加载脚本:

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


【问题讨论】:

你能分享创建和处理webview的相关代码吗? @amacf 我已经添加了相关的代码示例 【参考方案1】:

在我将其缩小到我的画布调整大小方法后,我已经解决了这个问题。调用 window.onload 时未设置 window.innerWidth 和 window.innerHeight,初始值为 0。它们仅在调用 window.onresize 事件后正确设置,因此监听该事件然后缩放画布给出正确的结果。

【讨论】:

以上是关于HTML5 - 在 Android WebView 中首次加载时未呈现画布的主要内容,如果未能解决你的问题,请参考以下文章

WebView 中的 Android HTML5 视频

Android webview html5地理定位

HTML5 - 在 Android WebView 中首次加载时未呈现画布

html5 视频不适用于 android webview

通过 Android WebView 在 YouTube HTML5 视频中搜索

无法在 Android 4.2.2 上运行的 Webview 上自动启动 html5 视频