问题
iOS WebGL has a bug, which can be reproduced with following 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>
I have uploaded this HTML to http://adam1234.s3-website-us-east-1.amazonaws.com/bug.html so you can run it easily.
For people who don't have an iOS device, I have uploaded screenshots of my iPad before and after pressing the button, which show the bug in iOS.
This code works on desktop browsers and Android, but in iOS the resized WebGL window goes outside the Canvas and stomps on stuff outside the canvas. This is a bug in iOS. The bug goes away if devicePixelRatio
is set to 1, but I want to use the higher resolution of retina screens.
How can I resize a high resolution WebGL canvas in iOS?
回答1:
I found a work-around. The app should put the WebGL <canvas> element inside a <div>, and recreate the <canvas> element whenever the <div> size changes. Also, the <canvas> should have no border to avoid another iOS bug in placing the GL window inside the canvas with thick border in retina displays. If you want a border, then just put the border on the <div> element.
来源:https://stackoverflow.com/questions/35745878/resize-webgl-context-in-ios