gallly
gallly

Reputation: 1211

trying to save an html5 canvas but its blank

I am using a website called cesium which shows me a globe of the world, it uses html5. Basically I want to save everything I see on the screen, I am new to html5/javascript...

Everytime I tried to save the canvas it kept showing me a blank black screen. I thought this maybe because the canvas has not finished loading so I put it inside an onload function. Also tried using a timer to sleep the script from saving until after it loads.

window.onload = function(){
    var scene = viewer.scene;
    var canvas = scene.canvas;
    var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
    window.location.href=image;
}

I also read it could be something related to CORS (cross origin resource sharing) but I am not getting any errors. Sorry I know this has been asked, but I am new to html5 and the other solutions did not help me.

edit:

Thanks for your help, as I am new to this I took a lot of time trying to understand it, even got a response on the cesium forum. I was hoping you could help me understand the issue some more..

require(['Cesium'], function(Cesium) {
    "use strict";

    // Cesium.CesiumWidget is similar to Cesium.Viewer, but
    // is trimmed down.  It is just a widget for the 3D globe;
    // it does not include the animation, imagery selection,
    // and other widgets, nor does it depend on the third-party
    // Knockout library.
    var widget = new Cesium.CesiumWidget('cesiumContainer',
        {
        contextOptions:{webgl:{preserveDrawingBuffer : true}
                           }});
    var scene = widget.scene;   

    var canvas = scene.canvas;
    var dataUrl = canvas.toDataURL("image/png");
    window.open(dataUrl,'Screenshot','toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');
    Sandcastle.finishedLoading();
});

this is my code, I set the preserveDrawingBuffer to true but I still get a blank image, the cesium forum told me this

We capture the WebGL canvas on a couple of projects including Doarama.  You need to initialize the WebGL context with preserveDrawingBuffer enabled before capturing.  This can be done in Cesium like this...

  var scene = new Cesium.Scene(canvas, {
    webgl : {
      preserveDrawingBuffer : true
    }
  }, creditContainer);

Upvotes: 2

Views: 3081

Answers (2)

Erik Hogan
Erik Hogan

Reputation: 41

I recognize this question is now old, but I had the same problem and came across the solution. When you initialize your Viewer you can pass in the option to preserveDrawingBuffer directly, like this:

viewer=new Cesium.Viewer('cesiumContainer',{
    contextOptions: {
        webgl:{preserveDrawingBuffer:true}
    }
});

This will give you the behavior you need.

Upvotes: 4

wendelbsilva
wendelbsilva

Reputation: 772

Edit:

You are right, the method toDataURL is a method of canvas, so its independent of the context we are using. The snipped I posted here (I will leave it in the end of the post) I used it to compose the various layer that I have.

I just tested here, and toDataURL only worked fine after setting preserveDrawingBuffer: true.

gl = canvas.getContext("experimental-webgl",{preserveDrawingBuffer:true});

Here's the trick part. Assuming that you cant modified the code and you celsium get the context only once. You can override the variable assigned to the context with a new context but now with this parameter. I havent tried this on celsium yet, but worked it worked in this example.

Unfortunately, I dont have time right now to find where exactly cesium get the context and if it only get once. Although, I was able to track the context 'creation' down to:

this._originalGLContext=i.getContext("webgl",s)||i.getContext("experimental-webgl",s);
this._gl=this._originalGLContext;

Anyway, I hope you have access to the code and can just add the preserveDrawingBuffer parameter.

var dataUrl = document.getElementById("webglCanvas").toDataURL("image/png");
window.open(dataUrl,'Screenshot','toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,copyhistory=yes, resizable=yes');

Upvotes: 3

Related Questions