UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

111 lines (91 loc) 3.32 kB
import { clamp } from "../../../core/math/clamp.js"; import Entity from "../../ecs/Entity.js"; import { decodeMouseEventButtons } from "../../input/devices/mouse/decodeMouseEventButtons.js"; import InputController from "../../input/ecs/components/InputController.js"; import { Camera } from "../ecs/camera/Camera.js"; import TopDownCameraController, { rotate_from_view } from "../ecs/camera/topdown/TopDownCameraController.js"; /** * * @param {number} camera_entity * @param {EntityComponentDataset} ecd * @param {HTMLElement} dom_element * @param {number} [sensitivity] * @return {Entity} */ export function makeOrbitalCameraController({ camera_entity, ecd, dom_element, sensitivity = 1 }) { /** * * @returns {TopDownCameraController} */ function getCameraController() { return ecd.getComponent(camera_entity, TopDownCameraController) } function getCamera() { return ecd.getComponent(camera_entity, Camera) } /** * * @param {Vector2} delta */ function orbit(delta) { const cameraController = getCameraController(); const scale = sensitivity * 2 * Math.PI / dom_element.clientHeight; rotate_from_view(delta.x * scale, delta.y * scale, cameraController, cameraController); } /** * * @param {Vector2} delta */ function pan(delta) { const d = delta.clone(); const cameraController = getCameraController(); const camera = getCamera(); TopDownCameraController.pan(d, camera.object, dom_element, cameraController.distance, camera.object.fov, cameraController.target); } function zoom(delta) { const cameraController = getCameraController(); const new_distance = cameraController.distance + delta; cameraController.distance = clamp(new_distance, cameraController.distanceMin, cameraController.distanceMax); } const inputController = new InputController([ { path: 'pointer/on/tap', listener(position, event) { // event.preventDefault(); } }, { path: 'pointer/on/down', listener(position, event) { // event.preventDefault(); } }, { path: 'pointer/on/drag', listener: function (position, origin, lastDragPosition, event) { const delta = lastDragPosition.clone().sub(position); const buttons = decodeMouseEventButtons(event.buttons); if (buttons[0]) { pan(delta); } else { orbit(delta); } event.preventDefault(); } }, { path: 'pointer/on/wheel', listener(delta, event) { zoom(delta.y); } } ]); const eb = new Entity(); eb.add(inputController); return eb; }