UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

172 lines 7.16 kB
import { Reactive } from "@lincode/reactivity"; import { container } from "../../engine/renderLoop/renderSetup"; import { orbitCameraDefaults, orbitCameraSchema } from "../../interface/IOrbitCamera"; import { getTransformControlsDragging } from "../../states/useTransformControlsDragging"; import { onKeyClear } from "../../events/onKeyClear"; import { onSceneGraphChange } from "../../events/onSceneGraphChange"; import { getCameraRendered } from "../../states/useCameraRendered"; import { onBeforeRender } from "../../events/onBeforeRender"; import { Cancellable } from "@lincode/promiselikes"; import { idMap } from "../core/StaticObjectManager"; import { PerspectiveCamera } from "three"; import OrbitCameraBase from "../core/OrbitCameraBase"; import { vec2Point } from "../utils/vec2Point"; import getWorldPosition from "../utils/getWorldPosition"; import getCenter from "../utils/getCenter"; import { FAR, NEAR } from "../../globals"; export default class OrbitCamera extends OrbitCameraBase { static componentName = "orbitCamera"; static defaults = orbitCameraDefaults; static schema = orbitCameraSchema; constructor(camera = new PerspectiveCamera(75, 1, NEAR, FAR)) { super(camera); this.innerZ = 500; this.orbitMode = true; this.mouseControl = "drag"; this.camera.rotation.y = 0; this.createEffect(() => { const targetId = this.targetIdState.get(); if (!targetId) return; const handle = new Cancellable(); const timeout = setTimeout(() => { const find = () => { const [found] = idMap.get(targetId) ?? [undefined]; if (found) { this.manualTarget = found; this.targetState.set(found); } return found; }; if (find()) return; handle.watch(onSceneGraphChange(() => setTimeout(() => find() && handle.cancel()))); }); return () => { clearTimeout(timeout); handle.cancel(); }; }, [this.targetIdState.get]); this.createEffect(() => { const target = this.targetState.get(); if (!target) return; const handle = onBeforeRender(() => { this.placeAt(vec2Point(getCenter(target.nativeObject3d))); }); return () => { handle.cancel(); }; }, [this.targetState.get]); this.createEffect(() => { const autoRotate = this.autoRotateState.get(); if (getCameraRendered() !== camera || !autoRotate) return; const speed = typeof autoRotate === "number" ? autoRotate : 2; const handle = onBeforeRender(() => { this.gyrate(speed, 0, true); }); return () => { handle.cancel(); }; }, [getCameraRendered, this.autoRotateState.get]); this.createEffect(() => { if (getTransformControlsDragging() || getCameraRendered() !== camera || !this.mouseControlState.get()) return; const handle = new Cancellable(); if (this.enableZoomState.get()) { const cb = (e) => { e.preventDefault(); this.innerZ += e.deltaY; if (this.innerZ < 0) this.innerZ = 0; }; container.addEventListener("wheel", cb); handle.then(() => container.removeEventListener("wheel", cb)); } if (this.enableFlyState.get()) { const downSet = new Set(); handle.watch(onBeforeRender(() => { if (downSet.has("Meta") || downSet.has("Control")) return; const speed = downSet.has("Shift") ? 50 : 10; if (downSet.has("w")) this.translateZ(-speed); else if (downSet.has("s")) this.translateZ(speed); if (downSet.has("a") || downSet.has("ArrowLeft")) this.moveRight(-speed); else if (downSet.has("d") || downSet.has("ArrowRight")) this.moveRight(speed); if (downSet.has("w") || downSet.has("s") || downSet.has("a") || downSet.has("d")) { const worldPos = vec2Point(getWorldPosition(this.object3d)); this.innerZ = 0; this.placeAt(worldPos); } if (downSet.has("Meta") || downSet.has("Control")) return; if (downSet.has("ArrowDown")) this.y -= speed; else if (downSet.has("ArrowUp")) this.y += speed; })); const handleKeyDown = (e) => { downSet.add(e.key.length === 1 ? e.key.toLocaleLowerCase() : e.key); }; const handleKeyUp = (e) => { downSet.delete(e.key.length === 1 ? e.key.toLocaleLowerCase() : e.key); }; document.addEventListener("keydown", handleKeyDown); document.addEventListener("keyup", handleKeyUp); handle.watch(onKeyClear(() => downSet.clear())); handle.then(() => { document.removeEventListener("keydown", handleKeyDown); document.removeEventListener("keyup", handleKeyUp); }); } return () => { handle.cancel(); }; }, [ getCameraRendered, getTransformControlsDragging, this.enableZoomState.get, this.enableFlyState.get, this.mouseControlState.get ]); } targetIdState = new Reactive(undefined); get targetId() { return this.targetIdState.get(); } set targetId(val) { this.targetIdState.set(val); } enableZoomState = new Reactive(false); get enableZoom() { return this.enableZoomState.get(); } set enableZoom(val) { this.enableZoomState.set(val); } enableFlyState = new Reactive(false); get enableFly() { return this.enableFlyState.get(); } set enableFly(val) { this.enableFlyState.set(val); } autoRotateState = new Reactive(false); get autoRotate() { return this.autoRotateState.get(); } set autoRotate(val) { this.autoRotateState.set(val); } } //# sourceMappingURL=OrbitCamera.js.map