[vtk.js] trackball/default interaction style with pan/zoom on other mouse buttons

Is there an easy way to enable pan with right-click on the default trackball interactor style? Currently, if I want to add pan with the right mouse button and zoom with the middle mouse button (the typical defaults for VTK applications), I define a new vtkInteractorStyleManipulator and set up those events plus all the defaults that the trackball interactor style handles.

For example:

import vtkInteractorStyleManipulator from 'vtk.js/Sources/Interaction/Style/InteractorStyleManipulator';
import vtkMouseCameraTrackballRotateManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseCameraTrackballRotateManipulator';
import vtkMouseCameraTrackballPanManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseCameraTrackballPanManipulator';
import vtkMouseCameraTrackballZoomManipulator from 'vtk.js/Sources/Interaction/Manipulators/MouseCameraTrackballZoomManipulator';


function vtkDefaultCameraInteractor () {
  const interactorStyle = vtkInteractorStyleManipulator.newInstance();

  const rotateManipulator = vtkMouseCameraTrackballRotateManipulator.newInstance();
  rotateManipulator.setButton(1); // Left Button

  const zoomManipulatorMiddleButton = vtkMouseCameraTrackballZoomManipulator.newInstance();
  zoomManipulatorMiddleButton.setButton(2); // Middle Button

  const zoomManipulatorScroll = vtkMouseCameraTrackballZoomManipulator.newInstance();

  const zoomManipulatorLeft = vtkMouseCameraTrackballZoomManipulator.newInstance();
  zoomManipulatorLeft.setButton(1); // Left Button

  const panManipulatorRightMouse = vtkMouseCameraTrackballPanManipulator.newInstance();
  panManipulatorRightMouse.setButton(3); // Right button

  const panManipulatorLeftMouse = vtkMouseCameraTrackballPanManipulator.newInstance();
  panManipulatorLeftMouse.setButton(1); // Left button

  return interactorStyle;

is there an easier way to do this where I can quickly enable those additional manipulators on the default trackball interactor style?

itk-vtk-viewer has an interesting approach where they use a list of objects defining these options here, but I cannot traceback where that is used to set up the camera… any tips?

This is using the Manipulators which is bundled in the View Proxy.

Ah, thanks for pointer. Since I am not using a View Proxy in my app, I can use the vtkInteractorStyleManipulator with the helpers in InteractionPresets to do this a bit easier:

import vtkInteractorStyleManipulator from 'vtk.js/Sources/Interaction/Style/InteractorStyleManipulator';
import InteractionPresets from 'vtk.js/Sources/Interaction/Style/InteractorStyleManipulator/Presets';


const interactorStyle = vtkInteractorStyleManipulator.newInstance();
InteractionPresets.applyPreset('3D', interactorStyle);

But since I want the right button to pan, I have to modifyy this to use other definitions than the presets in InteractionPresets:

import vtkInteractorStyleManipulator from 'vtk.js/Sources/Interaction/Style/InteractorStyleManipulator';
import InteractionPresets from 'vtk.js/Sources/Interaction/Style/InteractorStyleManipulator/Presets';


const interactorStyleDefinitions = [
  { type: 'pan', options: { button: 3 } }, // Pan on Right button drag
  { type: 'pan', options: { button: 1, shift: true } }, // Pan on Shift + Left button drag
  { type: 'zoom', options: { button: 1, control: true } }, // Zoom on Ctrl + Left button drag
  { type: 'zoom', options: { dragEnabled: false, scrollEnabled: true } }, // Zoom on scroll
  { type: 'rotate', options: { button: 1 } } // Rotate on Left button drag

const interactorStyle = vtkInteractorStyleManipulator.newInstance();
InteractionPresets.applyDefinitions(interactorStyleDefinitions, interactorStyle);

(figured I share in case someone else is trying to figure out how to more easily customize the interactor style)


Hi Bane and Sebastian, very useful discussion!
I have already changed some mouse and key combinations successfully. However I want to have more complex interaction. In c++ I am able to really control and create my interactors, but in vtk js it’s been a challange.

I am trying to do something similar to what Bane has, while mixing up with this example: https://kitware.github.io/vtk-js/examples/InteractorStyleMPRSlice.html

I am trying to add the part

but nothing is happening. Am I missing some options in the interactorStyleDefinitions ? or in the interactorStyle? I would like to be able to “parse” the mouse clicks as I do in c++.


You can make your own style if need be that way you could track mouseDown/Up/Move and so on.

For the modified, I would not expect the Style to be modified and therefore your callback should not be called. Could you attach the onModified on the camera? Or maybe there is another even type that is more inlined with what you want to listen to?

Could you explain when you want your callback to be triggered?

Hi Sebastien, thank you for your quick reply.

I am having a 2D rendering of slices with several actors. By using this, the window/level mouse interaction stops working on the CT - I assume it is because of the internal picker.
So I want to catch the mouse / keyboards interactions and set my own functions to control the scene and update the UI like in the example from MPRSlice
So from that example I see that the UI is updated with mouse interaction. I assume it comes from the

My original interactor was:

const iStyle = vtkInteractorStyleImage.newInstance();

You can create your own style which will give you everything that you want to catch and then, you can forward those calls to a vtkInteractorStyleImage if you extend it when you want to.

Basically, you want to create your own style.

yes, that would be ideal. But I dont know how to do it in JS. And I havent found an example doing so.
Do you have any resource around explaining how to do it?
Would be much appreciated!
Best regards

What you want to look at is probably the Manipulator style as it only forwarding those events to various instances of manipulators. And creating a style is just about exposing methods for the event that you want to handle and reacting to those by changing camera or doing something else.
The list of events you can monitor are available here.

So you just need to create methods with names like handle${EventName} in your style class.

1 Like