2015-06-26 4 views
1

Мы разрабатываем сложное приложение, работающее на 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>

+0

Его имя ['preserveDrawingBuffer'] (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext#Parameters) –

+1

Возможный дубликат [Canvas toDataURL() возвращает только пустое изображение в Firefox] (http://stackoverflow.com/questions/26783586/canvas-todataurl-returns-blank-image-only-in-firefox) –

+0

@ LJ_1102 Я не думаю, что это как-то связано с preserveDrawingBuffer: специально для вы создали [другой тестовый файл] (http://delightex.com/test/test1.html) с параметром preserveDrawingBuffer равным true. он по-прежнему работает неправильно в сафари. – appr

ответ

0

Наткнулся на эту проблему сам. Я думаю, что это просто ошибка в сафари: когда вы устанавливаете premultipliedAlpha: false при получении контекста gl, canvas.toDataURL() вернет обратное изображение. Отправил отчет об ошибке в яблоко.

Смежные вопросы