Reputation: 1211
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
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
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