UNPKG

kitchen-simulator

Version:

It is a kitchen simulator (self-contained micro-frontend).

1,174 lines (1,173 loc) 112 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.EventDispatcher = void 0; var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _superPropGet(t, o, e, r) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } /*! * camera-controls * https://github.com/yomotsu/camera-controls * (c) 2017 @yomotsu * Released under the MIT License. */ // see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons#value var MOUSE_BUTTON = { LEFT: 1, RIGHT: 2, MIDDLE: 4 }; var ACTION = Object.freeze({ NONE: 0, ROTATE: 1, TRUCK: 2, OFFSET: 4, DOLLY: 8, ZOOM: 16, TOUCH_ROTATE: 32, TOUCH_TRUCK: 64, TOUCH_OFFSET: 128, TOUCH_DOLLY: 256, TOUCH_ZOOM: 512, TOUCH_DOLLY_TRUCK: 1024, TOUCH_DOLLY_OFFSET: 2048, TOUCH_DOLLY_ROTATE: 4096, TOUCH_ZOOM_TRUCK: 8192, TOUCH_ZOOM_OFFSET: 16384, TOUCH_ZOOM_ROTATE: 32768 }); var DOLLY_DIRECTION = { NONE: 0, IN: 1, OUT: -1 }; function isPerspectiveCamera(camera) { return camera.isPerspectiveCamera; } function isOrthographicCamera(camera) { return camera.isOrthographicCamera; } var PI_2 = Math.PI * 2; var PI_HALF = Math.PI / 2; var EPSILON = 1e-5; var DEG2RAD = Math.PI / 180; function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } function approxZero(number) { var error = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : EPSILON; return Math.abs(number) < error; } function approxEquals(a, b) { var error = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EPSILON; return approxZero(a - b, error); } function roundToStep(value, step) { return Math.round(value / step) * step; } function infinityToMaxNumber(value) { if (isFinite(value)) return value; if (value < 0) return -Number.MAX_VALUE; return Number.MAX_VALUE; } function maxNumberToInfinity(value) { if (Math.abs(value) < Number.MAX_VALUE) return value; return value * Infinity; } // https://docs.unity3d.com/ScriptReference/Mathf.SmoothDamp.html // https://github.com/Unity-Technologies/UnityCsReference/blob/a2bdfe9b3c4cd4476f44bf52f848063bfaf7b6b9/Runtime/Export/Math/Mathf.cs#L308 function smoothDamp(current, target, currentVelocityRef, smoothTime) { var maxSpeed = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : Infinity; var deltaTime = arguments.length > 5 ? arguments[5] : undefined; // Based on Game Programming Gems 4 Chapter 1.10 smoothTime = Math.max(0.0001, smoothTime); var omega = 2 / smoothTime; var x = omega * deltaTime; var exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x); var change = current - target; var originalTo = target; // Clamp maximum speed var maxChange = maxSpeed * smoothTime; change = clamp(change, -maxChange, maxChange); target = current - change; var temp = (currentVelocityRef.value + omega * change) * deltaTime; currentVelocityRef.value = (currentVelocityRef.value - omega * temp) * exp; var output = target + (change + temp) * exp; // Prevent overshooting if (originalTo - current > 0.0 === output > originalTo) { output = originalTo; currentVelocityRef.value = (output - originalTo) / deltaTime; } return output; } // https://docs.unity3d.com/ScriptReference/Vector3.SmoothDamp.html // https://github.com/Unity-Technologies/UnityCsReference/blob/a2bdfe9b3c4cd4476f44bf52f848063bfaf7b6b9/Runtime/Export/Math/Vector3.cs#L97 function smoothDampVec3(current, target, currentVelocityRef, smoothTime) { var maxSpeed = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : Infinity; var deltaTime = arguments.length > 5 ? arguments[5] : undefined; var out = arguments.length > 6 ? arguments[6] : undefined; // Based on Game Programming Gems 4 Chapter 1.10 smoothTime = Math.max(0.0001, smoothTime); var omega = 2 / smoothTime; var x = omega * deltaTime; var exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x); var targetX = target.x; var targetY = target.y; var targetZ = target.z; var changeX = current.x - targetX; var changeY = current.y - targetY; var changeZ = current.z - targetZ; var originalToX = targetX; var originalToY = targetY; var originalToZ = targetZ; // Clamp maximum speed var maxChange = maxSpeed * smoothTime; var maxChangeSq = maxChange * maxChange; var magnitudeSq = changeX * changeX + changeY * changeY + changeZ * changeZ; if (magnitudeSq > maxChangeSq) { var magnitude = Math.sqrt(magnitudeSq); changeX = changeX / magnitude * maxChange; changeY = changeY / magnitude * maxChange; changeZ = changeZ / magnitude * maxChange; } targetX = current.x - changeX; targetY = current.y - changeY; targetZ = current.z - changeZ; var tempX = (currentVelocityRef.x + omega * changeX) * deltaTime; var tempY = (currentVelocityRef.y + omega * changeY) * deltaTime; var tempZ = (currentVelocityRef.z + omega * changeZ) * deltaTime; currentVelocityRef.x = (currentVelocityRef.x - omega * tempX) * exp; currentVelocityRef.y = (currentVelocityRef.y - omega * tempY) * exp; currentVelocityRef.z = (currentVelocityRef.z - omega * tempZ) * exp; out.x = targetX + (changeX + tempX) * exp; out.y = targetY + (changeY + tempY) * exp; out.z = targetZ + (changeZ + tempZ) * exp; // Prevent overshooting var origMinusCurrentX = originalToX - current.x; var origMinusCurrentY = originalToY - current.y; var origMinusCurrentZ = originalToZ - current.z; var outMinusOrigX = out.x - originalToX; var outMinusOrigY = out.y - originalToY; var outMinusOrigZ = out.z - originalToZ; if (origMinusCurrentX * outMinusOrigX + origMinusCurrentY * outMinusOrigY + origMinusCurrentZ * outMinusOrigZ > 0) { out.x = originalToX; out.y = originalToY; out.z = originalToZ; currentVelocityRef.x = (out.x - originalToX) / deltaTime; currentVelocityRef.y = (out.y - originalToY) / deltaTime; currentVelocityRef.z = (out.z - originalToZ) / deltaTime; } return out; } function extractClientCoordFromEvent(pointers, out) { out.set(0, 0); pointers.forEach(function (pointer) { out.x += pointer.clientX; out.y += pointer.clientY; }); out.x /= pointers.length; out.y /= pointers.length; } function notSupportedInOrthographicCamera(camera, message) { if (isOrthographicCamera(camera)) { console.warn("".concat(message, " is not supported in OrthographicCamera")); return true; } return false; } var EventDispatcher = exports.EventDispatcher = /*#__PURE__*/function () { function EventDispatcher() { (0, _classCallCheck2["default"])(this, EventDispatcher); this._listeners = {}; } /** * Adds the specified event listener. * @param type event name * @param listener handler function * @category Methods */ return (0, _createClass2["default"])(EventDispatcher, [{ key: "addEventListener", value: function addEventListener(type, listener) { var listeners = this._listeners; if (listeners[type] === undefined) listeners[type] = []; if (listeners[type].indexOf(listener) === -1) listeners[type].push(listener); } /** * Presence of the specified event listener. * @param type event name * @param listener handler function * @category Methods */ }, { key: "hasEventListener", value: function hasEventListener(type, listener) { var listeners = this._listeners; return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; } /** * Removes the specified event listener * @param type event name * @param listener handler function * @category Methods */ }, { key: "removeEventListener", value: function removeEventListener(type, listener) { var listeners = this._listeners; var listenerArray = listeners[type]; if (listenerArray !== undefined) { var index = listenerArray.indexOf(listener); if (index !== -1) listenerArray.splice(index, 1); } } /** * Removes all event listeners * @param type event name * @category Methods */ }, { key: "removeAllEventListeners", value: function removeAllEventListeners(type) { if (!type) { this._listeners = {}; return; } if (Array.isArray(this._listeners[type])) this._listeners[type].length = 0; } /** * Fire an event type. * @param event DispatcherEvent * @category Methods */ }, { key: "dispatchEvent", value: function dispatchEvent(event) { var listeners = this._listeners; var listenerArray = listeners[event.type]; if (listenerArray !== undefined) { event.target = this; var array = listenerArray.slice(0); for (var i = 0, l = array.length; i < l; i++) { array[i].call(this, event); } } } }]); }(); var _a; var VERSION = '2.8.4'; // will be replaced with `version` in package.json during the build process. var TOUCH_DOLLY_FACTOR = 1 / 8; var isMac = /Mac/.test((_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _a === void 0 ? void 0 : _a.platform); var THREE; var _ORIGIN; var _AXIS_Y; var _AXIS_Z; var _v2; var _v3A; var _v3B; var _v3C; var _cameraDirection; var _xColumn; var _yColumn; var _zColumn; var _deltaTarget; var _deltaOffset; var _sphericalA; var _sphericalB; var _box3A; var _box3B; var _sphere; var _quaternionA; var _quaternionB; var _rotationMatrix; var _raycaster; var CameraControls = exports["default"] = /*#__PURE__*/function (_EventDispatcher) { /** * Creates a `CameraControls` instance. * * Note: * You **must install** three.js before using camera-controls. see [#install](#install) * Not doing so will lead to runtime errors (`undefined` references to THREE). * * e.g. * ``` * CameraControls.install( { THREE } ); * const cameraControls = new CameraControls( camera, domElement ); * ``` * * @param camera A `THREE.PerspectiveCamera` or `THREE.OrthographicCamera` to be controlled. * @param domElement A `HTMLElement` for the draggable area, usually `renderer.domElement`. * @category Constructor */ function CameraControls(camera, domElement) { var _this; (0, _classCallCheck2["default"])(this, CameraControls); _this = _callSuper(this, CameraControls); /** * Minimum vertical angle in radians. * The angle has to be between `0` and `.maxPolarAngle` inclusive. * The default value is `0`. * * e.g. * ``` * cameraControls.maxPolarAngle = 0; * ``` * @category Properties */ _this.minPolarAngle = 0; // radians /** * Maximum vertical angle in radians. * The angle has to be between `.maxPolarAngle` and `Math.PI` inclusive. * The default value is `Math.PI`. * * e.g. * ``` * cameraControls.maxPolarAngle = Math.PI; * ``` * @category Properties */ _this.maxPolarAngle = Math.PI; // radians /** * Minimum horizontal angle in radians. * The angle has to be less than `.maxAzimuthAngle`. * The default value is `- Infinity`. * * e.g. * ``` * cameraControls.minAzimuthAngle = - Infinity; * ``` * @category Properties */ _this.minAzimuthAngle = -Infinity; // radians /** * Maximum horizontal angle in radians. * The angle has to be greater than `.minAzimuthAngle`. * The default value is `Infinity`. * * e.g. * ``` * cameraControls.maxAzimuthAngle = Infinity; * ``` * @category Properties */ _this.maxAzimuthAngle = Infinity; // radians // How far you can dolly in and out ( PerspectiveCamera only ) /** * Minimum distance for dolly. The value must be higher than `0`. Default is `Number.EPSILON`. * PerspectiveCamera only. * @category Properties */ _this.minDistance = Number.EPSILON; /** * Maximum distance for dolly. The value must be higher than `minDistance`. Default is `Infinity`. * PerspectiveCamera only. * @category Properties */ _this.maxDistance = Infinity; /** * `true` to enable Infinity Dolly for wheel and pinch. Use this with `minDistance` and `maxDistance` * If the Dolly distance is less (or over) than the `minDistance` (or `maxDistance`), `infinityDolly` will keep the distance and pushes the target position instead. * @category Properties */ _this.infinityDolly = false; /** * Minimum camera zoom. * @category Properties */ _this.minZoom = 0.01; /** * Maximum camera zoom. * @category Properties */ _this.maxZoom = Infinity; /** * Approximate time in seconds to reach the target. A smaller value will reach the target faster. * @category Properties */ _this.smoothTime = 0.25; /** * the smoothTime while dragging * @category Properties */ _this.draggingSmoothTime = 0.125; /** * Max transition speed in unit-per-seconds * @category Properties */ _this.maxSpeed = Infinity; /** * Speed of azimuth (horizontal) rotation. * @category Properties */ _this.azimuthRotateSpeed = 1.0; /** * Speed of polar (vertical) rotation. * @category Properties */ _this.polarRotateSpeed = 1.0; /** * Speed of mouse-wheel dollying. * @category Properties */ _this.dollySpeed = 1.0; /** * `true` to invert direction when dollying or zooming via drag * @category Properties */ _this.dollyDragInverted = false; /** * Speed of drag for truck and pedestal. * @category Properties */ _this.truckSpeed = 2.0; /** * `true` to enable Dolly-in to the mouse cursor coords. * @category Properties */ _this.dollyToCursor = false; /** * @category Properties */ _this.dragToOffset = false; /** * The same as `.screenSpacePanning` in three.js's OrbitControls. * @category Properties */ _this.verticalDragToForward = false; /** * Friction ratio of the boundary. * @category Properties */ _this.boundaryFriction = 0.0; /** * Controls how soon the `rest` event fires as the camera slows. * @category Properties */ _this.restThreshold = 0.01; /** * An array of Meshes to collide with camera. * Be aware colliderMeshes may decrease performance. The collision test uses 4 raycasters from the camera since the near plane has 4 corners. * @category Properties */ _this.colliderMeshes = []; /** * Force cancel user dragging. * @category Methods */ // cancel will be overwritten in the constructor. _this.cancel = function () {}; _this._enabled = true; _this._state = ACTION.NONE; _this._viewport = null; _this._changedDolly = 0; _this._changedZoom = 0; _this._hasRested = true; _this._boundaryEnclosesCamera = false; _this._needsUpdate = true; _this._updatedLastTime = false; _this._elementRect = new DOMRect(); _this._isDragging = false; _this._dragNeedsUpdate = true; _this._activePointers = []; _this._lockedPointer = null; _this._interactiveArea = new DOMRect(0, 0, 1, 1); // Use draggingSmoothTime over smoothTime while true. // set automatically true on user-dragging start. // set automatically false on programmable methods call. _this._isUserControllingRotate = false; _this._isUserControllingDolly = false; _this._isUserControllingTruck = false; _this._isUserControllingOffset = false; _this._isUserControllingZoom = false; _this._lastDollyDirection = DOLLY_DIRECTION.NONE; // velocities for smoothDamp _this._thetaVelocity = { value: 0 }; _this._phiVelocity = { value: 0 }; _this._radiusVelocity = { value: 0 }; _this._targetVelocity = new THREE.Vector3(); _this._focalOffsetVelocity = new THREE.Vector3(); _this._zoomVelocity = { value: 0 }; _this._truckInternal = function (deltaX, deltaY, dragToOffset) { var truckX; var pedestalY; if (isPerspectiveCamera(_this._camera)) { var offset = _v3A.copy(_this._camera.position).sub(_this._target); // half of the fov is center to top of screen var fov = _this._camera.getEffectiveFOV() * DEG2RAD; var targetDistance = offset.length() * Math.tan(fov * 0.5); truckX = _this.truckSpeed * deltaX * targetDistance / _this._elementRect.height; pedestalY = _this.truckSpeed * deltaY * targetDistance / _this._elementRect.height; } else if (isOrthographicCamera(_this._camera)) { var _camera = _this._camera; truckX = deltaX * (_camera.right - _camera.left) / _camera.zoom / _this._elementRect.width; pedestalY = deltaY * (_camera.top - _camera.bottom) / _camera.zoom / _this._elementRect.height; } else { return; } if (_this.verticalDragToForward) { dragToOffset ? _this.setFocalOffset(_this._focalOffsetEnd.x + truckX, _this._focalOffsetEnd.y, _this._focalOffsetEnd.z, true) : _this.truck(truckX, 0, true); _this.forward(-pedestalY, true); } else { dragToOffset ? _this.setFocalOffset(_this._focalOffsetEnd.x + truckX, _this._focalOffsetEnd.y + pedestalY, _this._focalOffsetEnd.z, true) : _this.truck(truckX, pedestalY, true); } }; _this._rotateInternal = function (deltaX, deltaY) { var theta = PI_2 * _this.azimuthRotateSpeed * deltaX / _this._elementRect.height; // divide by *height* to refer the resolution var phi = PI_2 * _this.polarRotateSpeed * deltaY / _this._elementRect.height; _this.rotate(theta, phi, true); }; _this._dollyInternal = function (delta, x, y) { var dollyScale = Math.pow(0.95, -delta * _this.dollySpeed); var lastDistance = _this._sphericalEnd.radius; var distance = _this._sphericalEnd.radius * dollyScale; var clampedDistance = clamp(distance, _this.minDistance, _this.maxDistance); var overflowedDistance = clampedDistance - distance; if (_this.infinityDolly && _this.dollyToCursor) { _this._dollyToNoClamp(distance, true); } else if (_this.infinityDolly && !_this.dollyToCursor) { _this.dollyInFixed(overflowedDistance, true); _this._dollyToNoClamp(clampedDistance, true); } else { _this._dollyToNoClamp(clampedDistance, true); } if (_this.dollyToCursor) { _this._changedDolly += (_this.infinityDolly ? distance : clampedDistance) - lastDistance; _this._dollyControlCoord.set(x, y); } _this._lastDollyDirection = Math.sign(-delta); }; _this._zoomInternal = function (delta, x, y) { var zoomScale = Math.pow(0.95, delta * _this.dollySpeed); var lastZoom = _this._zoom; var zoom = _this._zoom * zoomScale; // for both PerspectiveCamera and OrthographicCamera _this.zoomTo(zoom, true); if (_this.dollyToCursor) { _this._changedZoom += zoom - lastZoom; _this._dollyControlCoord.set(x, y); } }; // Check if the user has installed THREE if (typeof THREE === 'undefined') { console.error('camera-controls: `THREE` is undefined. You must first run `CameraControls.install( { THREE: THREE } )`. Check the docs for further information.'); } _this._camera = camera; _this._yAxisUpSpace = new THREE.Quaternion().setFromUnitVectors(_this._camera.up, _AXIS_Y); // this._yAxisUpSpaceInverse = this._yAxisUpSpace.clone().invert(); _this._yAxisUpSpaceInverse = _this._yAxisUpSpace.clone(); _this._state = ACTION.NONE; // the location _this._target = new THREE.Vector3(); _this._targetEnd = _this._target.clone(); _this._focalOffset = new THREE.Vector3(); _this._focalOffsetEnd = _this._focalOffset.clone(); // rotation _this._spherical = new THREE.Spherical().setFromVector3(_v3A.copy(_this._camera.position).applyQuaternion(_this._yAxisUpSpace)); _this._sphericalEnd = _this._spherical.clone(); _this._lastDistance = _this._spherical.radius; _this._zoom = _this._camera.zoom; _this._zoomEnd = _this._zoom; _this._lastZoom = _this._zoom; // collisionTest uses nearPlane.s _this._nearPlaneCorners = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()]; _this._updateNearPlaneCorners(); // Target cannot move outside of this box _this._boundary = new THREE.Box3(new THREE.Vector3(-Infinity, -Infinity, -Infinity), new THREE.Vector3(Infinity, Infinity, Infinity)); // reset _this._cameraUp0 = _this._camera.up.clone(); _this._target0 = _this._target.clone(); _this._position0 = _this._camera.position.clone(); _this._zoom0 = _this._zoom; _this._focalOffset0 = _this._focalOffset.clone(); _this._dollyControlCoord = new THREE.Vector2(); // configs _this.mouseButtons = { left: ACTION.ROTATE, middle: ACTION.DOLLY, right: ACTION.TRUCK, wheel: isPerspectiveCamera(_this._camera) ? ACTION.DOLLY : isOrthographicCamera(_this._camera) ? ACTION.ZOOM : ACTION.NONE }; _this.touches = { one: ACTION.TOUCH_ROTATE, two: isPerspectiveCamera(_this._camera) ? ACTION.TOUCH_DOLLY_TRUCK : isOrthographicCamera(_this._camera) ? ACTION.TOUCH_ZOOM_TRUCK : ACTION.NONE, three: ACTION.TOUCH_TRUCK }; var dragStartPosition = new THREE.Vector2(); var lastDragPosition = new THREE.Vector2(); var dollyStart = new THREE.Vector2(); var onPointerDown = function onPointerDown(event) { if (!_this._enabled || !_this._domElement) return; if (_this._interactiveArea.left !== 0 || _this._interactiveArea.top !== 0 || _this._interactiveArea.width !== 1 || _this._interactiveArea.height !== 1) { var elRect = _this._domElement.getBoundingClientRect(); var left = event.clientX / elRect.width; var top = event.clientY / elRect.height; // check if the interactiveArea contains the drag start position. if (left < _this._interactiveArea.left || left > _this._interactiveArea.right || top < _this._interactiveArea.top || top > _this._interactiveArea.bottom) return; } // Don't call `event.preventDefault()` on the pointerdown event // to keep receiving pointermove evens outside dragging iframe // https://taye.me/blog/tips/2015/11/16/mouse-drag-outside-iframe/ var mouseButton = event.pointerType !== 'mouse' ? null : (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT ? MOUSE_BUTTON.LEFT : (event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE ? MOUSE_BUTTON.MIDDLE : (event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT ? MOUSE_BUTTON.RIGHT : null; if (mouseButton !== null) { var zombiePointer = _this._findPointerByMouseButton(mouseButton); zombiePointer && _this._disposePointer(zombiePointer); } if ((event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT && _this._lockedPointer) return; var pointer = { pointerId: event.pointerId, clientX: event.clientX, clientY: event.clientY, deltaX: 0, deltaY: 0, mouseButton: mouseButton }; _this._activePointers.push(pointer); // eslint-disable-next-line no-undef _this._domElement.ownerDocument.removeEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.removeEventListener('pointerup', onPointerUp); _this._domElement.ownerDocument.addEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.addEventListener('pointerup', onPointerUp); _this._isDragging = true; startDragging(event); }; var onPointerMove = function onPointerMove(event) { if (event.cancelable) event.preventDefault(); var pointerId = event.pointerId; var pointer = _this._lockedPointer || _this._findPointerById(pointerId); if (!pointer) return; pointer.clientX = event.clientX; pointer.clientY = event.clientY; pointer.deltaX = event.movementX; pointer.deltaY = event.movementY; _this._state = 0; if (event.pointerType === 'touch') { switch (_this._activePointers.length) { case 1: _this._state = _this.touches.one; break; case 2: _this._state = _this.touches.two; break; case 3: _this._state = _this.touches.three; break; } } else { if (!_this._isDragging && _this._lockedPointer || _this._isDragging && (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT) { _this._state = _this._state | _this.mouseButtons.left; } if (_this._isDragging && (event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE) { _this._state = _this._state | _this.mouseButtons.middle; } if (_this._isDragging && (event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT) { _this._state = _this._state | _this.mouseButtons.right; } } dragging(); }; var onPointerUp = function onPointerUp(event) { var pointer = _this._findPointerById(event.pointerId); if (pointer && pointer === _this._lockedPointer) return; pointer && _this._disposePointer(pointer); if (event.pointerType === 'touch') { switch (_this._activePointers.length) { case 0: _this._state = ACTION.NONE; break; case 1: _this._state = _this.touches.one; break; case 2: _this._state = _this.touches.two; break; case 3: _this._state = _this.touches.three; break; } } else { _this._state = ACTION.NONE; } endDragging(); }; var lastScrollTimeStamp = -1; var onMouseWheel = function onMouseWheel(event) { if (!_this._domElement) return; if (!_this._enabled || _this.mouseButtons.wheel === ACTION.NONE) return; if (_this._interactiveArea.left !== 0 || _this._interactiveArea.top !== 0 || _this._interactiveArea.width !== 1 || _this._interactiveArea.height !== 1) { var elRect = _this._domElement.getBoundingClientRect(); var left = event.clientX / elRect.width; var top = event.clientY / elRect.height; // check if the interactiveArea contains the drag start position. if (left < _this._interactiveArea.left || left > _this._interactiveArea.right || top < _this._interactiveArea.top || top > _this._interactiveArea.bottom) return; } event.preventDefault(); if (_this.dollyToCursor || _this.mouseButtons.wheel === ACTION.ROTATE || _this.mouseButtons.wheel === ACTION.TRUCK) { var now = performance.now(); // only need to fire this at scroll start. if (lastScrollTimeStamp - now < 1000) _this._getClientRect(_this._elementRect); lastScrollTimeStamp = now; } // Ref: https://github.com/cedricpinson/osgjs/blob/00e5a7e9d9206c06fdde0436e1d62ab7cb5ce853/sources/osgViewer/input/source/InputSourceMouse.js#L89-L103 var deltaYFactor = isMac ? -1 : -3; var delta = event.deltaMode === 1 ? event.deltaY / deltaYFactor : event.deltaY / (deltaYFactor * 10); var x = _this.dollyToCursor ? (event.clientX - _this._elementRect.x) / _this._elementRect.width * 2 - 1 : 0; var y = _this.dollyToCursor ? (event.clientY - _this._elementRect.y) / _this._elementRect.height * -2 + 1 : 0; switch (_this.mouseButtons.wheel) { case ACTION.ROTATE: { _this._rotateInternal(event.deltaX, event.deltaY); _this._isUserControllingRotate = true; break; } case ACTION.TRUCK: { _this._truckInternal(event.deltaX, event.deltaY, false); _this._isUserControllingTruck = true; break; } case ACTION.OFFSET: { _this._truckInternal(event.deltaX, event.deltaY, true); _this._isUserControllingOffset = true; break; } case ACTION.DOLLY: { _this._dollyInternal(-delta, x, y); _this._isUserControllingDolly = true; break; } case ACTION.ZOOM: { _this._zoomInternal(-delta, x, y); _this._isUserControllingZoom = true; break; } } _this.dispatchEvent({ type: 'control' }); }; var onContextMenu = function onContextMenu(event) { if (!_this._domElement || !_this._enabled) return; // contextmenu event is fired right after pointerdown // remove attached handlers and active pointer, if interrupted by contextmenu. if (_this.mouseButtons.right === CameraControls.ACTION.NONE) { var pointerId = event instanceof PointerEvent ? event.pointerId : 0; var pointer = _this._findPointerById(pointerId); pointer && _this._disposePointer(pointer); // eslint-disable-next-line no-undef _this._domElement.ownerDocument.removeEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.removeEventListener('pointerup', onPointerUp); return; } event.preventDefault(); }; var startDragging = function startDragging(event) { if (!_this._enabled) return; extractClientCoordFromEvent(_this._activePointers, _v2); _this._getClientRect(_this._elementRect); dragStartPosition.copy(_v2); lastDragPosition.copy(_v2); var isMultiTouch = _this._activePointers.length >= 2; if (isMultiTouch) { // 2 finger pinch var dx = _v2.x - _this._activePointers[1].clientX; var dy = _v2.y - _this._activePointers[1].clientY; var distance = Math.sqrt(dx * dx + dy * dy); dollyStart.set(0, distance); // center coords of 2 finger truck var x = (_this._activePointers[0].clientX + _this._activePointers[1].clientX) * 0.5; var y = (_this._activePointers[0].clientY + _this._activePointers[1].clientY) * 0.5; lastDragPosition.set(x, y); } _this._state = 0; if (!event) { if (_this._lockedPointer) _this._state = _this._state | _this.mouseButtons.left; } else if ('pointerType' in event && event.pointerType === 'touch') { switch (_this._activePointers.length) { case 1: _this._state = _this.touches.one; break; case 2: _this._state = _this.touches.two; break; case 3: _this._state = _this.touches.three; break; } } else { if (!_this._lockedPointer && (event.buttons & MOUSE_BUTTON.LEFT) === MOUSE_BUTTON.LEFT) { _this._state = _this._state | _this.mouseButtons.left; } if ((event.buttons & MOUSE_BUTTON.MIDDLE) === MOUSE_BUTTON.MIDDLE) { _this._state = _this._state | _this.mouseButtons.middle; } if ((event.buttons & MOUSE_BUTTON.RIGHT) === MOUSE_BUTTON.RIGHT) { _this._state = _this._state | _this.mouseButtons.right; } } // stop current movement on drag start if ((_this._state & ACTION.ROTATE) === ACTION.ROTATE || (_this._state & ACTION.TOUCH_ROTATE) === ACTION.TOUCH_ROTATE || (_this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (_this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) { _this._sphericalEnd.theta = _this._spherical.theta; _this._sphericalEnd.phi = _this._spherical.phi; _this._thetaVelocity.value = 0; _this._phiVelocity.value = 0; } if ((_this._state & ACTION.TRUCK) === ACTION.TRUCK || (_this._state & ACTION.TOUCH_TRUCK) === ACTION.TOUCH_TRUCK || (_this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (_this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK) { _this._targetEnd.copy(_this._target); _this._targetVelocity.set(0, 0, 0); } if ((_this._state & ACTION.DOLLY) === ACTION.DOLLY || (_this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (_this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (_this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (_this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE) { _this._sphericalEnd.radius = _this._spherical.radius; _this._radiusVelocity.value = 0; } if ((_this._state & ACTION.ZOOM) === ACTION.ZOOM || (_this._state & ACTION.TOUCH_ZOOM) === ACTION.TOUCH_ZOOM || (_this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK || (_this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET || (_this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) { _this._zoomEnd = _this._zoom; _this._zoomVelocity.value = 0; } if ((_this._state & ACTION.OFFSET) === ACTION.OFFSET || (_this._state & ACTION.TOUCH_OFFSET) === ACTION.TOUCH_OFFSET || (_this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (_this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET) { _this._focalOffsetEnd.copy(_this._focalOffset); _this._focalOffsetVelocity.set(0, 0, 0); } _this.dispatchEvent({ type: 'controlstart' }); }; var dragging = function dragging() { if (!_this._enabled || !_this._dragNeedsUpdate) return; _this._dragNeedsUpdate = false; extractClientCoordFromEvent(_this._activePointers, _v2); // When pointer lock is enabled clientX, clientY, screenX, and screenY remain 0. // If pointer lock is enabled, use the Delta directory, and assume active-pointer is not multiple. var isPointerLockActive = _this._domElement && _this._domElement.ownerDocument.pointerLockElement === _this._domElement; var lockedPointer = isPointerLockActive ? _this._lockedPointer || _this._activePointers[0] : null; var deltaX = lockedPointer ? -lockedPointer.deltaX : lastDragPosition.x - _v2.x; var deltaY = lockedPointer ? -lockedPointer.deltaY : lastDragPosition.y - _v2.y; lastDragPosition.copy(_v2); if ((_this._state & ACTION.ROTATE) === ACTION.ROTATE || (_this._state & ACTION.TOUCH_ROTATE) === ACTION.TOUCH_ROTATE || (_this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (_this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) { _this._rotateInternal(deltaX, deltaY); _this._isUserControllingRotate = true; } if ((_this._state & ACTION.DOLLY) === ACTION.DOLLY || (_this._state & ACTION.ZOOM) === ACTION.ZOOM) { var dollyX = _this.dollyToCursor ? (dragStartPosition.x - _this._elementRect.x) / _this._elementRect.width * 2 - 1 : 0; var dollyY = _this.dollyToCursor ? (dragStartPosition.y - _this._elementRect.y) / _this._elementRect.height * -2 + 1 : 0; var dollyDirection = _this.dollyDragInverted ? -1 : 1; if ((_this._state & ACTION.DOLLY) === ACTION.DOLLY) { _this._dollyInternal(dollyDirection * deltaY * TOUCH_DOLLY_FACTOR, dollyX, dollyY); _this._isUserControllingDolly = true; } else { _this._zoomInternal(dollyDirection * deltaY * TOUCH_DOLLY_FACTOR, dollyX, dollyY); _this._isUserControllingZoom = true; } } if ((_this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (_this._state & ACTION.TOUCH_ZOOM) === ACTION.TOUCH_ZOOM || (_this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (_this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK || (_this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (_this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET || (_this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (_this._state & ACTION.TOUCH_ZOOM_ROTATE) === ACTION.TOUCH_ZOOM_ROTATE) { var dx = _v2.x - _this._activePointers[1].clientX; var dy = _v2.y - _this._activePointers[1].clientY; var distance = Math.sqrt(dx * dx + dy * dy); var dollyDelta = dollyStart.y - distance; dollyStart.set(0, distance); var _dollyX = _this.dollyToCursor ? (lastDragPosition.x - _this._elementRect.x) / _this._elementRect.width * 2 - 1 : 0; var _dollyY = _this.dollyToCursor ? (lastDragPosition.y - _this._elementRect.y) / _this._elementRect.height * -2 + 1 : 0; if ((_this._state & ACTION.TOUCH_DOLLY) === ACTION.TOUCH_DOLLY || (_this._state & ACTION.TOUCH_DOLLY_ROTATE) === ACTION.TOUCH_DOLLY_ROTATE || (_this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (_this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET) { _this._dollyInternal(dollyDelta * TOUCH_DOLLY_FACTOR, _dollyX, _dollyY); _this._isUserControllingDolly = true; } else { _this._zoomInternal(dollyDelta * TOUCH_DOLLY_FACTOR, _dollyX, _dollyY); _this._isUserControllingZoom = true; } } if ((_this._state & ACTION.TRUCK) === ACTION.TRUCK || (_this._state & ACTION.TOUCH_TRUCK) === ACTION.TOUCH_TRUCK || (_this._state & ACTION.TOUCH_DOLLY_TRUCK) === ACTION.TOUCH_DOLLY_TRUCK || (_this._state & ACTION.TOUCH_ZOOM_TRUCK) === ACTION.TOUCH_ZOOM_TRUCK) { _this._truckInternal(deltaX, deltaY, false); _this._isUserControllingTruck = true; } if ((_this._state & ACTION.OFFSET) === ACTION.OFFSET || (_this._state & ACTION.TOUCH_OFFSET) === ACTION.TOUCH_OFFSET || (_this._state & ACTION.TOUCH_DOLLY_OFFSET) === ACTION.TOUCH_DOLLY_OFFSET || (_this._state & ACTION.TOUCH_ZOOM_OFFSET) === ACTION.TOUCH_ZOOM_OFFSET) { _this._truckInternal(deltaX, deltaY, true); _this._isUserControllingOffset = true; } _this.dispatchEvent({ type: 'control' }); }; var endDragging = function endDragging() { extractClientCoordFromEvent(_this._activePointers, _v2); lastDragPosition.copy(_v2); _this._dragNeedsUpdate = false; if (_this._activePointers.length === 0 || _this._activePointers.length === 1 && _this._activePointers[0] === _this._lockedPointer) { _this._isDragging = false; } if (_this._activePointers.length === 0 && _this._domElement) { // eslint-disable-next-line no-undef _this._domElement.ownerDocument.removeEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.removeEventListener('pointerup', onPointerUp); _this.dispatchEvent({ type: 'controlend' }); } }; _this.lockPointer = function () { if (!_this._enabled || !_this._domElement) return; _this.cancel(); // Element.requestPointerLock is allowed to happen without any pointer active - create a faux one for compatibility with controls _this._lockedPointer = { pointerId: -1, clientX: 0, clientY: 0, deltaX: 0, deltaY: 0, mouseButton: null }; _this._activePointers.push(_this._lockedPointer); // eslint-disable-next-line no-undef _this._domElement.ownerDocument.removeEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.removeEventListener('pointerup', onPointerUp); _this._domElement.requestPointerLock(); _this._domElement.ownerDocument.addEventListener('pointerlockchange', onPointerLockChange); _this._domElement.ownerDocument.addEventListener('pointerlockerror', onPointerLockError); _this._domElement.ownerDocument.addEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.addEventListener('pointerup', onPointerUp); startDragging(); }; _this.unlockPointer = function () { var _a, _b, _c; if (_this._lockedPointer !== null) { _this._disposePointer(_this._lockedPointer); _this._lockedPointer = null; } (_a = _this._domElement) === null || _a === void 0 ? void 0 : _a.ownerDocument.exitPointerLock(); (_b = _this._domElement) === null || _b === void 0 ? void 0 : _b.ownerDocument.removeEventListener('pointerlockchange', onPointerLockChange); (_c = _this._domElement) === null || _c === void 0 ? void 0 : _c.ownerDocument.removeEventListener('pointerlockerror', onPointerLockError); _this.cancel(); }; var onPointerLockChange = function onPointerLockChange() { var isPointerLockActive = _this._domElement && _this._domElement.ownerDocument.pointerLockElement === _this._domElement; if (!isPointerLockActive) _this.unlockPointer(); }; var onPointerLockError = function onPointerLockError() { _this.unlockPointer(); }; _this._addAllEventListeners = function (domElement) { _this._domElement = domElement; _this._domElement.style.touchAction = 'none'; _this._domElement.style.userSelect = 'none'; _this._domElement.style.webkitUserSelect = 'none'; _this._domElement.addEventListener('pointerdown', onPointerDown); _this._domElement.addEventListener('pointercancel', onPointerUp); _this._domElement.addEventListener('wheel', onMouseWheel, { passive: false }); _this._domElement.addEventListener('contextmenu', onContextMenu); }; _this._removeAllEventListeners = function () { if (!_this._domElement) return; _this._domElement.style.touchAction = ''; _this._domElement.style.userSelect = ''; _this._domElement.style.webkitUserSelect = ''; _this._domElement.removeEventListener('pointerdown', onPointerDown); _this._domElement.removeEventListener('pointercancel', onPointerUp); // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener#matching_event_listeners_for_removal // > it's probably wise to use the same values used for the call to `addEventListener()` when calling `removeEventListener()` // see https://github.com/microsoft/TypeScript/issues/32912#issuecomment-522142969 // eslint-disable-next-line no-undef _this._domElement.removeEventListener('wheel', onMouseWheel, { passive: false }); _this._domElement.removeEventListener('contextmenu', onContextMenu); // eslint-disable-next-line no-undef _this._domElement.ownerDocument.removeEventListener('pointermove', onPointerMove, { passive: false }); _this._domElement.ownerDocument.removeEventListener('pointerup', onPointerUp); _this._domElement.ownerDocument.removeEventListener('pointerlockchange', onPointerLockChange); _this._domElement.ownerDocument.removeEventListener('pointerlockerror', onPointerLockError); }; _this.cancel = function () { if (_this._state === ACTION.NONE) return; _this._state = ACTION.NONE; _this._activePointers.length = 0; endDragging(); }; if (domElement) _this.connect(domElement); _this.update(0); return _this; } /** * The camera to be controlled * @category Properties */ (0, _inherits2["default"])(CameraControls, _EventDispatcher); return (0, _createClass2["default"])(CameraControls, [{ key: "camera", get: function get() { return this._camera; }, set: function set(camera) { this._camera = camera; this.updateCameraUp(); this._camera.updateProjectionMatrix(); this._updateNearPlaneCorners(); this._needsUpdate = true; } /** * Whether or not the controls are enabled. * `false` to disable user dragging/touch-move, but all methods works. * @category Properties */ }, { key: "enabled", get: function get() { return this._enabled; }, set: function set(enabled) { this._enabled = enabled; if (!this._domElement) return; if (enabled) { this._domElement.style.touchAction = 'none'; this._domElement.style.userSelect = 'none'; this._domElement.style.webkitUserSelect = 'none'; } else { this.cancel(); this._domElement.style.touchAction = ''; this._domElement.style.userSelect = ''; this._domElement.style.webkitUserSelect = ''; } } /** * Returns `true` if the controls are active updating. * readonly value. * @category Properties */ }, { key: "active", get: function get() { return !this._hasRested; } /** * Getter for the current `ACTION`. * readonly value. * @category Properties */ }, { key: "currentAction", get: function get() { return this._state; } /** * get/set Current distance. * @category Properties */ }, { key: "distance", get: function get() { return this._spherical.radius; }, set: function set(distance) { if (this._spherical.radius === distance && this._sphericalEnd.radius === distance) return; this._spherical.radius = distance; this._sphericalEnd.radius = distance; this._needsUpdate = true; } // horizontal angle /** * get/set the azimuth angle (horizontal) in radians. * Every 360 degrees turn is added to `.azimuthAngle` value, which is accumulative. * @category Properties */ }, { key: "azimuthAngle", get: function get() { return this._spherical.theta; }, set: function set(azimuthAngle) { if (this._spherical.theta === azimuthAngle && this._sphericalEnd.theta === azimuthAngle) return; this._spherical.theta = azimuthAngle; this._sphericalEnd.theta = azimuthAngle; this._needsUpdate = true; } // vertical angle /** * get/set the polar angle (vertical) in radians. * @category Properties */ }, { key: "polarAngle", get: function get() { return this._spherical.phi; }, set: function set(polarAngle) { if (this._spherical.phi === polarAngle && this._sphericalEnd.phi === polarAngle) return; this._spherical.phi = polarAngle; this._sphericalEnd.phi = polarAngle; this._needsUpdate = true; } /** * Whether camera position should be enclosed in the boundary or not. * @category Properties */ }, { key: "boundaryEnclosesCamera", get: function get() { return this._boundaryEnclosesCamera; }, set: function set(boundaryEnclosesCamera) { this._boundaryEnclosesCamera = boundaryEnclosesCamera; this._needsUpdate = true; } /** * Set drag-start, touches and wheel enable area in the domElement. * each values are between `0` and `1` inclusive, where `0` is left/top and `1` is right/bottom of the screen. * e.g. `{ x: 0, y: 0, width: 1, height: 1 }` for entire area. * @category Properties */ }, { key: "interactiveArea", set: function set(interactiveArea) { this._interactiveArea.width = clamp(interactiveArea.width, 0, 1); this._interactiveArea.height = clamp(interactiveArea.height, 0, 1); this._interactiveArea.x = clamp(interactiveArea.x, 0, 1 - this._interactiveArea.width); this._interactiveArea.y = clamp(interactiveArea.y, 0, 1 - this._interactiveArea.height); } /** * Adds the specified event listener. * Applicable event types (which is `K`) are: * | Event name | Timing | * | ------------------- | ------ | * | `'controlstart'` | When the user starts to control the camera via mouse / touches. ¹ | * | `'control'` | When the user controls the camera (dragging). | * | `'controlend'` | When the user ends to control the camera. ¹ | * | `'transitionstart'` | When any kind of transition starts, either user control or using a method with `enableTransition = true` | * | `'update'` | When the camera position is updated. | * | `'wake'` | When the camera starts moving. | * | `'rest'` | When the camera movement is below `.restThreshold` ². | * | `'sleep'` | When the camera end moving. | * * 1. `mouseButtons.wheel` (Mouse wheel control) does not emit `'controlstart'` and `'controlend'`. `mouseButtons.wheel` uses scroll-event internally, and scroll-event happens intermittently. That means "s