123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140 |
- import AssociativeArray from "./AssociativeArray.js";
- import Cartesian2 from "./Cartesian2.js";
- import defaultValue from "./defaultValue.js";
- import defined from "./defined.js";
- import destroyObject from "./destroyObject.js";
- import DeveloperError from "./DeveloperError.js";
- import FeatureDetection from "./FeatureDetection.js";
- import getTimestamp from "./getTimestamp.js";
- import KeyboardEventModifier from "./KeyboardEventModifier.js";
- import ScreenSpaceEventType from "./ScreenSpaceEventType.js";
- function getPosition(screenSpaceEventHandler, event, result) {
- const element = screenSpaceEventHandler._element;
- if (element === document) {
- result.x = event.clientX;
- result.y = event.clientY;
- return result;
- }
- const rect = element.getBoundingClientRect();
- result.x = event.clientX - rect.left;
- result.y = event.clientY - rect.top;
- return result;
- }
- function getInputEventKey(type, modifier) {
- let key = type;
- if (defined(modifier)) {
- key += `+${modifier}`;
- }
- return key;
- }
- function getModifier(event) {
- if (event.shiftKey) {
- return KeyboardEventModifier.SHIFT;
- } else if (event.ctrlKey) {
- return KeyboardEventModifier.CTRL;
- } else if (event.altKey) {
- return KeyboardEventModifier.ALT;
- }
- return undefined;
- }
- const MouseButton = {
- LEFT: 0,
- MIDDLE: 1,
- RIGHT: 2,
- };
- function registerListener(screenSpaceEventHandler, domType, element, callback) {
- function listener(e) {
- callback(screenSpaceEventHandler, e);
- }
- if (FeatureDetection.isInternetExplorer()) {
- element.addEventListener(domType, listener, false);
- } else {
- element.addEventListener(domType, listener, {
- capture: false,
- passive: false,
- });
- }
- screenSpaceEventHandler._removalFunctions.push(function () {
- element.removeEventListener(domType, listener, false);
- });
- }
- function registerListeners(screenSpaceEventHandler) {
- const element = screenSpaceEventHandler._element;
- // some listeners may be registered on the document, so we still get events even after
- // leaving the bounds of element.
- // this is affected by the existence of an undocumented disableRootEvents property on element.
- const alternateElement = !defined(element.disableRootEvents)
- ? document
- : element;
- if (FeatureDetection.supportsPointerEvents()) {
- registerListener(
- screenSpaceEventHandler,
- "pointerdown",
- element,
- handlePointerDown
- );
- registerListener(
- screenSpaceEventHandler,
- "pointerup",
- element,
- handlePointerUp
- );
- registerListener(
- screenSpaceEventHandler,
- "pointermove",
- element,
- handlePointerMove
- );
- registerListener(
- screenSpaceEventHandler,
- "pointercancel",
- element,
- handlePointerUp
- );
- } else {
- registerListener(
- screenSpaceEventHandler,
- "mousedown",
- element,
- handleMouseDown
- );
- registerListener(
- screenSpaceEventHandler,
- "mouseup",
- alternateElement,
- handleMouseUp
- );
- registerListener(
- screenSpaceEventHandler,
- "mousemove",
- alternateElement,
- handleMouseMove
- );
- registerListener(
- screenSpaceEventHandler,
- "touchstart",
- element,
- handleTouchStart
- );
- registerListener(
- screenSpaceEventHandler,
- "touchend",
- alternateElement,
- handleTouchEnd
- );
- registerListener(
- screenSpaceEventHandler,
- "touchmove",
- alternateElement,
- handleTouchMove
- );
- registerListener(
- screenSpaceEventHandler,
- "touchcancel",
- alternateElement,
- handleTouchEnd
- );
- }
- registerListener(
- screenSpaceEventHandler,
- "dblclick",
- element,
- handleDblClick
- );
- // detect available wheel event
- let wheelEvent;
- if ("onwheel" in element) {
- // spec event type
- wheelEvent = "wheel";
- } else if (document.onmousewheel !== undefined) {
- // legacy event type
- wheelEvent = "mousewheel";
- } else {
- // older Firefox
- wheelEvent = "DOMMouseScroll";
- }
- registerListener(screenSpaceEventHandler, wheelEvent, element, handleWheel);
- }
- function unregisterListeners(screenSpaceEventHandler) {
- const removalFunctions = screenSpaceEventHandler._removalFunctions;
- for (let i = 0; i < removalFunctions.length; ++i) {
- removalFunctions[i]();
- }
- }
- const mouseDownEvent = {
- position: new Cartesian2(),
- };
- function gotTouchEvent(screenSpaceEventHandler) {
- screenSpaceEventHandler._lastSeenTouchEvent = getTimestamp();
- }
- function canProcessMouseEvent(screenSpaceEventHandler) {
- return (
- getTimestamp() - screenSpaceEventHandler._lastSeenTouchEvent >
- ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds
- );
- }
- function checkPixelTolerance(startPosition, endPosition, pixelTolerance) {
- const xDiff = startPosition.x - endPosition.x;
- const yDiff = startPosition.y - endPosition.y;
- const totalPixels = Math.sqrt(xDiff * xDiff + yDiff * yDiff);
- return totalPixels < pixelTolerance;
- }
- function handleMouseDown(screenSpaceEventHandler, event) {
- if (!canProcessMouseEvent(screenSpaceEventHandler)) {
- return;
- }
- const button = event.button;
- screenSpaceEventHandler._buttonDown[button] = true;
- let screenSpaceEventType;
- if (button === MouseButton.LEFT) {
- screenSpaceEventType = ScreenSpaceEventType.LEFT_DOWN;
- } else if (button === MouseButton.MIDDLE) {
- screenSpaceEventType = ScreenSpaceEventType.MIDDLE_DOWN;
- } else if (button === MouseButton.RIGHT) {
- screenSpaceEventType = ScreenSpaceEventType.RIGHT_DOWN;
- } else {
- return;
- }
- const position = getPosition(
- screenSpaceEventHandler,
- event,
- screenSpaceEventHandler._primaryPosition
- );
- Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition);
- Cartesian2.clone(position, screenSpaceEventHandler._primaryPreviousPosition);
- const modifier = getModifier(event);
- const action = screenSpaceEventHandler.getInputAction(
- screenSpaceEventType,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(position, mouseDownEvent.position);
- action(mouseDownEvent);
- event.preventDefault();
- }
- }
- const mouseUpEvent = {
- position: new Cartesian2(),
- };
- const mouseClickEvent = {
- position: new Cartesian2(),
- };
- function cancelMouseEvent(
- screenSpaceEventHandler,
- screenSpaceEventType,
- clickScreenSpaceEventType,
- event
- ) {
- const modifier = getModifier(event);
- const action = screenSpaceEventHandler.getInputAction(
- screenSpaceEventType,
- modifier
- );
- const clickAction = screenSpaceEventHandler.getInputAction(
- clickScreenSpaceEventType,
- modifier
- );
- if (defined(action) || defined(clickAction)) {
- const position = getPosition(
- screenSpaceEventHandler,
- event,
- screenSpaceEventHandler._primaryPosition
- );
- if (defined(action)) {
- Cartesian2.clone(position, mouseUpEvent.position);
- action(mouseUpEvent);
- }
- if (defined(clickAction)) {
- const startPosition = screenSpaceEventHandler._primaryStartPosition;
- if (
- checkPixelTolerance(
- startPosition,
- position,
- screenSpaceEventHandler._clickPixelTolerance
- )
- ) {
- Cartesian2.clone(position, mouseClickEvent.position);
- clickAction(mouseClickEvent);
- }
- }
- }
- }
- function handleMouseUp(screenSpaceEventHandler, event) {
- if (!canProcessMouseEvent(screenSpaceEventHandler)) {
- return;
- }
- const button = event.button;
- if (
- button !== MouseButton.LEFT &&
- button !== MouseButton.MIDDLE &&
- button !== MouseButton.RIGHT
- ) {
- return;
- }
- if (screenSpaceEventHandler._buttonDown[MouseButton.LEFT]) {
- cancelMouseEvent(
- screenSpaceEventHandler,
- ScreenSpaceEventType.LEFT_UP,
- ScreenSpaceEventType.LEFT_CLICK,
- event
- );
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT] = false;
- }
- if (screenSpaceEventHandler._buttonDown[MouseButton.MIDDLE]) {
- cancelMouseEvent(
- screenSpaceEventHandler,
- ScreenSpaceEventType.MIDDLE_UP,
- ScreenSpaceEventType.MIDDLE_CLICK,
- event
- );
- screenSpaceEventHandler._buttonDown[MouseButton.MIDDLE] = false;
- }
- if (screenSpaceEventHandler._buttonDown[MouseButton.RIGHT]) {
- cancelMouseEvent(
- screenSpaceEventHandler,
- ScreenSpaceEventType.RIGHT_UP,
- ScreenSpaceEventType.RIGHT_CLICK,
- event
- );
- screenSpaceEventHandler._buttonDown[MouseButton.RIGHT] = false;
- }
- }
- const mouseMoveEvent = {
- startPosition: new Cartesian2(),
- endPosition: new Cartesian2(),
- };
- function handleMouseMove(screenSpaceEventHandler, event) {
- if (!canProcessMouseEvent(screenSpaceEventHandler)) {
- return;
- }
- const modifier = getModifier(event);
- const position = getPosition(
- screenSpaceEventHandler,
- event,
- screenSpaceEventHandler._primaryPosition
- );
- const previousPosition = screenSpaceEventHandler._primaryPreviousPosition;
- const action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.MOUSE_MOVE,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(previousPosition, mouseMoveEvent.startPosition);
- Cartesian2.clone(position, mouseMoveEvent.endPosition);
- action(mouseMoveEvent);
- }
- Cartesian2.clone(position, previousPosition);
- if (
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT] ||
- screenSpaceEventHandler._buttonDown[MouseButton.MIDDLE] ||
- screenSpaceEventHandler._buttonDown[MouseButton.RIGHT]
- ) {
- event.preventDefault();
- }
- }
- const mouseDblClickEvent = {
- position: new Cartesian2(),
- };
- function handleDblClick(screenSpaceEventHandler, event) {
- const button = event.button;
- let screenSpaceEventType;
- if (button === MouseButton.LEFT) {
- screenSpaceEventType = ScreenSpaceEventType.LEFT_DOUBLE_CLICK;
- } else {
- return;
- }
- const modifier = getModifier(event);
- const action = screenSpaceEventHandler.getInputAction(
- screenSpaceEventType,
- modifier
- );
- if (defined(action)) {
- getPosition(screenSpaceEventHandler, event, mouseDblClickEvent.position);
- action(mouseDblClickEvent);
- }
- }
- function handleWheel(screenSpaceEventHandler, event) {
- // currently this event exposes the delta value in terms of
- // the obsolete mousewheel event type. so, for now, we adapt the other
- // values to that scheme.
- let delta;
- // standard wheel event uses deltaY. sign is opposite wheelDelta.
- // deltaMode indicates what unit it is in.
- if (defined(event.deltaY)) {
- const deltaMode = event.deltaMode;
- if (deltaMode === event.DOM_DELTA_PIXEL) {
- delta = -event.deltaY;
- } else if (deltaMode === event.DOM_DELTA_LINE) {
- delta = -event.deltaY * 40;
- } else {
- // DOM_DELTA_PAGE
- delta = -event.deltaY * 120;
- }
- } else if (event.detail > 0) {
- // old Firefox versions use event.detail to count the number of clicks. The sign
- // of the integer is the direction the wheel is scrolled.
- delta = event.detail * -120;
- } else {
- delta = event.wheelDelta;
- }
- if (!defined(delta)) {
- return;
- }
- const modifier = getModifier(event);
- const action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.WHEEL,
- modifier
- );
- if (defined(action)) {
- action(delta);
- event.preventDefault();
- }
- }
- function handleTouchStart(screenSpaceEventHandler, event) {
- gotTouchEvent(screenSpaceEventHandler);
- const changedTouches = event.changedTouches;
- let i;
- const length = changedTouches.length;
- let touch;
- let identifier;
- const positions = screenSpaceEventHandler._positions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- positions.set(
- identifier,
- getPosition(screenSpaceEventHandler, touch, new Cartesian2())
- );
- }
- fireTouchEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- previousPositions.set(
- identifier,
- Cartesian2.clone(positions.get(identifier))
- );
- }
- }
- function handleTouchEnd(screenSpaceEventHandler, event) {
- gotTouchEvent(screenSpaceEventHandler);
- const changedTouches = event.changedTouches;
- let i;
- const length = changedTouches.length;
- let touch;
- let identifier;
- const positions = screenSpaceEventHandler._positions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- positions.remove(identifier);
- }
- fireTouchEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- previousPositions.remove(identifier);
- }
- }
- const touchStartEvent = {
- position: new Cartesian2(),
- };
- const touch2StartEvent = {
- position1: new Cartesian2(),
- position2: new Cartesian2(),
- };
- const touchEndEvent = {
- position: new Cartesian2(),
- };
- const touchClickEvent = {
- position: new Cartesian2(),
- };
- const touchHoldEvent = {
- position: new Cartesian2(),
- };
- function fireTouchEvents(screenSpaceEventHandler, event) {
- const modifier = getModifier(event);
- const positions = screenSpaceEventHandler._positions;
- const numberOfTouches = positions.length;
- let action;
- let clickAction;
- const pinching = screenSpaceEventHandler._isPinching;
- if (
- numberOfTouches !== 1 &&
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT]
- ) {
- // transitioning from single touch, trigger UP and might trigger CLICK
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT] = false;
- if (defined(screenSpaceEventHandler._touchHoldTimer)) {
- clearTimeout(screenSpaceEventHandler._touchHoldTimer);
- screenSpaceEventHandler._touchHoldTimer = undefined;
- }
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.LEFT_UP,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(
- screenSpaceEventHandler._primaryPosition,
- touchEndEvent.position
- );
- action(touchEndEvent);
- }
- if (numberOfTouches === 0 && !screenSpaceEventHandler._isTouchHolding) {
- // releasing single touch, check for CLICK
- clickAction = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.LEFT_CLICK,
- modifier
- );
- if (defined(clickAction)) {
- const startPosition = screenSpaceEventHandler._primaryStartPosition;
- const endPosition =
- screenSpaceEventHandler._previousPositions.values[0];
- if (
- checkPixelTolerance(
- startPosition,
- endPosition,
- screenSpaceEventHandler._clickPixelTolerance
- )
- ) {
- Cartesian2.clone(
- screenSpaceEventHandler._primaryPosition,
- touchClickEvent.position
- );
- clickAction(touchClickEvent);
- }
- }
- }
- screenSpaceEventHandler._isTouchHolding = false;
- // Otherwise don't trigger CLICK, because we are adding more touches.
- }
- if (numberOfTouches === 0 && pinching) {
- // transitioning from pinch, trigger PINCH_END
- screenSpaceEventHandler._isPinching = false;
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.PINCH_END,
- modifier
- );
- if (defined(action)) {
- action();
- }
- }
- if (numberOfTouches === 1 && !pinching) {
- // transitioning to single touch, trigger DOWN
- const position = positions.values[0];
- Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition);
- Cartesian2.clone(position, screenSpaceEventHandler._primaryStartPosition);
- Cartesian2.clone(
- position,
- screenSpaceEventHandler._primaryPreviousPosition
- );
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT] = true;
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.LEFT_DOWN,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(position, touchStartEvent.position);
- action(touchStartEvent);
- }
- screenSpaceEventHandler._touchHoldTimer = setTimeout(function () {
- if (!screenSpaceEventHandler.isDestroyed()) {
- screenSpaceEventHandler._touchHoldTimer = undefined;
- screenSpaceEventHandler._isTouchHolding = true;
- clickAction = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.RIGHT_CLICK,
- modifier
- );
- if (defined(clickAction)) {
- const startPosition = screenSpaceEventHandler._primaryStartPosition;
- const endPosition =
- screenSpaceEventHandler._previousPositions.values[0];
- if (
- checkPixelTolerance(
- startPosition,
- endPosition,
- screenSpaceEventHandler._holdPixelTolerance
- )
- ) {
- Cartesian2.clone(
- screenSpaceEventHandler._primaryPosition,
- touchHoldEvent.position
- );
- clickAction(touchHoldEvent);
- }
- }
- }
- }, ScreenSpaceEventHandler.touchHoldDelayMilliseconds);
- event.preventDefault();
- }
- if (numberOfTouches === 2 && !pinching) {
- // transitioning to pinch, trigger PINCH_START
- screenSpaceEventHandler._isPinching = true;
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.PINCH_START,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(positions.values[0], touch2StartEvent.position1);
- Cartesian2.clone(positions.values[1], touch2StartEvent.position2);
- action(touch2StartEvent);
- // Touch-enabled devices, in particular iOS can have many default behaviours for
- // "pinch" events, which can still be executed unless we prevent them here.
- event.preventDefault();
- }
- }
- }
- function handleTouchMove(screenSpaceEventHandler, event) {
- gotTouchEvent(screenSpaceEventHandler);
- const changedTouches = event.changedTouches;
- let i;
- const length = changedTouches.length;
- let touch;
- let identifier;
- const positions = screenSpaceEventHandler._positions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- const position = positions.get(identifier);
- if (defined(position)) {
- getPosition(screenSpaceEventHandler, touch, position);
- }
- }
- fireTouchMoveEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- for (i = 0; i < length; ++i) {
- touch = changedTouches[i];
- identifier = touch.identifier;
- Cartesian2.clone(
- positions.get(identifier),
- previousPositions.get(identifier)
- );
- }
- }
- const touchMoveEvent = {
- startPosition: new Cartesian2(),
- endPosition: new Cartesian2(),
- };
- const touchPinchMovementEvent = {
- distance: {
- startPosition: new Cartesian2(),
- endPosition: new Cartesian2(),
- },
- angleAndHeight: {
- startPosition: new Cartesian2(),
- endPosition: new Cartesian2(),
- },
- };
- function fireTouchMoveEvents(screenSpaceEventHandler, event) {
- const modifier = getModifier(event);
- const positions = screenSpaceEventHandler._positions;
- const previousPositions = screenSpaceEventHandler._previousPositions;
- const numberOfTouches = positions.length;
- let action;
- if (
- numberOfTouches === 1 &&
- screenSpaceEventHandler._buttonDown[MouseButton.LEFT]
- ) {
- // moving single touch
- const position = positions.values[0];
- Cartesian2.clone(position, screenSpaceEventHandler._primaryPosition);
- const previousPosition = screenSpaceEventHandler._primaryPreviousPosition;
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.MOUSE_MOVE,
- modifier
- );
- if (defined(action)) {
- Cartesian2.clone(previousPosition, touchMoveEvent.startPosition);
- Cartesian2.clone(position, touchMoveEvent.endPosition);
- action(touchMoveEvent);
- }
- Cartesian2.clone(position, previousPosition);
- event.preventDefault();
- } else if (numberOfTouches === 2 && screenSpaceEventHandler._isPinching) {
- // moving pinch
- action = screenSpaceEventHandler.getInputAction(
- ScreenSpaceEventType.PINCH_MOVE,
- modifier
- );
- if (defined(action)) {
- const position1 = positions.values[0];
- const position2 = positions.values[1];
- const previousPosition1 = previousPositions.values[0];
- const previousPosition2 = previousPositions.values[1];
- const dX = position2.x - position1.x;
- const dY = position2.y - position1.y;
- const dist = Math.sqrt(dX * dX + dY * dY) * 0.25;
- const prevDX = previousPosition2.x - previousPosition1.x;
- const prevDY = previousPosition2.y - previousPosition1.y;
- const prevDist = Math.sqrt(prevDX * prevDX + prevDY * prevDY) * 0.25;
- const cY = (position2.y + position1.y) * 0.125;
- const prevCY = (previousPosition2.y + previousPosition1.y) * 0.125;
- const angle = Math.atan2(dY, dX);
- const prevAngle = Math.atan2(prevDY, prevDX);
- Cartesian2.fromElements(
- 0.0,
- prevDist,
- touchPinchMovementEvent.distance.startPosition
- );
- Cartesian2.fromElements(
- 0.0,
- dist,
- touchPinchMovementEvent.distance.endPosition
- );
- Cartesian2.fromElements(
- prevAngle,
- prevCY,
- touchPinchMovementEvent.angleAndHeight.startPosition
- );
- Cartesian2.fromElements(
- angle,
- cY,
- touchPinchMovementEvent.angleAndHeight.endPosition
- );
- action(touchPinchMovementEvent);
- }
- }
- }
- function handlePointerDown(screenSpaceEventHandler, event) {
- event.target.setPointerCapture(event.pointerId);
- if (event.pointerType === "touch") {
- const positions = screenSpaceEventHandler._positions;
- const identifier = event.pointerId;
- positions.set(
- identifier,
- getPosition(screenSpaceEventHandler, event, new Cartesian2())
- );
- fireTouchEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- previousPositions.set(
- identifier,
- Cartesian2.clone(positions.get(identifier))
- );
- } else {
- handleMouseDown(screenSpaceEventHandler, event);
- }
- }
- function handlePointerUp(screenSpaceEventHandler, event) {
- if (event.pointerType === "touch") {
- const positions = screenSpaceEventHandler._positions;
- const identifier = event.pointerId;
- positions.remove(identifier);
- fireTouchEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- previousPositions.remove(identifier);
- } else {
- handleMouseUp(screenSpaceEventHandler, event);
- }
- }
- function handlePointerMove(screenSpaceEventHandler, event) {
- if (event.pointerType === "touch") {
- const positions = screenSpaceEventHandler._positions;
- const identifier = event.pointerId;
- const position = positions.get(identifier);
- if (!defined(position)) {
- return;
- }
- getPosition(screenSpaceEventHandler, event, position);
- fireTouchMoveEvents(screenSpaceEventHandler, event);
- const previousPositions = screenSpaceEventHandler._previousPositions;
- Cartesian2.clone(
- positions.get(identifier),
- previousPositions.get(identifier)
- );
- } else {
- handleMouseMove(screenSpaceEventHandler, event);
- }
- }
- /**
- * @typedef {Object} ScreenSpaceEventHandler.PositionedEvent
- *
- * An Event that occurs at a single position on screen.
- *
- * @property {Cartesian2} position
- */
- /**
- * @callback ScreenSpaceEventHandler.PositionedEventCallback
- *
- * The callback invoked when a positioned event triggers an event listener.
- *
- * @param {ScreenSpaceEventHandler.PositionedEvent} event The event which triggered the listener
- */
- /**
- * @typedef {Object} ScreenSpaceEventHandler.MotionEvent
- *
- * An Event that starts at one position and ends at another.
- *
- * @property {Cartesian2} startPosition
- * @property {Cartesian2} endPosition
- */
- /**
- * @callback ScreenSpaceEventHandler.MotionEventCallback
- *
- * The callback invoked when a motion event triggers an event listener.
- *
- * @param {ScreenSpaceEventHandler.MotionEvent} event The event which triggered the listener
- */
- /**
- * @typedef {Object} ScreenSpaceEventHandler.TwoPointEvent
- *
- * An Event that occurs at a two positions on screen.
- *
- * @property {Cartesian2} position1
- * @property {Cartesian2} position2
- */
- /**
- * @callback ScreenSpaceEventHandler.TwoPointEventCallback
- *
- * The callback invoked when a two-point event triggers an event listener.
- *
- * @param {ScreenSpaceEventHandler.TwoPointEvent} event The event which triggered the listener
- */
- /**
- * @typedef {Object} ScreenSpaceEventHandler.TwoPointMotionEvent
- *
- * An Event that starts at a two positions on screen and moves to two other positions.
- *
- * @property {Cartesian2} position1
- * @property {Cartesian2} position2
- * @property {Cartesian2} previousPosition1
- * @property {Cartesian2} previousPosition2
- */
- /**
- * @callback ScreenSpaceEventHandler.TwoPointMotionEventCallback
- *
- * The callback invoked when a two-point motion event triggers an event listener.
- *
- * @param {ScreenSpaceEventHandler.TwoPointMotionEvent} event The event which triggered the listener
- */
- /**
- * @callback ScreenSpaceEventHandler.WheelEventCallback
- *
- * The callback invoked when a mouse-wheel event triggers an event listener.
- *
- * @param {number} delta The amount that the mouse wheel moved
- */
- /**
- * Handles user input events. Custom functions can be added to be executed on
- * when the user enters input.
- *
- * @alias ScreenSpaceEventHandler
- *
- * @param {HTMLCanvasElement} [element=document] The element to add events to.
- *
- * @constructor
- */
- function ScreenSpaceEventHandler(element) {
- this._inputEvents = {};
- this._buttonDown = {
- LEFT: false,
- MIDDLE: false,
- RIGHT: false,
- };
- this._isPinching = false;
- this._isTouchHolding = false;
- this._lastSeenTouchEvent = -ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds;
- this._primaryStartPosition = new Cartesian2();
- this._primaryPosition = new Cartesian2();
- this._primaryPreviousPosition = new Cartesian2();
- this._positions = new AssociativeArray();
- this._previousPositions = new AssociativeArray();
- this._removalFunctions = [];
- this._touchHoldTimer = undefined;
- // TODO: Revisit when doing mobile development. May need to be configurable
- // or determined based on the platform?
- this._clickPixelTolerance = 5;
- this._holdPixelTolerance = 25;
- this._element = defaultValue(element, document);
- registerListeners(this);
- }
- /**
- * Set a function to be executed on an input event.
- *
- * @param {ScreenSpaceEventHandler.PositionedEventCallback|ScreenSpaceEventHandler.MotionEventCallback|ScreenSpaceEventHandler.WheelEventCallback|ScreenSpaceEventHandler.TwoPointEventCallback|ScreenSpaceEventHandler.TwoPointMotionEventCallback} action Function to be executed when the input event occurs.
- * @param {ScreenSpaceEventType} type The ScreenSpaceEventType of input event.
- * @param {KeyboardEventModifier} [modifier] A KeyboardEventModifier key that is held when a <code>type</code>
- * event occurs.
- *
- * @see ScreenSpaceEventHandler#getInputAction
- * @see ScreenSpaceEventHandler#removeInputAction
- */
- ScreenSpaceEventHandler.prototype.setInputAction = function (
- action,
- type,
- modifier
- ) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(action)) {
- throw new DeveloperError("action is required.");
- }
- if (!defined(type)) {
- throw new DeveloperError("type is required.");
- }
- //>>includeEnd('debug');
- const key = getInputEventKey(type, modifier);
- this._inputEvents[key] = action;
- };
- /**
- * Returns the function to be executed on an input event.
- *
- * @param {ScreenSpaceEventType} type The ScreenSpaceEventType of input event.
- * @param {KeyboardEventModifier} [modifier] A KeyboardEventModifier key that is held when a <code>type</code>
- * event occurs.
- *
- * @returns {ScreenSpaceEventHandler.PositionedEventCallback|ScreenSpaceEventHandler.MotionEventCallback|ScreenSpaceEventHandler.WheelEventCallback|ScreenSpaceEventHandler.TwoPointEventCallback|ScreenSpaceEventHandler.TwoPointMotionEventCallback} The function to be executed on an input event.
- *
- * @see ScreenSpaceEventHandler#setInputAction
- * @see ScreenSpaceEventHandler#removeInputAction
- */
- ScreenSpaceEventHandler.prototype.getInputAction = function (type, modifier) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(type)) {
- throw new DeveloperError("type is required.");
- }
- //>>includeEnd('debug');
- const key = getInputEventKey(type, modifier);
- return this._inputEvents[key];
- };
- /**
- * Removes the function to be executed on an input event.
- *
- * @param {ScreenSpaceEventType} type The ScreenSpaceEventType of input event.
- * @param {KeyboardEventModifier} [modifier] A KeyboardEventModifier key that is held when a <code>type</code>
- * event occurs.
- *
- * @see ScreenSpaceEventHandler#getInputAction
- * @see ScreenSpaceEventHandler#setInputAction
- */
- ScreenSpaceEventHandler.prototype.removeInputAction = function (
- type,
- modifier
- ) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(type)) {
- throw new DeveloperError("type is required.");
- }
- //>>includeEnd('debug');
- const key = getInputEventKey(type, modifier);
- delete this._inputEvents[key];
- };
- /**
- * Returns true if this object was destroyed; otherwise, false.
- * <br /><br />
- * If this object was destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
- *
- * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
- *
- * @see ScreenSpaceEventHandler#destroy
- */
- ScreenSpaceEventHandler.prototype.isDestroyed = function () {
- return false;
- };
- /**
- * Removes listeners held by this object.
- * <br /><br />
- * Once an object is destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
- * assign the return value (<code>undefined</code>) to the object as done in the example.
- *
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
- *
- *
- * @example
- * handler = handler && handler.destroy();
- *
- * @see ScreenSpaceEventHandler#isDestroyed
- */
- ScreenSpaceEventHandler.prototype.destroy = function () {
- unregisterListeners(this);
- return destroyObject(this);
- };
- /**
- * The amount of time, in milliseconds, that mouse events will be disabled after
- * receiving any touch events, such that any emulated mouse events will be ignored.
- * @type {Number}
- * @default 800
- */
- ScreenSpaceEventHandler.mouseEmulationIgnoreMilliseconds = 800;
- /**
- * The amount of time, in milliseconds, before a touch on the screen becomes a
- * touch and hold.
- * @type {Number}
- * @default 1500
- */
- ScreenSpaceEventHandler.touchHoldDelayMilliseconds = 1500;
- export default ScreenSpaceEventHandler;
|