UNPKG

@baleada/listenable-gestures

Version:

A collection of gesture recognizers that are compatible with Baleada Logic's Listenable class.

173 lines (154 loc) 4.77 kB
import { emit, toEmitted, naiveDeepClone, getGetPoint, isDefined } from '../util'; /* * clicks is defined as a single mouse that: * - starts at a given point * - does not move beyond a maximum distance * - does not cancel * - ends * - repeats 2 times (or a minimum number of your choice), with each click ending less than or equal to 500ms (or a maximum interval of your choice) after the previous click ended */ var defaultOptions = { minClicks: 1, maxInterval: 500, // Via https://ux.stackexchange.com/questions/40364/what-is-the-expected-timeframe-of-a-double-click maxDistance: 5 // TODO: research standard maxDistance }; export default function clicks() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var onDown = options.onDown, onMove = options.onMove, onLeave = options.onLeave, onUp = options.onUp, minClicks = isDefined(options.minClicks) ? options.minClicks : defaultOptions.minClicks, maxInterval = isDefined(options.maxInterval) ? options.maxInterval : defaultOptions.maxInterval, maxDistance = isDefined(options.maxDistance) ? options.maxDistance : defaultOptions.maxDistance; function mousedown(handlerApi) { var event = handlerApi.event, setMetadata = handlerApi.setMetadata; setMetadata({ path: 'mouseStatus', value: 'down' }); setMetadata({ path: 'lastClick.times.start', value: event.timeStamp }); var getPoint = getGetPoint('mouse'); setMetadata({ path: 'lastClick.points.start', value: getPoint(event) }); emit(onDown, toEmitted(handlerApi)); } function mousemove(handlerApi) { var getMetadata = handlerApi.getMetadata, denied = handlerApi.denied; if (getMetadata().mouseStatus !== 'down') { denied(); } emit(onMove, toEmitted(handlerApi)); } function mouseleave(handlerApi) { var getMetadata = handlerApi.getMetadata, denied = handlerApi.denied; if (getMetadata().mouseStatus === 'down') { denied(); setMetadata({ path: 'mouseStatus', value: 'leave' }); } emit(onLeave, toEmitted(handlerApi)); } function mouseup(handlerApi) { var event = handlerApi.event, getMetadata = handlerApi.getMetadata, toPolarCoordinates = handlerApi.toPolarCoordinates, setMetadata = handlerApi.setMetadata, pushMetadata = handlerApi.pushMetadata; setMetadata({ path: 'mouseStatus', value: 'up' }); var _getMetadata$lastClic = getMetadata().lastClick.points.start, xA = _getMetadata$lastClic.x, yA = _getMetadata$lastClic.y, xB = event.clientX, yB = event.clientY, _toPolarCoordinates = toPolarCoordinates({ xA: xA, xB: xB, yA: yA, yB: yB }), distance = _toPolarCoordinates.distance, endPoint = { x: xB, y: yB }, endTime = event.timeStamp; setMetadata({ path: 'lastClick.points.end', value: endPoint }); setMetadata({ path: 'lastClick.times.end', value: endTime }); setMetadata({ path: 'lastClick.distance', value: distance }); if (!Array.isArray(getMetadata().clicks)) { setMetadata({ path: 'clicks', value: [] }); } var interval = getMetadata().clicks.length === 0 ? 0 : endTime - getMetadata().clicks[getMetadata().clicks.length - 1].times.end; setMetadata({ path: 'lastClick.interval', value: interval }); var newClick = naiveDeepClone(getMetadata().lastClick); pushMetadata({ path: 'clicks', value: newClick }); recognize(handlerApi); emit(onUp, toEmitted(handlerApi)); } function recognize(_ref) { var getMetadata = _ref.getMetadata, denied = _ref.denied, setMetadata = _ref.setMetadata, pushMetadata = _ref.pushMetadata, recognized = _ref.recognized; switch (true) { case getMetadata().lastClick.interval > maxInterval || getMetadata().lastClick.distance > maxDistance: // Deny after multiple touches and after clicks with intervals or movement distances that are too large var lastClick = naiveDeepClone(getMetadata().lastClick); denied(); setMetadata({ path: 'clicks', value: [] }); pushMetadata({ path: 'clicks', value: lastClick }); break; default: if (getMetadata().clicks.length >= minClicks) { recognized(); } break; } } return { mousedown: mousedown, mousemove: mousemove, mouseleave: mouseleave, mouseup: mouseup }; }