use canvas created by hand rather than set renderwindow a div container

I want to use a canvas element already existing in the dom to actor as a container of a renderWindow, for example a vtkOpenGLRenderWindow. Does anyone know how to achieve this? I saw the vtkCanvasView object in the api, maybe useful to me, but I didn’t see any examole code…

You can try openglRenderWindow.set({ canvas: yourCanvasElement }) to see if that will work.

What is your use-case for this? It’s usually better to let vtkOpenGLRenderWindow control the canvas, and if you need a direct ref to the element, you can always call openglRenderWindow.getCanvas().

thank you for your reply. I want to “insert” a map in a vtkRenderWindow. I have found a library can do this job, called mappa.js, which treat the vtkRender canvas as a overlay of map div. In the official example, they integrate the Leaflet map or Google map with the Threejs, p5js. But when comes to vtkjs, the results is always discourage. In those official examples, a canvas is created by hand, set the map as a overlay of the canvas, then draw some graphics on the canvas using threejs. In vtkjs we can’t draw anything on the canvas comes from the openglRenderWindow.getCanvas() method, here is my simpe code:

import "vtk.js/Sources/favicon";

// Load the rendering pieces we want to use (for both WebGL and WebGPU)
import "vtk.js/Sources/Rendering/Profiles/Geometry";
import vtkFullScreenRenderWindow from "vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow";
import vtkActor from "vtk.js/Sources/Rendering/Core/Actor";
import vtkConeSource from "vtk.js/Sources/Filters/Sources/ConeSource";
import vtkMapper from "vtk.js/Sources/Rendering/Core/Mapper";
import vtkOpenGLRenderWindow from "vtk.js/Sources/Rendering/OpenGL/RenderWindow";
import vtkRenderWindow from "vtk.js/Sources/Rendering/Core/RenderWindow";
import vtkRenderWindowInteractor from "vtk.js/Sources/Rendering/Core/RenderWindowInteractor";
import vtkRenderer from "vtk.js/Sources/Rendering/Core/Renderer";
import vtkInteractorStyleTrackballCamera from "vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera";

import Mappa from "mappa-mundi/dist/mappa";

var fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
var actor = vtkActor.newInstance();
var mapper = vtkMapper.newInstance();
var cone = vtkConeSource.newInstance();

actor.setMapper(mapper);
mapper.setInputConnection(cone.getOutputPort());

const options = {
  lat: 0,
  lng: 0,
  zoom: 4,
  style: "http://{s}.tile.osm.org/{z}/{x}/{y}.png",
};
const mappa = new Mappa("Leaflet");
const myMap = mappa.tileMap(options);
const canvasElement = fullScreenRenderer.getContainer().firstChild;
myMap.overlay(canvasElement);
myMap.onChange(onChangeHandle);
function onChangeHandle() {
  console.log(canvasElement);
}
var renderer = fullScreenRenderer.getRenderer();
renderer.addActor(actor);
renderer.resetCamera();

var renderWindow = fullScreenRenderer.getRenderWindow();
renderWindow.render();

additionally, the openglRenderWindow.set({ canvas: yourCanvasElement })method does’t work…

In general you can not share the canvas between 2D and 3D rendering.
If I were you, I will create my own canvas and use the vtk.js on top with transparent background.

Thank you for you reply. I will try…

1 Like