UNPKG

@inweb/viewer-three

Version:

JavaScript library for rendering CAD and BIM files in a browser using Three.js

138 lines (119 loc) 4.98 kB
/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a // license agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// import { MOUSE, TOUCH } from "three"; import { type IDragger } from "@inweb/viewer-core"; import type { Viewer } from "../Viewer"; import { OrbitControls, STATE } from "../controls/OrbitControls.js"; export class OrbitDragger implements IDragger { protected viewer: Viewer; protected orbit: OrbitControls; protected changed: boolean; constructor(viewer: Viewer) { this.orbit = new OrbitControls(viewer.camera, viewer.canvas); this.orbit.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.PAN, RIGHT: MOUSE.PAN }; this.orbit.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN }; this.orbit.screenSpacePanning = true; this.orbit.rotateSpeed = 0.33; this.orbit.addEventListener("start", this.controlsStart); this.orbit.addEventListener("change", this.controlsChange); this.changed = false; this.viewer = viewer; this.viewer.addEventListener("databasechunk", this.updateControls); this.viewer.addEventListener("clear", this.updateControls); this.viewer.on("viewposition", this.updateControls); this.viewer.addEventListener("zoom", this.updateControls); this.viewer.addEventListener("drawviewpoint", this.updateControls); this.viewer.addEventListener("changecameramode", this.updateControlsCamera); this.viewer.addEventListener("optionschange", this.optionsChange); this.viewer.addEventListener("contextmenu", this.stopContextMenu); this.updateControls(); } initialize() {} dispose(): void { this.viewer.removeEventListener("databasechunk", this.updateControls); this.viewer.removeEventListener("clear", this.updateControls); this.viewer.off("viewposition", this.updateControls); this.viewer.removeEventListener("zoom", this.updateControls); this.viewer.removeEventListener("drawviewpoint", this.updateControls); this.viewer.removeEventListener("changecameramode", this.updateControlsCamera); this.viewer.removeEventListener("optionschange", this.optionsChange); this.viewer.removeEventListener("contextmenu", this.stopContextMenu); this.orbit.removeEventListener("start", this.controlsStart); this.orbit.removeEventListener("change", this.controlsChange); this.orbit.dispose(); } updateControls = () => { this.orbit.target.copy(this.viewer.target); this.orbit.update(); }; updateControlsCamera = () => { this.orbit.maxDistance = this.viewer.camera.far; this.orbit.minDistance = this.viewer.camera.near; this.orbit.object = this.viewer.camera; this.orbit.update(); }; optionsChange = ({ data: options }) => { this.orbit.zoomSpeed = Math.abs(this.orbit.zoomSpeed) * (options.reverseZoomWheel ? -1 : 1); }; controlsStart = () => { this.changed = false; }; controlsChange = () => { this.viewer.target.copy(this.orbit.target); this.viewer.update(); switch (this.orbit.state) { case STATE.ROTATE: case STATE.TOUCH_ROTATE: this.viewer.emitEvent({ type: "orbit", }); break; case STATE.PAN: case STATE.TOUCH_PAN: this.viewer.emitEvent({ type: "pan", x: this.orbit.panEnd.x, y: this.orbit.panEnd.y, dX: this.orbit.panDelta.x, dY: this.orbit.panDelta.y, }); break; case STATE.DOLLY: this.viewer.emitEvent({ type: "zoomat", data: this.orbit.dollyScale, x: this.orbit.dollyEnd.x, y: this.orbit.dollyEnd.y, }); break; } this.viewer.emitEvent({ type: "changecamera" }); this.changed = true; }; stopContextMenu = (event: PointerEvent) => { if (this.changed) { event.preventDefault(); event.stopPropagation(); } }; }