UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

292 lines (244 loc) 9.06 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var THREE = _interopRequireWildcard(require("three")); var _MainLoop = require("../Core/MainLoop"); var MOVEMENTS = { 38: { method: 'translateZ', sign: -1 }, // FORWARD: up key 40: { method: 'translateZ', sign: 1 }, // BACKWARD: down key 37: { method: 'translateX', sign: -1 }, // STRAFE_LEFT: left key 39: { method: 'translateX', sign: 1 }, // STRAFE_RIGHT: right key 33: { method: 'rotateZ', sign: 1, noSpeed: true }, // UP: PageUp key 34: { method: 'rotateZ', sign: -1, noSpeed: true }, // DOWN: PageDown key wheelup: { method: 'translateZ', sign: 1, oneshot: true }, // WHEEL up wheeldown: { method: 'translateZ', sign: -1, oneshot: true } // WHEEL down }; function onDocumentMouseDown(event) { event.preventDefault(); this._isMouseDown = true; var coords = this.view.eventToViewCoords(event); this._onMouseDownMouseX = coords.x; this._onMouseDownMouseY = coords.y; } function onTouchStart(event) { event.preventDefault(); this._isMouseDown = true; this._onMouseDownMouseX = event.touches[0].pageX; this._onMouseDownMouseY = event.touches[0].pageY; } function onPointerMove(event) { if (this._isMouseDown === true) { var coords = this.view.eventToViewCoords(event); // in rigor we have tan(theta) = tan(cameraFOV) * deltaH / H // (where deltaH is the vertical amount we moved, and H the renderer height) // we loosely approximate tan(x) by x var pxToAngleRatio = THREE.Math.degToRad(this._camera3D.fov) / this.view.mainLoop.gfxEngine.height; this._camera3D.rotateY((coords.x - this._onMouseDownMouseX) * pxToAngleRatio); this._camera3D.rotateX((coords.y - this._onMouseDownMouseY) * pxToAngleRatio); this._onMouseDownMouseX = coords.x; this._onMouseDownMouseY = coords.y; this.view.notifyChange(this._camera3D, false); } } function onDocumentMouseUp() { this._isMouseDown = false; } function onKeyUp(e) { var move = MOVEMENTS[e.keyCode]; if (move) { this.moves["delete"](move); e.preventDefault(); } } function onKeyDown(e) { var move = MOVEMENTS[e.keyCode]; if (move) { this.moves.add(move); this.view.notifyChange(this._camera3D, false); e.preventDefault(); } } function onDocumentMouseWheel(event) { var delta = 0; if (event.wheelDelta !== undefined) { delta = event.wheelDelta; // Firefox } else if (event.detail !== undefined) { delta = -event.detail; } if (delta < 0) { this.moves.add(MOVEMENTS.wheelup); } else { this.moves.add(MOVEMENTS.wheeldown); } this.view.notifyChange(this._camera3D, false); } /** * First-Person controls (at least a possible declination of it). * * Bindings: * - up + down keys: forward/backward * - left + right keys: strafing movements * - PageUp + PageDown: roll movement * - mouse click+drag: pitch and yaw movements (as looking at a panorama, not as in FPS games for instance) */ var FlyControls = /*#__PURE__*/ function (_THREE$EventDispatche) { (0, _inherits2["default"])(FlyControls, _THREE$EventDispatche); /** * @Constructor * @param {View} view * @param {object} options * @param {boolean} options.focusOnClick - whether or not to focus the renderer domElement on click * @param {boolean} options.focusOnMouseOver - whether or not to focus when the mouse is over the domElement */ function FlyControls(view) { var _this; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; (0, _classCallCheck2["default"])(this, FlyControls); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(FlyControls).call(this)); var domElement = view.mainLoop.gfxEngine.renderer.domElement; _this.view = view; _this.options = options; _this._camera3D = view.camera.camera3D; _this.moves = new Set(); _this.moveSpeed = 10; // backward or forward move speed in m/s _this._onMouseDownMouseX = 0; _this._onMouseDownMouseY = 0; _this._isMouseDown = false; domElement.addEventListener('mousedown', onDocumentMouseDown.bind((0, _assertThisInitialized2["default"])(_this)), false); domElement.addEventListener('touchstart', onTouchStart.bind((0, _assertThisInitialized2["default"])(_this)), false); var bindedPM = onPointerMove.bind((0, _assertThisInitialized2["default"])(_this)); domElement.addEventListener('mousemove', bindedPM, false); domElement.addEventListener('touchmove', bindedPM, false); domElement.addEventListener('mouseup', onDocumentMouseUp.bind((0, _assertThisInitialized2["default"])(_this)), false); domElement.addEventListener('touchend', onDocumentMouseUp.bind((0, _assertThisInitialized2["default"])(_this)), false); domElement.addEventListener('mousewheel', onDocumentMouseWheel.bind((0, _assertThisInitialized2["default"])(_this)), false); domElement.addEventListener('DOMMouseScroll', onDocumentMouseWheel.bind((0, _assertThisInitialized2["default"])(_this)), false); // firefox domElement.addEventListener('keyup', onKeyUp.bind((0, _assertThisInitialized2["default"])(_this)), true); domElement.addEventListener('keydown', onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)), true); _this.view.addFrameRequester(_MainLoop.MAIN_LOOP_EVENTS.AFTER_CAMERA_UPDATE, _this.update.bind((0, _assertThisInitialized2["default"])(_this))); // focus policy if (options.focusOnMouseOver) { domElement.addEventListener('mouseover', function () { return domElement.focus(); }); } if (options.focusOnClick) { domElement.addEventListener('click', function () { return domElement.focus(); }); } return _this; } (0, _createClass2["default"])(FlyControls, [{ key: "isUserInteracting", value: function isUserInteracting() { return this.moves.size !== 0 || this._isMouseDown; } }, { key: "update", value: function update(dt, updateLoopRestarted) { // if we are in a keypressed state, then update position // dt will not be relevant when we just started rendering, we consider a 1-frame move in this case if (updateLoopRestarted) { dt = 16; } var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.moves[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _move = _step.value; this._camera3D[_move.method](_move.sign * (_move.noSpeed ? 1 : this.moveSpeed) * dt / 1000); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator["return"] != null) { _iterator["return"](); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (this.moves.size > 0 || this._isMouseDown) { this.view.notifyChange(this._camera3D); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = this.moves[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var move = _step2.value; if (move.oneshot) { this.moves["delete"](move); } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) { _iterator2["return"](); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } } }]); return FlyControls; }(THREE.EventDispatcher); var _default = FlyControls; exports["default"] = _default;