globe.gl icon indicating copy to clipboard operation
globe.gl copied to clipboard

How to export a 2d picture from a rendered globe?

Open itismoej opened this issue 1 year ago • 4 comments

I want to export a 2d picture from a rendered globe which has many hexPolygon points on it. And use this picture as a background image in order to improve load-time and performance. Is it possible?

itismoej avatar Nov 12 '22 15:11 itismoej

Check out HTMLCanvasElement.toDataURL().

You can find many code samples & tutorials on how to export <canvas> data as an image. Search for "canvas to image" or "three.js save image".

I recommend closing this issue, as the solution is not specific to this project.

mrienstra avatar Nov 17 '22 17:11 mrienstra

toDataURL() consistently returns a blank image for me, regardless of how I call it and across multiple browsers; you can replicate by opening https://globe.gl/example/basic/ and using window.location = document.querySelector('canvas').toDataURL( 'png' ) (directly in JS, ref.renderer().domElement.toDataURL( 'png' ))

I've seen some notes that indicate it might need "finalising" or something before using this, but I can't see any relevant methods to call that might help with that.

rmccue avatar Nov 19 '22 12:11 rmccue

Yeah, hmm, sorry for the drive-by suggestion, it wasn't clear to me what had been tried already.

~~Looks like the library which powers this one has the same problem: https://vasturiano.github.io/three-globe/example/basic/~~

Oh, OK, that's not where the three.js renderer is setup, that's happening here: https://github.com/vasturiano/three-render-objects/blob/e771a35/src/three-render-objects.js#L373

Which is called here: https://github.com/vasturiano/globe.gl/blob/671a650/src/globe.js#L324-L329

As per https://github.com/vasturiano/globe.gl#initialisation, rendererConfig is passed to the ThreeJS WebGLRenderer constructor.

When initializing, e.g. here: https://github.com/vasturiano/globe.gl/blob/671a650/example/basic/index.html#L21

Globe()

... you need to specify preserveDrawingBuffer: true via rendererConfig:

Globe({
  rendererConfig: { preserveDrawingBuffer: true },
})

After making that change, I ran the following in the console:

const canvasEl = document.querySelector('canvas');
const imageEl = document.createElement('img');
imageEl.src = canvasEl.toDataURL();
document.body.appendChild(imageEl);

Which resulted in this image: image

mrienstra avatar Nov 21 '22 19:11 mrienstra

Yeah, hmm, sorry for the drive-by suggestion, it wasn't clear to me what had been tried already.

~Looks like the library which powers this one has the same problem: https://vasturiano.github.io/three-globe/example/basic/~

Oh, OK, that's not where the three.js renderer is setup, that's happening here: https://github.com/vasturiano/three-render-objects/blob/e771a35/src/three-render-objects.js#L373

Which is called here: https://github.com/vasturiano/globe.gl/blob/671a650/src/globe.js#L324-L329

As per https://github.com/vasturiano/globe.gl#initialisation, rendererConfig is passed to the ThreeJS WebGLRenderer constructor.

When initializing, e.g. here: https://github.com/vasturiano/globe.gl/blob/671a650/example/basic/index.html#L21

Globe()

... you need to specify preserveDrawingBuffer: true via rendererConfig:

Globe({
  rendererConfig: { preserveDrawingBuffer: true },
})

After making that change, I ran the following in the console:

const canvasEl = document.querySelector('canvas');
const imageEl = document.createElement('img');
imageEl.src = canvasEl.toDataURL();
document.body.appendChild(imageEl);

Which resulted in this image: image

This is not the image I'm looking for. I want the globe itself.

Assume that you have rendered a globe with many dots or hexPolygons on it; and you want to do this render of dots or hexPolygons once and export an image from it and use the image as globeImageUrl for the next times.

itismoej avatar Nov 21 '22 20:11 itismoej