@pmndrs/handle
Version:
framework agnostic expandable handle implementation for threejs
59 lines (58 loc) • 2.59 kB
JavaScript
import { BoxGeometry, Euler, Group, Mesh, MeshBasicMaterial } from 'three';
import { handleXRayMaterialProperties, setupHandlesContextHoverMaterial } from '../material.js';
import { RegisteredHandle } from '../registered.js';
import { extractHandleTransformOptions } from '../utils.js';
const normalRotation = new Euler(0, 0, -Math.PI / 2);
const invertedRotation = new Euler(0, 0, Math.PI / 2);
export class UniformAxisScaleHandle extends RegisteredHandle {
actualAxis;
invert;
constructor(context, tagPrefix = '', actualAxis, invert = false) {
super(context, 'xyz', tagPrefix, () => ({
scale: { uniform: true, ...this.options },
rotate: false,
translate: 'as-scale',
multitouch: false,
}));
this.actualAxis = actualAxis;
this.invert = invert;
}
bind(defaultColor, defaultHoverColor, config) {
const { options, disabled } = extractHandleTransformOptions(this.actualAxis, config);
if (options === false) {
return undefined;
}
this.options = options;
const rotation = this.invert ? invertedRotation : normalRotation;
//visualization
const headGroup = new Group();
headGroup.position.x = this.invert ? -0.7 : 0.7;
headGroup.rotation.copy(rotation);
this.add(headGroup);
const material = new MeshBasicMaterial(handleXRayMaterialProperties);
const cleanupHeadHover = setupHandlesContextHoverMaterial(this.context, material, this.tag, {
color: defaultColor,
hoverColor: defaultHoverColor,
opacity: 0.5,
hoverOpacity: 1,
disabled,
});
const visualizationHeadMesh = new Mesh(new BoxGeometry(0.08, 0.08, 0.08), material);
visualizationHeadMesh.renderOrder = Infinity;
visualizationHeadMesh.rotation.copy(rotation);
headGroup.add(visualizationHeadMesh);
const interactionHeadMesh = new Mesh(new BoxGeometry(0.15, 0.15, 0.15), material);
interactionHeadMesh.visible = false;
interactionHeadMesh.pointerEventsOrder = Infinity;
interactionHeadMesh.rotation.copy(rotation);
headGroup.add(interactionHeadMesh);
const unregister = disabled ? undefined : this.context.registerHandle(this.store, interactionHeadMesh, this.tag);
return () => {
material.dispose();
visualizationHeadMesh.geometry.dispose();
unregister?.();
cleanupHeadHover?.();
this.remove(headGroup);
};
}
}