UNPKG

@pmndrs/handle

Version:

framework agnostic expandable handle implementation for threejs

66 lines (65 loc) 2.6 kB
import { Vector3 } from 'three'; import { clamp } from 'three/src/math/MathUtils.js'; import { applyDampedScreenCameraState, applyScreenCameraState, createScreenCameraStore, } from './camera.js'; import { filterForOnePointerLeftClick, filterForOnePointerRightClickOrTwoPointer } from './index.js'; import { PanScreenHandleStore } from './pan.js'; import { RotateScreenHandleStore } from './rotate.js'; import { ZoomScreenHandleStore } from './zoom.js'; export function defaultOrbitHandlesScreenCameraApply(update, store) { if (update.pitch != null) { update.pitch = clamp(update.pitch, -Math.PI / 2, Math.PI / 2); } store.setState(update); } const vectorHelper = new Vector3(); export class OrbitHandles { rotate; pan; zoom; store; getCamera; updateDamping; damping = false; constructor(canvas, camera, store) { if (store == null) { store = createScreenCameraStore(); const resolvedCamera = typeof camera === 'function' ? camera() : camera; store.getState().setCameraPosition(...resolvedCamera.getWorldPosition(vectorHelper).toArray()); } this.store = store; this.getCamera = typeof camera === 'function' ? camera : () => camera; this.updateDamping = applyDampedScreenCameraState(store, this.getCamera, () => this.damping); this.rotate = new RotateScreenHandleStore(store, this.getCamera, filterForOnePointerLeftClick, defaultOrbitHandlesScreenCameraApply); this.pan = new PanScreenHandleStore(canvas, store, this.getCamera, filterForOnePointerRightClickOrTwoPointer, defaultOrbitHandlesScreenCameraApply); this.zoom = new ZoomScreenHandleStore(store, this.getCamera, undefined, defaultOrbitHandlesScreenCameraApply); } getStore() { return this.store; } update(deltaTime) { this.rotate.update(); this.pan.update(); this.zoom.update(); this.updateDamping(deltaTime); } bind(scene, damping = false) { const unbindRotate = this.rotate.bind(scene); const unbindPan = this.pan.bind(scene); const unbindZoom = this.zoom.bind(scene); let unsubscribeCamera; if (damping === false) { unsubscribeCamera = applyScreenCameraState(this.store, this.getCamera); } this.damping = damping; return () => { unbindRotate(); unbindPan(); unbindZoom(); unsubscribeCamera?.(); }; } } /** * @deprecated use OrbitHandles instead */ export const OrbitControls = OrbitHandles;