@kitware/vtk.js
Version:
Visualization Toolkit for the Web
144 lines (138 loc) • 4.75 kB
JavaScript
import { m as macro } from '../../../macros2.js';
import { k as add } from '../../../Common/Core/Math/index.js';
import { vec3 } from 'gl-matrix';
function widgetBehavior(publicAPI, model) {
const state = model.widgetState;
const moveHandle = state.getMoveHandle();
const centerHandle = state.getCenterHandle();
const borderHandle = state.getBorderHandle();
const shapeHandle = state.getSphereHandle();
// Set while moving the center or border handle.
model._isDragging = false;
model.classHierarchy.push('vtkSphereWidgetProp');
moveHandle.setVisible(true);
centerHandle.setVisible(false);
borderHandle.setVisible(false);
shapeHandle.setVisible(true);
function isValidHandle(handle) {
return handle === centerHandle || handle === borderHandle || handle === moveHandle;
}
function isPlaced() {
return !!centerHandle.getOrigin() && !!borderHandle.getOrigin();
}
// Update the sphereHandle parameters from {center,border}Handle.
function updateSphere() {
const center = centerHandle.getOrigin();
if (!center) return;
centerHandle.setVisible(true);
let border = borderHandle.getOrigin();
if (border) {
borderHandle.setVisible(true);
} else {
border = moveHandle.getOrigin();
if (!border) return;
}
if (isPlaced()) {
moveHandle.setVisible(false);
}
const radius = vec3.distance(center, border);
shapeHandle.setVisible(true);
shapeHandle.setOrigin(center);
shapeHandle.setScale1(radius * 2);
model._interactor.render();
}
function currentWorldCoords(e) {
const manipulator = model.activeState?.getManipulator?.() ?? model.manipulator;
return manipulator.handleEvent(e, model._apiSpecificRenderWindow);
}
// Update the sphere's center and radius. Example:
// handle.setCenterAndRadius([1,2,3], 10);
publicAPI.setCenterAndRadius = (newCenter, newRadius) => {
const oldCenter = centerHandle.getOrigin();
const oldBorder = borderHandle.getOrigin();
let newBorder = [newCenter[0] + newRadius, newCenter[1], newCenter[2]];
if (oldBorder) {
// Move the boundary handle to reflect the new radius, while preserving
// its direction relative to the center.
const direction = vec3.sub(vec3.create(), oldBorder, oldCenter);
const oldRadius = vec3.length(direction);
if (oldRadius > 1e-10) {
newBorder = vec3.add(vec3.create(), newCenter, vec3.scale(vec3.create(), direction, newRadius / oldRadius));
}
}
centerHandle.setOrigin(newCenter);
borderHandle.setOrigin(newBorder);
updateSphere();
model._widgetManager.enablePicking();
};
publicAPI.handleLeftButtonPress = e => {
if (!isValidHandle(model.activeState)) {
model.activeState = null;
return macro.VOID;
}
const {
worldCoords
} = currentWorldCoords(e);
if (model.activeState === moveHandle) {
// Initial sphere placement.
if (!centerHandle.getOrigin()) {
centerHandle.setOrigin(worldCoords);
} else if (!borderHandle.getOrigin()) {
borderHandle.setOrigin(worldCoords);
publicAPI.loseFocus();
}
updateSphere();
return macro.EVENT_ABORT;
}
model._isDragging = true;
model._apiSpecificRenderWindow.setCursor('grabbing');
publicAPI.invokeStartInteractionEvent();
return macro.EVENT_ABORT;
};
publicAPI.handleLeftButtonRelease = e => {
if (!model._isDragging) {
model.activeState = null;
return macro.VOID;
}
if (isPlaced()) {
model._widgetManager.enablePicking();
model._apiSpecificRenderWindow.setCursor('pointer');
model._isDragging = false;
model.activeState = null;
state.deactivate();
}
publicAPI.invokeEndInteractionEvent();
return macro.EVENT_ABORT;
};
publicAPI.handleMouseMove = e => {
if (!model.activeState) return macro.VOID;
const {
worldCoords,
worldDelta
} = currentWorldCoords(e);
if (model.hasFocus) {
model.activeState.setOrigin(worldCoords);
} else if (model._isDragging) {
model.activeState.setOrigin(add(model.activeState.getOrigin(), worldDelta, []));
}
updateSphere();
return macro.VOID;
};
const superGrabFocus = publicAPI.grabFocus;
publicAPI.grabFocus = () => {
superGrabFocus();
moveHandle.setVisible(true);
centerHandle.setVisible(false);
borderHandle.setVisible(false);
centerHandle.setOrigin(null);
borderHandle.setOrigin(null);
model.activeState = moveHandle;
model._interactor.render();
};
const superLoseFocus = publicAPI.loseFocus;
publicAPI.loseFocus = () => {
superLoseFocus();
model.activeState = null;
};
}
export { widgetBehavior as default };