48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import { useEffect } from "react";
|
|
import { useThree } from "@react-three/fiber";
|
|
import * as THREE from "three";
|
|
import type { CameraControls } from "@react-three/drei";
|
|
|
|
export const useCameraShortcuts = (controlsRef: React.RefObject<CameraControls>) => {
|
|
const { camera } = useThree();
|
|
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
if (!controlsRef.current) return;
|
|
|
|
// get current distance from camera to target
|
|
const target = new THREE.Vector3();
|
|
controlsRef.current.getTarget(target);
|
|
|
|
const distance = camera.position.distanceTo(target);
|
|
let pos: THREE.Vector3 | null = null;
|
|
|
|
switch (e.key) {
|
|
case "1": // Front
|
|
pos = new THREE.Vector3(0, 0, distance).add(target);
|
|
break;
|
|
case "3": // Right
|
|
pos = new THREE.Vector3(distance, 0, 0).add(target);
|
|
break;
|
|
case "7": // Top
|
|
pos = new THREE.Vector3(0, distance, 0).add(target);
|
|
break;
|
|
case "9": // Back
|
|
pos = new THREE.Vector3(0, 0, -distance).add(target);
|
|
break;
|
|
}
|
|
|
|
if (pos) {
|
|
controlsRef.current.setLookAt(
|
|
pos.x, pos.y, pos.z, // camera position
|
|
target.x, target.y, target.z, // keep same target
|
|
true // smooth transition
|
|
);
|
|
}
|
|
};
|
|
|
|
window.addEventListener("keydown", handleKeyDown);
|
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
}, [controlsRef, camera]);
|
|
};
|