We develop complex WebGL powered application and offer our users an ability to save screenshot of the current scene. While this feature works as expected in Chrome and Firefox, we are facing several issues in safari.
Please take a look at the following code. As you can see, we use toDataURL() method of CanvasElement to make screenshots. While this code works as expected in other browsers, it produces wrong images in safari (at least for WebGL canvases).
You can easily reproduce the issue yourself by openning this file in safari and other browsers.
Are we doing something wrong? Is there workaround for this issue?
Thank you.
<html>
<head>
<script type="text/javascript" src="http://www.html5rocks.com/en/tutorials/webgl/webgl_fundamentals/webgl/resources/webgl-utils.js"></script>
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0, 1);
}
</script>
<script id="2d-fragment-shader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(0,1,0,1); // green
}
</script>
</head>
<body>
<div>
<canvas id="canvas1" width="300" height="300"></canvas>
<img id="img1"/>
</div>
<div>
<canvas id="canvas2" width="300" height="300"></canvas>
<img id="img2"/>
</div>
<div>
<canvas id="canvas3" width="300" height="300"></canvas>
<img id="img3"/>
</div>
<script type="text/javascript">
function test(canvas, img, premultipliedAlpha, alpha) {
var gl = canvas.getContext("experimental-webgl", {premultipliedAlpha: premultipliedAlpha, alpha: alpha});
var vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
var fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");
var program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);
var positionLocation = gl.getAttribLocation(program, "a_position");
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
1.0, -1.0,
1.0, 1.0
]),
gl.STATIC_DRAW
);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 5);
img.src = canvas.toDataURL();
}
window.onload = function() {
test(document.getElementById("canvas1"), document.getElementById("img1"), true, true);
test(document.getElementById("canvas2"), document.getElementById("img2"), false, true);
test(document.getElementById("canvas3"), document.getElementById("img3"), false, false);
};
</script>
</body>
</html>
I think it's worth noting that this was reported as safari issue #17361233 exactly one year ago. Since then we received no answers at all and the issue is still in "Open" state.