UNPKG

@here/harp-mapview

Version:

Functionality needed to render a map.

151 lines 6.16 kB
"use strict"; /* * Copyright (C) 2019-2021 HERE Europe B.V. * Licensed under Apache 2.0, see full license in LICENSE * SPDX-License-Identifier: Apache-2.0 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CameraMovementDetector = void 0; const three_1 = require("three"); const Utils_1 = require("./Utils"); /** * The default value for camera movement throttling, in milliseconds. */ const DEFAULT_THROTTLING_TIMEOUT = 300; /** * The `CameraMovementDetector` class checks for changes in camera position and orientation, to * detect continuous movements without the animation mode activated in {@link MapView}. If the * interaction is not continuous enough, you can use a throttling timer to reduce the number of * callbacks. */ class CameraMovementDetector { /** * Initializes the detector with timeout value and callbacks. {@link MapView} also provides * events for client code to be notified when these cues occur. * * @param m_throttlingTimeout - The delay, in milliseconds, between the last user interaction * detected and the call to `m_movementFinishedFunc`; the default is `300`. * @param m_movementStartedFunc - Callback function, called when the user starts interacting. * @param m_movementFinishedFunc - Callback function, called when the user stops interacting. */ constructor(m_throttlingTimeout, m_movementStartedFunc, m_movementFinishedFunc) { this.m_throttlingTimeout = m_throttlingTimeout; this.m_movementStartedFunc = m_movementStartedFunc; this.m_movementFinishedFunc = m_movementFinishedFunc; this.m_lastCameraPos = new three_1.Vector3(); this.m_newCameraPos = new three_1.Vector3(); this.m_throttlingTimerId = undefined; this.m_movementDetectorDeadline = 0; this.onDeadlineTimer = () => { this.m_throttlingTimerId = undefined; const now = performance.now(); if (now >= this.m_movementDetectorDeadline) { this.movementFinished(); } else { this.startMovementFinishedTimer(now); } }; if (this.m_throttlingTimeout === undefined) { this.m_throttlingTimeout = DEFAULT_THROTTLING_TIMEOUT; } } /** * Checks if the camera has moved since the last time it was checked. The * `m_movementStartedFunc` is called when a movement starts. If no movement * is detected, a timer for `m_movementFinishedFunc` starts. * * @param mapView - [[Mapview]]'s position and camera are checked for modifications. */ checkCameraMoved(mapView, now) { const newAttitude = Utils_1.MapViewUtils.extractAttitude(mapView, mapView.camera); const newCameraPos = mapView.camera.getWorldPosition(this.m_newCameraPos); if (this.m_lastAttitude === undefined) { this.m_lastCameraPos.copy(newCameraPos); this.m_lastAttitude = newAttitude; return false; } const cameraMoved = !this.m_lastCameraPos.equals(newCameraPos) || newAttitude.yaw !== this.m_lastAttitude.yaw || newAttitude.pitch !== this.m_lastAttitude.pitch || newAttitude.roll !== this.m_lastAttitude.roll; if (cameraMoved) { this.m_lastCameraPos.copy(newCameraPos); this.m_lastAttitude = newAttitude; } if (cameraMoved !== this.m_cameraMovedLastFrame) { if (cameraMoved) { this.movementStarted(); } this.m_cameraMovedLastFrame = cameraMoved; } if (cameraMoved) { // Start timer this.m_movementDetectorDeadline = now + this.m_throttlingTimeout; this.startMovementFinishedTimer(now); } return this.m_cameraMovedLastFrame; } /** * Reset the saved camera position. Next time checkCameraMoved is called, it will return * `false`. */ clear(mapView) { const newCameraPos = mapView.camera.getWorldPosition(this.m_newCameraPos); this.m_lastCameraPos.set(newCameraPos.x, newCameraPos.y, newCameraPos.z); const newAttitude = Utils_1.MapViewUtils.extractAttitude(mapView, mapView.camera); this.m_lastAttitude = newAttitude; } /** * Force change of camera position. Next time checkCameraMoved is called, it will return `true`. */ forceMoved() { this.m_lastCameraPos.set(Number.NaN, Number.NaN, Number.NaN); } /** * Returns `true` if the camera of this {@link MapView} is currently moving. In this case the * `m_movementFinishedFunc` is waiting to be called after the throttling timer runs out. */ get cameraIsMoving() { return this.m_throttlingTimerId !== undefined; } /** * Disposes resources and kills the throttling timer. */ dispose() { this.removeMovementFinishedTimer(); this.m_movementStartedFunc = undefined; this.m_movementFinishedFunc = undefined; } /** * Returns `true` if the camera has moved in the last frame. */ get cameraMovedLastFrame() { return this.m_cameraMovedLastFrame === true; } movementStarted() { if (this.m_movementStartedFunc !== undefined) { this.m_movementStartedFunc(); } } movementFinished() { this.removeMovementFinishedTimer(); if (this.m_movementFinishedFunc !== undefined) { this.m_movementFinishedFunc(); } } startMovementFinishedTimer(now) { if (this.m_throttlingTimerId === undefined) { const remainingTime = Math.max(0, this.m_movementDetectorDeadline - now); this.m_throttlingTimerId = setTimeout(this.onDeadlineTimer, remainingTime); } } removeMovementFinishedTimer() { if (this.m_throttlingTimerId !== undefined) { clearTimeout(this.m_throttlingTimerId); this.m_throttlingTimerId = undefined; } } } exports.CameraMovementDetector = CameraMovementDetector; //# sourceMappingURL=CameraMovementDetector.js.map