Synchronizers
Synchronizers can be used to link particular actions across viewports (e.g. sync pan/zoom interaction), but they can also be used to tie any callback to a particular event. Synchronizers require:
- An
Event
to listen for - A function to call when that event is raised on a source viewport
- An array of
source
viewports - An array of
target
viewports
The provided function receives the event, source viewports, and target viewports, and is often used to check “some value” on the source viewport. The function then updates the target viewports, often using public API exposed by the core library, to match that state/value.
Usage
The SynchronizerManager
exposes similar API to that of the ToolGroupManager
. A
created Synchronizer has methods like addTarget
, addSource
, add
(which adds
the viewport as a "source" and a "target"), and equivalent remove*
methods.
Synchronizers will self-remove sources/targets if the viewport becomes disabled.
Synchronizers also expose a disabled
flag that can be used to temporarily prevent
synchronization.
import { Enums } from '@cornerstonejs/core';
import { SynchronizerManager } from '@cornerstonejs/tools';
const cameraPositionSynchronizer = SynchronizerManager.createSynchronizer(
'synchronizerName',
Enums.Events.CAMERA_MODIFIED,
(
synchronizerInstance,
sourceViewport,
targetViewport,
cameraModifiedEvent
) => {
// Synchronization logic should go here
}
);
// Add viewports to synchronize
const firstViewport = { renderingEngineId, viewportId };
const secondViewport = {
/* */
};
sync.addSource(firstViewport);
sync.addTarget(secondViewport);
Built-in Synchronizers
We have currently implemented two synchronizers that can be used right away,
Position Synchronizer
It synchronize the camera properties including the zoom, pan and scrolling between the viewports.
const ctAxial = {
viewportId: VIEWPORT_IDS.CT.AXIAL,
type: ViewportType.ORTHOGRAPHIC,
element,
defaultOptions: {
orientation: Enums.OrientationAxis.AXIAL,
},
};
const ptAxial = {
viewportId: VIEWPORT_IDS.PT.AXIAL,
type: ViewportType.ORTHOGRAPHIC,
element,
defaultOptions: {
orientation: Enums.OrientationAxis.AXIAL,
background: [1, 1, 1],
},
};
const axialSync = createCameraPositionSynchronizer('axialSync')[
(ctAxial, ptAxial)
].forEach((vp) => {
const { renderingEngineId, viewportId } = vp;
axialSync.add({ renderingEngineId, viewportId });
});
Internally, upon camera modified event on the source viewport, cameraSyncCallback
runs to synchronize all the target viewports.
VOI Synchronizer
It synchronizes the VOI between the viewports. For instance, if in the 3x3 layout of PET/CT, the CT image contrast gets manipulated, we want the fusion viewports to reflect the change as well.
const ctWLSync = createVOISynchronizer('ctWLSync');
ctViewports.forEach((viewport) => {
const { renderingEngineId, viewportId } = viewport;
ctWLSync.addSource({ renderingEngineId, viewportId });
});
fusionViewports.forEach((viewport) => {
const { renderingEngineId, viewportId } = viewport;
ctWLSync.addTarget({ renderingEngineId, viewportId });
});
Internally, voiSyncCallback
runs after the VOI_MODIFIED
event.