UNPKG

react-native-gesture-handler

Version:

Experimental implementation of a new declarative API for gesture handling in react-native

149 lines (128 loc) 5.75 kB
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import { EventTypes, TouchEventType } from '../interfaces'; import EventManager from './EventManager'; import { calculateViewScale, isPointerInBounds } from '../utils'; import { PointerType } from '../../PointerType'; export default class TouchEventManager extends EventManager { constructor(...args) { super(...args); _defineProperty(this, "touchStartCallback", event => { for (let i = 0; i < event.changedTouches.length; ++i) { const adaptedEvent = this.mapEvent(event, EventTypes.DOWN, i, TouchEventType.DOWN); // Here we skip stylus, because in case of anything different than touch we want to handle it by using PointerEvents // If we leave stylus to send touch events, handlers will receive every action twice if (!isPointerInBounds(this.view, { x: adaptedEvent.x, y: adaptedEvent.y }) || // @ts-ignore touchType field does exist event.changedTouches[i].touchType === 'stylus') { continue; } this.markAsInBounds(adaptedEvent.pointerId); if (++this.activePointersCounter > 1) { adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_DOWN; this.onPointerAdd(adaptedEvent); } else { this.onPointerDown(adaptedEvent); } } }); _defineProperty(this, "touchMoveCallback", event => { for (let i = 0; i < event.changedTouches.length; ++i) { const adaptedEvent = this.mapEvent(event, EventTypes.MOVE, i, TouchEventType.MOVE); // @ts-ignore touchType field does exist if (event.changedTouches[i].touchType === 'stylus') { continue; } const inBounds = isPointerInBounds(this.view, { x: adaptedEvent.x, y: adaptedEvent.y }); const pointerIndex = this.pointersInBounds.indexOf(adaptedEvent.pointerId); if (inBounds) { if (pointerIndex < 0) { adaptedEvent.eventType = EventTypes.ENTER; this.onPointerEnter(adaptedEvent); this.markAsInBounds(adaptedEvent.pointerId); } else { this.onPointerMove(adaptedEvent); } } else { if (pointerIndex >= 0) { adaptedEvent.eventType = EventTypes.LEAVE; this.onPointerLeave(adaptedEvent); this.markAsOutOfBounds(adaptedEvent.pointerId); } else { this.onPointerOutOfBounds(adaptedEvent); } } } }); _defineProperty(this, "touchEndCallback", event => { for (let i = 0; i < event.changedTouches.length; ++i) { // When we call reset on gesture handlers, it also resets their event managers // In some handlers (like RotationGestureHandler) reset is called before all pointers leave view // This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view // Removing them will end in activePointersCounter going below 0, therefore handlers won't behave properly if (this.activePointersCounter === 0) { break; } // @ts-ignore touchType field does exist if (event.changedTouches[i].touchType === 'stylus') { continue; } const adaptedEvent = this.mapEvent(event, EventTypes.UP, i, TouchEventType.UP); this.markAsOutOfBounds(adaptedEvent.pointerId); if (--this.activePointersCounter > 0) { adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_UP; this.onPointerRemove(adaptedEvent); } else { this.onPointerUp(adaptedEvent); } } }); _defineProperty(this, "touchCancelCallback", event => { for (let i = 0; i < event.changedTouches.length; ++i) { const adaptedEvent = this.mapEvent(event, EventTypes.CANCEL, i, TouchEventType.CANCELLED); // @ts-ignore touchType field does exist if (event.changedTouches[i].touchType === 'stylus') { continue; } this.onPointerCancel(adaptedEvent); this.markAsOutOfBounds(adaptedEvent.pointerId); this.activePointersCounter = 0; } }); } registerListeners() { this.view.addEventListener('touchstart', this.touchStartCallback); this.view.addEventListener('touchmove', this.touchMoveCallback); this.view.addEventListener('touchend', this.touchEndCallback); this.view.addEventListener('touchcancel', this.touchCancelCallback); } unregisterListeners() { this.view.removeEventListener('touchstart', this.touchStartCallback); this.view.removeEventListener('touchmove', this.touchMoveCallback); this.view.removeEventListener('touchend', this.touchEndCallback); this.view.removeEventListener('touchcancel', this.touchCancelCallback); } mapEvent(event, eventType, index, touchEventType) { const rect = this.view.getBoundingClientRect(); const clientX = event.changedTouches[index].clientX; const clientY = event.changedTouches[index].clientY; const { scaleX, scaleY } = calculateViewScale(this.view); return { x: clientX, y: clientY, offsetX: (clientX - rect.left) / scaleX, offsetY: (clientY - rect.top) / scaleY, pointerId: event.changedTouches[index].identifier, eventType: eventType, pointerType: PointerType.TOUCH, time: event.timeStamp, allTouches: event.touches, changedTouches: event.changedTouches, touchEventType: touchEventType }; } } //# sourceMappingURL=TouchEventManager.js.map