在iOS中调整WebGL上下文的大小

iOS WebGL有一个错误,可以用下面的HTML重现:

<html> <head> <title>Resize WebGL</title> <meta name="viewport" content="width=device-width, user-scalable=no"> </head> <body> <input type="button" id="resizeButton" value="resize"><br> <canvas id="chart" style="width:100px; height:100px; border:1px solid #000;"> <script> var canvas = document.getElementById('chart'); var gl = null; function resetGL() { var devicePixelRatio = 2; // Warning: overrides window.devicePixelRatio var w = Math.floor(canvas.clientWidth * devicePixelRatio); var h = Math.floor(canvas.clientHeight * devicePixelRatio); if (canvas.width != w || canvas.height != h) { console.log("resetGL: Setting canvas.width=" + w + " canvas.height=" + h); canvas.width = w; canvas.height = h; } if (!gl || gl.isContextLost()) { gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); console.log("Allocated WebGL context: " + gl); } } function redraw() { requestAnimationFrame(function () { resetGL(); gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.clearColor(1, 1, 0.8, 1); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); }); } var bToggle = false; function resize() { bToggle = !bToggle; var s = bToggle ? '50px' : '100px'; console.log(""); console.log("Button: Setting canvas.style.width=" + s + " canvas.style.height=" + s); canvas.style.width = s; canvas.style.height = s; redraw(); } var button = document.getElementById('resizeButton'); button.addEventListener("click", resize); redraw(); </script> </canvas> <br> Press "resize", and iOS stomps on this text! </body> </html> 

我已经把这个HTML上传到http://adam1234.s3-website-us-east-1.amazonaws.com/bug.html,所以你可以很容易的运行它。

对于没有iOS设备的人, 在按下button之前和之后 ,我已经上传了iPad的屏幕截图,显示了iOS中的错误。

此代码适用于桌面浏览器和Android,但在iOS中,resize的WebGL窗口会出现在Canvas之外,并踩在canvas外的东西。 这是iOS中的一个错误。 如果devicePixelRatio设置为1,错误消失,但我想使用更高分辨率的视网膜屏幕。

如何在iOS中调整高分辨率的WebGLcanvas?

我发现了一个解决方法。 应用程序应将WebGL <canvas>元素放入<div>中,并在<div>大小发生更改时重新创build<canvas>元素。 另外,<canvas>应该没有边框,以避免在视网膜显示器中将GL窗口放置在canvas内的厚边框的另一个iOS错误。 如果你想要一个边框,那就把边框放在<div>元素上。