Мы разрабатываем сложное приложение, работающее на WebGL, и предлагаем нашим пользователям возможность сохранять скриншот текущей сцены. Хотя эта функция работает в Chrome и Firefox, мы сталкиваемся с несколькими проблемами в сафари.CanvasElement.toDataURL() для холстов WebGL
Пожалуйста, ознакомьтесь с нижеследующим кодом. Как вы можете видеть, мы используем метод CanvasElement toDataURL() для создания скриншотов. Хотя этот код работает так, как ожидалось, в других браузерах, он создает неправильные изображения в сафари (по крайней мере, для WebGL-холстов).
Вы можете легко воспроизвести проблему самостоятельно, открыв this file или выполнив прикрепленный фрагмент кода в сафари и других браузерах.
Мы делаем что-то неправильно? Существует ли обходное решение для этой проблемы?
спасибо.
UPD: Специально для тех, кто говорит, что это связано с preserveDrawingBuffer я изменил подключенному фрагмент кода, чтобы показать, что даже с preserveDrawingBuffer установлен верно, то это по-прежнему ведет себя неправильно в сафари.
<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>
<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>
<div>
<canvas id="canvas4" width="300" height="300"></canvas>
<img id="img4"/>
</div>
<div>
<canvas id="canvas5" width="300" height="300"></canvas>
<img id="img5"/>
</div>
<div>
<canvas id="canvas6" width="300" height="300"></canvas>
<img id="img6"/>
</div>
<script type="text/javascript">
function test(canvas, img, premultipliedAlpha, alpha, preserveDrawingBuffer) {
var gl = canvas.getContext("experimental-webgl", {
premultipliedAlpha: premultipliedAlpha,
alpha: alpha,
preserveDrawingBuffer: preserveDrawingBuffer
});
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, false);
test(document.getElementById("canvas2"), document.getElementById("img2"), false, true, false);
test(document.getElementById("canvas3"), document.getElementById("img3"), false, false, false);
test(document.getElementById("canvas4"), document.getElementById("img4"), true, true, true);
test(document.getElementById("canvas5"), document.getElementById("img5"), false, true, true);
test(document.getElementById("canvas6"), document.getElementById("img6"), false, false, true);
};
</script>
Его имя ['preserveDrawingBuffer'] (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext#Parameters) –
Возможный дубликат [Canvas toDataURL() возвращает только пустое изображение в Firefox] (http://stackoverflow.com/questions/26783586/canvas-todataurl-returns-blank-image-only-in-firefox) –
@ LJ_1102 Я не думаю, что это как-то связано с preserveDrawingBuffer: специально для вы создали [другой тестовый файл] (http://delightex.com/test/test1.html) с параметром preserveDrawingBuffer равным true. он по-прежнему работает неправильно в сафари. – appr