How do I call renderer.GetActiveCamera() in JavaScript using VTK/WASM?

I am trying to access the current camera object from the frontend (JavaScript) in a VTK/WASM project.

In the “pure-js” example in the trame-vtklocal repository, there is a file called main.js. For the purposes of this question, I would simply like to add the line renderer.GetActiveCamera().Zoom(0.5) to this file. However, I do not know how to access the current vtkRenderer object inside this file.

Here is a link to the main.js file: trame-vtklocal/examples/pure-js/client/main.js at master · Kitware/trame-vtklocal · GitHub

Do I have to compile a custom version of the VTK/WASM binary with bindings in order to access these underlying VTK functions from the frontend?

I’m trying to avoid making a server round trip that the usual await trame.trigger() technique does.

renderer.GetActiveCamera().Zoom(0.5).

That will need the vtkCamera class and it’s member functions wrapped for javascript. Instead, we are thinking to enable function calls on object ids. So something like this might work in the future:

camera_id = rendererState.ActiveCamera.Id;
this.wasm.sceneManager.call(camera_id, "Zoom", 0.5);

What I don’t like about this is that code intellisense will not be able to tell you that there is a method called “Zoom” on the camera, and that it takes one floating point value.

fyi, @Sebastien_Jourdain

1 Like

Thanks for the quick response. A related question I have involves event listeners, also in VTK/WASM. Is there a way to add an event listener on the frontend in VTK/WASM to detect when a user has zoomed in or out?

For example, in the main.js file, how would I detect when a user has zoomed in or out? What is the best way to do this in VTK/WASM?

Hopefully setting event listeners doesn’t also require recompiling the wasm JS bindings c++.

You can attach listeners to the WASM objects. See

1 Like

Thank you. I have been studying the example at the link you provided, but I still don’t know where to begin to attach a listener to a hypothetical “OnCameraZoom” event (I made up that event name).

Can you provide a simple JavaScript example here of how I can do this, or point me to an example of a real camera event being set using createExtractCallback() and sceneManager.addObserver()?

I’m working in the mindset of the well-known convention Object.addEventListener(eventName, callbackFunction) in JavaScript, where I simply provide the event name and the function.

I see this createExtractCallback function declared in many VTK/WASM examples, but I’m not exactly sure where I would provide my own plain JavaScript event handler function to it like you can with the Object.addEventListener() example mentioned above. Can you point me to the documentation for the createExtractCallback function, and how it interacts with sceneManager.addObserver()?

Its signature takes the following three arguments. I’m not sure what extractInfo should be:

trame: a Trame object
wasmManager: a VtkWASMHandler object
extractInfo: ??

function createExtractCallback(trame, wasmManager, extractInfo) {
    return function () {
        wasmManager.clearStateCache();
        for (const [name, props] of Object.entries(extractInfo)) {
            const value = {};
            for (const [propName, statePath] of Object.entries(props)) {
                value[propName] = wasmManager.getStateValue(statePath, true);
            }
            trame.state.set(name, value);
        }
        wasmManager.clearStateCache();
    };
}

For pure JS (no trame), you should be able to do something like:

function print_state(wasm_id) {
   console.log(wasmManager.getState(wasm_id));
}

wasmManager.cameraIds.forEach((camera_id) => {
    wasmManager.sceneManager.addObserver(
       camera_id, 
      "ModifiedEvent", // VTK Event to listen to
      () => print_state(camera_id),
    )
});


VTK has its own events which you can find here when clicking on vtkCommand from the AddObserver method.

1 Like

Thanks so much, that helped tremendously. I was able to achieve the functionality I needed with that example.

1 Like