UNPKG

@pmndrs/handle

Version:

framework agnostic expandable handle implementation for threejs

52 lines (51 loc) 2.04 kB
import { BufferGeometry, Float32BufferAttribute, LineBasicMaterial, LineSegments, Quaternion } from 'three'; import { handleXRayMaterialProperties } from './material.js'; const quaternionHelper = new Quaternion(); const geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute([-1e3, 0, 0, 1e3, 0, 0], 3)); export class HandlesAxisHighlight extends LineSegments { context; rotationOffset; constructor(context, rotationOffset) { super(geometry); this.context = context; this.rotationOffset = rotationOffset; this.renderOrder = Infinity; } update() { this.quaternion.setFromEuler(this.rotationOffset); const target = this.context.getTarget(); if (this.context.getSpace() === 'world' && target != null) { target.getWorldQuaternion(quaternionHelper).invert(); this.quaternion.premultiply(quaternionHelper); } } bind(tag) { this.material = new LineBasicMaterial({ ...handleXRayMaterialProperties, color: this.material.color ?? 'white', opacity: this.material.opacity ?? 1, }); const unsubscribeHover = this.context.subscribeHover((tags) => { const isHovered = tags.some((activeTag) => activeTag.includes(tag)); this.visible = isHovered; }); const unsubscribeApply = this.context.subscribeApply((_, state) => { if (state.last) { this.position.set(0, 0, 0); return; } this.position.copy(state.initial.position).sub(state.current.position); const target = this.context.getTarget(); if (target != null) { quaternionHelper.copy(target.quaternion).invert(); this.position.applyQuaternion(quaternionHelper); } }); return () => { this.material.dispose(); unsubscribeHover(); unsubscribeApply(); }; } }