UNPKG

react-native-flip

Version:
128 lines (114 loc) 3.45 kB
import { TOUCH_ACTION_COMPUTE, TOUCH_ACTION_MAP, TOUCH_ACTION_NONE, TOUCH_ACTION_PAN_X, TOUCH_ACTION_PAN_Y } from './touchaction-Consts'; import { NATIVE_TOUCH_ACTION, PREFIXED_TOUCH_ACTION, } from "./get-touchaction-props"; import { DIRECTION_VERTICAL, DIRECTION_HORIZONTAL } from '../inputjs/input-consts'; import each from '../utils/each'; import boolOrFn from '../utils/bool-or-fn'; import inStr from '../utils/in-str'; import cleanTouchActions from './clean-touch-actions'; /** * @private * Touch Action * sets the touchAction property or uses the js alternative * @param {Manager} manager * @param {String} value * @constructor */ export default class TouchAction { constructor(manager, value) { this.manager = manager; this.set(value); } /** * @private * set the touchAction value on the element or enable the polyfill * @param {String} value */ set(value) { // find out the touch-action by the event handlers if (value === TOUCH_ACTION_COMPUTE) { value = this.compute(); } if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) { this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; } this.actions = value.toLowerCase().trim(); } /** * @private * just re-set the touchAction value */ update() { this.set(this.manager.options.touchAction); } /** * @private * compute the value for the touchAction property based on the recognizer's settings * @returns {String} value */ compute() { let actions = []; each(this.manager.recognizers, (recognizer) => { if (boolOrFn(recognizer.options.enable, [recognizer])) { actions = actions.concat(recognizer.getTouchAction()); } }); return cleanTouchActions(actions.join(' ')); } /** * @private * this method is called on each input cycle and provides the preventing of the browser behavior * @param {Object} input */ preventDefaults(input) { let { srcEvent } = input; let direction = input.offsetDirection; // if the touch action did prevented once this session if (this.manager.session.prevented) { srcEvent.preventDefault(); return; } let { actions } = this; let hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE]; let hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y]; let hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X]; if (hasNone) { // do not prevent defaults if this is a tap gesture let isTapPointer = input.pointers.length === 1; let isTapMovement = input.distance < 2; let isTapTouchTime = input.deltaTime < 250; if (isTapPointer && isTapMovement && isTapTouchTime) { return; } } if (hasPanX && hasPanY) { // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent return; } if (hasNone || (hasPanY && direction & DIRECTION_HORIZONTAL) || (hasPanX && direction & DIRECTION_VERTICAL)) { return this.preventSrc(srcEvent); } } /** * @private * call preventDefault to prevent the browser's default behavior (scrolling in most cases) * @param {Object} srcEvent */ preventSrc(srcEvent) { this.manager.session.prevented = true; srcEvent.preventDefault(); } }