gesturx 0.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +17 -1
  2. package/dist/core/index.d.ts +4 -0
  3. package/dist/core/manager.d.ts +15 -0
  4. package/dist/core/pan/PanRecognizer.d.ts +19 -0
  5. package/dist/core/pinch/PinchRecognizer.d.ts +29 -0
  6. package/dist/core/recognizer/Recognizer.d.ts +21 -0
  7. package/dist/core/recognizer/RecognizerEvent.d.ts +42 -0
  8. package/dist/core/recognizer/mapToRecognizerEvent.d.ts +8 -0
  9. package/dist/core/rotate/RotateRecognizer.d.ts +24 -0
  10. package/dist/core/swipe/SwipeRecognizer.d.ts +30 -0
  11. package/dist/core/swipe/SwipeRecognizer.test.d.ts +1 -0
  12. package/dist/core/swipe/isRecognizedAsSwipe.d.ts +4 -0
  13. package/dist/core/tap/TapRecognizer.d.ts +20 -0
  14. package/dist/core/tap/TapRecognizer.test.d.ts +1 -0
  15. package/dist/core/utils/events.d.ts +40 -0
  16. package/dist/core/utils/geometry.d.ts +17 -0
  17. package/dist/core/utils/utils.d.ts +17 -0
  18. package/dist/core/utils/utils.test.d.ts +1 -0
  19. package/dist/demo/App.d.ts +2 -0
  20. package/dist/demo/DebugBox.d.ts +5 -0
  21. package/dist/demo/useManager.d.ts +11 -0
  22. package/dist/demo/useTap.d.ts +5 -0
  23. package/dist/index.js +505 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.umd.cjs +2 -0
  26. package/dist/index.umd.cjs.map +1 -0
  27. package/dist/main.d.ts +1 -0
  28. package/dist/theme.d.ts +1 -0
  29. package/package.json +19 -3
  30. package/.github/workflows/publish.yml +0 -17
  31. package/.prettierrc.json +0 -1
  32. package/eslint.config.js +0 -9
  33. package/index.html +0 -13
  34. package/src/core/manager.ts +0 -45
  35. package/src/core/tapRecognizer.test.ts +0 -542
  36. package/src/core/tapRecognizer.ts +0 -143
  37. package/src/core/types.ts +0 -3
  38. package/src/core/utils.ts +0 -211
  39. package/src/main.ts +0 -19
  40. package/src/style.css +0 -29
  41. package/src/vite-env.d.ts +0 -1
  42. package/tsconfig.json +0 -23
  43. package/vite.config.ts +0 -33
  44. package/vitest.config.ts +0 -8
  45. /package/{public → dist}/vite.svg +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.cjs","sources":["../src/core/utils/geometry.ts","../src/core/utils/utils.ts","../src/core/recognizer/Recognizer.ts","../src/core/recognizer/mapToRecognizerEvent.ts","../src/core/utils/events.ts","../src/core/pan/PanRecognizer.ts","../src/core/swipe/isRecognizedAsSwipe.ts","../src/core/swipe/SwipeRecognizer.ts","../src/core/tap/TapRecognizer.ts","../src/core/manager.ts"],"sourcesContent":["type Point = { x: number; y: number }\n\nexport function calculateDistance(pointA: Point, pointB: Point): number {\n return Math.sqrt(\n Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2),\n )\n}\n\nexport function calculateAverageDistance(pointerEvents: Point[]): number {\n const n = pointerEvents.length\n if (n < 2) return 0 // No distance if fewer than 2 pointers\n\n const totalDistance = pointerEvents.reduce((sum, event1, i) => {\n return (\n sum +\n pointerEvents.slice(i + 1).reduce((innerSum, event2) => {\n return innerSum + calculateDistance(event1, event2)\n }, 0)\n )\n }, 0)\n\n // Number of pairs is n choose 2: n * (n - 1) / 2\n const numberOfPairs = (n * (n - 1)) / 2\n return totalDistance / numberOfPairs\n}\n\nexport function calculateRadianAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the differences in coordinates\n const deltaX = pointerB.x - pointerA.x\n const deltaY = pointerB.y - pointerA.y\n\n // Calculate the angle in radians\n const angleInRadians = Math.atan2(deltaY, deltaX)\n\n // Return the angle in degrees\n return angleInRadians\n}\n\nexport function calculateDegreeAngleBetweenPoints(\n pointerA: Point,\n pointerB: Point,\n): number {\n // Calculate the angle in radians\n const angleInRadians = calculateRadianAngleBetweenPoints(pointerA, pointerB)\n\n // Convert the angle to degrees (optional)\n const angleInDegrees = angleInRadians * (180 / Math.PI)\n\n // Return the angle in degrees\n return angleInDegrees\n}\n\nexport function calculateCentroid(points: Point[]) {\n const sum = points.reduce(\n (acc, point) => {\n acc.x += point.x\n acc.y += point.y\n\n return acc\n },\n { x: 0, y: 0 },\n )\n\n const numPoints = points.length || 1\n\n return {\n x: sum.x / numPoints,\n y: sum.y / numPoints,\n }\n}\n\nexport function calculateAngleDelta(\n initialPoints: Point[],\n newPoints: Point[],\n) {\n if (initialPoints.length !== newPoints.length) {\n throw new Error(\"Initial and new points arrays must have the same length.\")\n }\n\n const initialCentroid = calculateCentroid(initialPoints)\n const newCentroid = calculateCentroid(newPoints)\n\n let totalAngleDelta = 0\n\n for (let i = 0; i < initialPoints.length; i++) {\n const initialAngle = calculateRadianAngleBetweenPoints(\n initialCentroid,\n initialPoints[i]!,\n )\n const newAngle = calculateRadianAngleBetweenPoints(\n newCentroid,\n newPoints[i]!,\n )\n\n let angleDelta = newAngle - initialAngle\n\n // Normalize the angle delta to be within [-PI, PI]\n if (angleDelta > Math.PI) {\n angleDelta -= 2 * Math.PI\n } else if (angleDelta < -Math.PI) {\n angleDelta += 2 * Math.PI\n }\n\n totalAngleDelta += angleDelta\n }\n\n // Return the average angle delta\n const radianDelta = totalAngleDelta / initialPoints.length\n const degreesDelta = radianDelta * (180 / Math.PI)\n\n return { radianDelta, degreesDelta }\n}\n","import {\n NEVER,\n Observable,\n filter,\n merge,\n} from \"rxjs\"\nimport { calculateCentroid } from \"./geometry\"\n\nexport function isDefined<T>(\n arg: T | null | undefined,\n): arg is T extends null | undefined ? never : T {\n return arg !== null && arg !== undefined\n}\n\nexport const hasAtLeastOneItem = <T>(events: T[]): events is [T, ...T[]] =>\n events.length > 0\n\nexport const filterNotEmpty = <T>(\n stream: Observable<T[]>,\n): Observable<[T, ...T[]]> => stream.pipe(filter(hasAtLeastOneItem))\n\nexport function isOutsidePosThreshold(\n startEvent: PointerEvent,\n endEvent: PointerEvent,\n posThreshold: number,\n) {\n const start = calculateCentroid([startEvent])\n const end = calculateCentroid([endEvent])\n\n // Determines if the movement qualifies as a drag\n return (\n Math.abs(end.x - start.x) > posThreshold ||\n Math.abs(end.y - start.y) > posThreshold\n )\n}\n\nexport const fromFailWith = (failWith?: { start$: Observable<unknown> }[]) =>\n !failWith?.length\n ? NEVER\n : merge(...(failWith?.map(({ start$ }) => start$) ?? []))\n\n/**\n * Avoid division by zero\n * Calculate velocity in pixels per second\n */\nexport const calculateVelocity = (\n delay: number,\n deltaX: number,\n deltaY: number,\n) => {\n const velocityX = delay > 0 ? deltaX / delay : 0\n const velocityY = delay > 0 ? deltaY / delay : 0\n\n return {\n velocityX,\n velocityY,\n }\n}\n","import { BehaviorSubject, Observable, filter } from \"rxjs\"\n\ntype RecognizerConfig<Options> = {\n container?: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n options?: Options\n}\n\ntype ValidRecognizerConfig<Options> = Required<\n Pick<RecognizerConfig<Options>, \"container\">\n> &\n RecognizerConfig<Options>\n\nexport interface RecognizerOptions {\n failWith?: { start$: Observable<unknown> }[]\n}\n\nexport class Recognizer<Options> {\n protected config$ = new BehaviorSubject<RecognizerConfig<Options>>({})\n protected validConfig$ = this.config$.pipe(\n filter(\n (config): config is ValidRecognizerConfig<Options> => !!config.container,\n ),\n )\n\n constructor(options: Options) {\n this.update(options)\n }\n\n public initialize(config: RecognizerConfig<Options>) {\n const prevConfig = this.config$.getValue()\n\n this.config$.next({\n ...prevConfig,\n ...config,\n options: {\n ...prevConfig.options,\n ...config.options,\n } as Options,\n })\n }\n\n public update(options: Options) {\n const config = this.config$.getValue()\n\n this.config$.next({\n ...config,\n options: {\n ...config.options,\n ...options,\n },\n })\n }\n}\n","import { Observable, map, scan } from \"rxjs\"\nimport { RecognizerEvent } from \"./RecognizerEvent\"\nimport { calculateVelocity } from \"../utils/utils\"\nimport {\n calculateAngleDelta,\n calculateAverageDistance,\n calculateCentroid,\n} from \"../utils/geometry\"\n\nexport interface RecognizerEventInput {\n event: PointerEvent\n latestActivePointers: PointerEvent[]\n}\n\ninterface RecognizerEventState extends RecognizerEventInput {\n startTime: number\n center: { x: number; y: number }\n deltaX: number\n deltaY: number\n deltaPointersAngle: number\n}\n\nconst calculateNewDelta = (\n newCenter: { x: number; y: number },\n prevCenter: { x: number; y: number },\n prevDeltaX: number,\n prevDeltaY: number,\n) => {\n const deltaX = newCenter.x - prevCenter.x + prevDeltaX\n const deltaY = newCenter.y - prevCenter.y + prevDeltaY\n\n return {\n deltaX,\n deltaY,\n }\n}\n\nexport const mapToRecognizerEvent = <T extends RecognizerEventInput>(\n stream: Observable<T>,\n): Observable<RecognizerEvent> => {\n const getCenterFromData = (data: T) =>\n calculateCentroid(\n !data.latestActivePointers.length\n ? [data.event]\n : data.latestActivePointers,\n )\n\n return stream.pipe(\n scan<\n T,\n RecognizerEventState,\n Pick<\n RecognizerEventState,\n \"deltaX\" | \"center\" | \"deltaY\" | \"latestActivePointers\"\n >\n >(\n (acc, curr) => {\n const newCenter = getCenterFromData(curr)\n const prevCenter = acc.center\n const prevDeltaX = acc.deltaX\n const prevDeltaY = acc.deltaY\n const prevActivePointersNumber = acc.latestActivePointers?.length ?? 0\n const currActivePointersNumber = curr.latestActivePointers?.length ?? 0\n\n const hasAddedOrRemovedAFinger =\n [\n \"pointerdown\",\n \"pointercancel\",\n \"pointerleave\",\n \"pointerup\",\n ].includes(curr.event.type) &&\n prevActivePointersNumber !== currActivePointersNumber\n const hasAtLeastOneFinger = currActivePointersNumber > 0\n\n const { deltaX, deltaY } =\n hasAddedOrRemovedAFinger && hasAtLeastOneFinger\n ? calculateNewDelta(newCenter, newCenter, prevDeltaX, prevDeltaY)\n : calculateNewDelta(newCenter, prevCenter, prevDeltaX, prevDeltaY)\n\n const { degreesDelta: deltaPointersAngle } =\n prevActivePointersNumber === currActivePointersNumber &&\n prevActivePointersNumber >= 2 &&\n currActivePointersNumber >= 2\n ? calculateAngleDelta(\n acc.latestActivePointers ?? [],\n curr.latestActivePointers ?? [],\n )\n : { degreesDelta: 0 }\n\n return {\n startTime: new Date().getTime(),\n ...acc,\n ...curr,\n center: newCenter,\n deltaX,\n deltaY,\n deltaPointersAngle,\n }\n },\n {\n deltaX: 0,\n deltaY: 0,\n center: { x: 0, y: 0 },\n latestActivePointers: [],\n },\n ),\n map((data) => {\n const {\n deltaX,\n deltaY,\n latestActivePointers,\n startTime,\n center,\n event,\n deltaPointersAngle,\n } = data\n const events = latestActivePointers ?? []\n\n // Calculate the change in time\n const now = Date.now()\n const delay = now - startTime\n\n const { velocityX, velocityY } = calculateVelocity(delay, deltaX, deltaY)\n const pointersAverageDistance =\n calculateAverageDistance(latestActivePointers)\n\n return {\n deltaX,\n deltaY,\n velocityX,\n velocityY,\n delay,\n center,\n pointers: events,\n startTime,\n event,\n deltaPointersAngle,\n pointersAverageDistance,\n } satisfies RecognizerEvent\n }),\n )\n}\n","import {\n NEVER,\n Observable,\n defer,\n endWith,\n filter,\n fromEvent,\n map,\n merge,\n mergeMap,\n of,\n scan,\n takeUntil,\n} from \"rxjs\"\nimport { isDefined } from \"./utils\"\n\nexport function matchPointer(pointer: PointerEvent) {\n return (stream: Observable<PointerEvent>) =>\n stream.pipe(\n filter((newPointer) => newPointer.pointerId === pointer.pointerId),\n )\n}\n\nexport const getPointerEvents = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const pointerDown$ = fromPointerDown({ afterEventReceived, container })\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\").pipe(\n map(afterEventReceived),\n )\n const pointerMove$ = fromEvent<PointerEvent>(container, \"pointermove\").pipe(\n map(afterEventReceived),\n )\n /**\n * Mostly used to handle cursor leaving window on mouse pointers.\n */\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\").pipe(\n map(afterEventReceived),\n )\n /**\n * Handle things such as contextual menu popup or\n * native swipe navigation conflict.\n */\n const pointerCancel$ = fromEvent<PointerEvent>(\n container,\n \"pointercancel\",\n ).pipe(map(afterEventReceived))\n\n return {\n pointerDown$,\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n }\n}\n\nexport const fromPointerDown = ({\n container,\n afterEventReceived = (event) => event,\n}: {\n container: HTMLElement\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) =>\n fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n map(afterEventReceived),\n )\n\n/**\n * @todo test the strict stability\n * @important\n * Stable function, will not emit if the pointers don't change\n */\nexport const trackActivePointers = ({\n container,\n}: {\n container: HTMLElement\n}) => {\n const pointerUp$ = fromEvent<PointerEvent>(container, \"pointerup\")\n const pointerLeave$ = fromEvent<PointerEvent>(container, \"pointerleave\")\n const pointerCancel$ = fromEvent<PointerEvent>(container, \"pointercancel\")\n\n return fromEvent<PointerEvent>(container, \"pointerdown\").pipe(\n mergeMap((pointerDown) => {\n const pointerDownRelease$ = merge(\n pointerUp$,\n pointerLeave$,\n pointerCancel$,\n ).pipe(matchPointer(pointerDown))\n const pointerDown$ = defer(() => of(pointerDown))\n\n return pointerDown$.pipe(\n mergeMap(() => merge(pointerDown$, NEVER)),\n map((event) => ({ id: event.pointerId, event })),\n takeUntil(pointerDownRelease$),\n endWith({ id: pointerDown.pointerId, event: undefined }),\n )\n }),\n scan(\n (acc, { event, id }) => {\n if (!event) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [id]: _deleted, ...rest } = acc\n\n return rest\n }\n\n return {\n ...acc,\n [id]: event,\n }\n },\n {} as Record<number, PointerEvent | undefined>,\n ),\n map((events) => Object.values(events).filter(isDefined)),\n )\n}\n\n/**\n * Track all pointerEvent for active fingers\n */\nexport const trackFingers =\n ({\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n trackMove,\n }: {\n pointerUp$: Observable<PointerEvent>\n pointerLeave$: Observable<PointerEvent>\n pointerCancel$: Observable<PointerEvent>\n pointerMove$: Observable<PointerEvent>\n /**\n * Setting this value to false will not update the list\n * on pointer move. Use it if you only need to track number of active\n * fingers.\n */\n trackMove: boolean\n }) =>\n (stream: Observable<PointerEvent>) => {\n return stream.pipe(\n mergeMap((pointerDown) => {\n const pointerDownRelease$ = merge(\n pointerUp$,\n pointerLeave$,\n pointerCancel$,\n ).pipe(matchPointer(pointerDown))\n\n const pointerDown$ = defer(() => of(pointerDown))\n\n const tracking$ = merge(\n pointerDown$,\n trackMove ? pointerMove$ : NEVER,\n ).pipe(\n matchPointer(pointerDown),\n map((event) => ({ id: event.pointerId, event })),\n takeUntil(pointerDownRelease$),\n endWith({ id: pointerDown.pointerId, event: undefined }),\n )\n\n return tracking$\n }),\n scan(\n (acc, { event, id }) => {\n if (!event) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [id]: _deleted, ...rest } = acc\n\n return rest\n }\n\n return {\n ...acc,\n [id]: event,\n }\n },\n {} as Record<number, PointerEvent | undefined>,\n ),\n map((events) => Object.values(events).filter(isDefined)),\n )\n }\n","import {\n Observable,\n combineLatest,\n exhaustMap,\n filter,\n first,\n map,\n merge,\n mergeMap,\n of,\n share,\n shareReplay,\n skipUntil,\n switchMap,\n takeUntil,\n withLatestFrom,\n} from \"rxjs\"\nimport { isOutsidePosThreshold } from \"../utils/utils\"\nimport { Recognizer } from \"../recognizer/Recognizer\"\nimport { RecognizerEvent } from \"../recognizer/RecognizerEvent\"\nimport { mapToRecognizerEvent } from \"../recognizer/mapToRecognizerEvent\"\nimport { getPointerEvents, matchPointer, trackFingers } from \"../utils/events\"\n\nexport interface PanEvent extends RecognizerEvent {\n type: \"panStart\" | \"panMove\" | \"panEnd\"\n}\n\ntype Options = {\n posThreshold?: number\n}\n\nexport class PanRecognizer extends Recognizer<Options> {\n public events$: Observable<PanEvent>\n public start$: Observable<PanEvent>\n public end$: Observable<PanEvent>\n public fingers$: Observable<number>\n\n constructor(protected options: Options = {}) {\n super(options)\n\n this.events$ = this.validConfig$.pipe(\n switchMap((config) => {\n const { container, afterEventReceived } = config\n const { posThreshold = 15 } = config.options ?? {}\n const {\n pointerCancel$,\n pointerDown$,\n pointerLeave$,\n pointerMove$,\n pointerUp$,\n } = getPointerEvents({\n container,\n afterEventReceived,\n })\n\n return pointerDown$.pipe(\n exhaustMap((initialPointerDownEvent) => {\n const pointerDowns$ = merge(\n of(initialPointerDownEvent),\n pointerDown$,\n )\n\n const pointerUpdate$ = merge(\n pointerCancel$,\n pointerDown$,\n pointerLeave$,\n pointerMove$,\n pointerUp$,\n )\n\n const trackFingers$ = pointerDowns$.pipe(\n trackFingers({\n pointerCancel$,\n pointerLeave$,\n pointerUp$,\n pointerMove$,\n trackMove: true,\n }),\n shareReplay(),\n )\n\n /**\n * We release when we detect a pointer leave and there are no more\n * active fingers.\n *\n * @todo move to utils\n */\n const panReleased$ = merge(\n pointerUp$,\n pointerLeave$,\n pointerCancel$,\n ).pipe(\n withLatestFrom(trackFingers$),\n filter(([_, pointers]) => !pointers.length),\n map(([event]) => event),\n first(),\n share(),\n )\n\n const firstPointerDownMovingOutOfThreshold$ = pointerDowns$.pipe(\n mergeMap((pointerDown) =>\n pointerMove$.pipe(\n matchPointer(pointerDown),\n // we start pan only if the user started moving a certain distance\n filter((pointerMoveEvent) =>\n isOutsidePosThreshold(\n pointerDown,\n pointerMoveEvent,\n posThreshold,\n ),\n ),\n ),\n ),\n first(),\n )\n\n const panStart$ = firstPointerDownMovingOutOfThreshold$.pipe(\n map(() => ({\n type: \"panStart\" as const,\n event: initialPointerDownEvent,\n })),\n share(),\n takeUntil(panReleased$),\n )\n\n const panEnd$ = panStart$.pipe(\n mergeMap(() =>\n panReleased$.pipe(\n map((endEvent) => ({\n type: \"panEnd\" as const,\n event: endEvent,\n })),\n ),\n ),\n )\n\n const panUpdate$ = pointerUpdate$.pipe(\n skipUntil(panStart$),\n map((event) => ({\n type: \"panMove\" as const,\n event,\n })),\n takeUntil(panReleased$),\n )\n\n const rawEvent$ = merge(panStart$, panUpdate$, panEnd$).pipe(\n withLatestFrom(trackFingers$),\n map(([event, pointers]) => ({\n ...event,\n latestActivePointers: pointers,\n })),\n share(),\n )\n\n return combineLatest([\n rawEvent$.pipe(mapToRecognizerEvent),\n rawEvent$,\n ]).pipe(\n map(([recognizerEvent, { type }]) => ({\n ...recognizerEvent,\n type,\n })),\n )\n }),\n )\n }),\n share(),\n )\n\n this.start$ = this.events$.pipe(\n filter((event) => event.type === \"panStart\"),\n )\n this.end$ = this.events$.pipe(filter((event) => event.type === \"panEnd\"))\n\n this.fingers$ = this.validConfig$.pipe(\n switchMap(({ container, afterEventReceived }) => {\n const pointerEvents = getPointerEvents({\n container,\n afterEventReceived,\n })\n\n return pointerEvents.pointerDown$.pipe(\n trackFingers({\n ...pointerEvents,\n trackMove: false,\n }),\n )\n }),\n map((events) => events.length),\n )\n }\n}\n","import { Observable, filter } from \"rxjs\"\nimport { PanEvent } from \"../pan/PanRecognizer\"\n\nexport const isRecognizedAsSwipe =\n (escapeVelocity: number) => (stream: Observable<PanEvent>) =>\n stream.pipe(\n filter((event) => {\n return (\n Math.abs(event.velocityX) >= escapeVelocity ||\n Math.abs(event.velocityY) >= escapeVelocity\n )\n }),\n )\n","import {\n Observable,\n exhaustMap,\n filter,\n first,\n map,\n share,\n switchMap,\n takeUntil,\n} from \"rxjs\"\nimport { Recognizer } from \"../recognizer/Recognizer\"\nimport { PanRecognizer } from \"../pan/PanRecognizer\"\nimport { RecognizerEvent } from \"../recognizer/RecognizerEvent\"\nimport { calculateDegreeAngleBetweenPoints } from \"../utils/geometry\"\nimport { isRecognizedAsSwipe } from \"./isRecognizedAsSwipe\"\n\nexport interface SwipeEvent extends RecognizerEvent {\n type: \"swipe\"\n /**\n * Angle between first pointer and last one in degree\n *\n * (-90)\n * (+/-180) <- | -> (+/-0)\n * (+90)\n */\n angle: number\n}\n\ntype Options = {\n /**\n * The minimum velocity (px/ms) that the gesture has to obtain by the end event.\n */\n escapeVelocity?: number\n // @todo\n numInputs?: number\n // @todo\n maxRestTime?: number\n posThreshold?: number\n}\n\nexport class SwipeRecognizer extends Recognizer<Options> {\n public events$: Observable<SwipeEvent>\n\n constructor(protected options: Options = {}) {\n super(options)\n\n this.events$ = this.validConfig$.pipe(\n switchMap((initializedWith) => {\n const { escapeVelocity = 0.9, posThreshold } =\n initializedWith.options ?? {}\n const panRecognizer = new PanRecognizer({ posThreshold })\n\n panRecognizer.initialize(initializedWith)\n\n const hasMoreThanOneFinger$ = panRecognizer.events$.pipe(\n filter(({ pointers }) => pointers.length > 1),\n )\n\n return panRecognizer.start$.pipe(\n exhaustMap((startEvent) => {\n return panRecognizer.end$.pipe(\n first(),\n isRecognizedAsSwipe(escapeVelocity),\n map(({ type, ...rest }) => {\n return {\n type: \"swipe\" as const,\n angle: calculateDegreeAngleBetweenPoints(\n startEvent.event,\n rest.event,\n ),\n ...rest,\n }\n }),\n takeUntil(hasMoreThanOneFinger$),\n )\n }),\n share(),\n )\n }),\n )\n }\n}\n","import {\n Observable,\n buffer,\n combineLatest,\n debounceTime,\n exhaustMap,\n filter,\n first,\n ignoreElements,\n map,\n merge,\n of,\n share,\n shareReplay,\n switchMap,\n takeUntil,\n timer,\n withLatestFrom,\n} from \"rxjs\"\nimport {\n fromFailWith,\n filterNotEmpty,\n isOutsidePosThreshold,\n} from \"../utils/utils\"\nimport { Recognizer, RecognizerOptions } from \"../recognizer/Recognizer\"\nimport { RecognizerEvent } from \"../recognizer/RecognizerEvent\"\nimport { mapToRecognizerEvent } from \"../recognizer/mapToRecognizerEvent\"\nimport {\n fromPointerDown,\n getPointerEvents,\n trackFingers,\n} from \"../utils/events\"\n\nexport interface TapEvent extends RecognizerEvent {\n type: \"tap\"\n taps: number\n}\n\ninterface Options extends RecognizerOptions {\n // Maximum time in ms between multiple taps.\n multiTapThreshold?: number\n // Maximum press time in ms.\n maximumPressTime?: number\n maxTaps?: number\n posThreshold?: number\n}\n\nexport class TapRecognizer extends Recognizer<Options> {\n public events$: Observable<TapEvent>\n\n constructor(protected options: Options) {\n super(options)\n\n this.events$ = this.validConfig$.pipe(\n switchMap((config) => {\n const { container, afterEventReceived } = config\n const {\n multiTapThreshold = 200,\n maximumPressTime = 250,\n maxTaps = 2,\n // threshold should be high because of fingers size\n // and potential margin due to it. clicks are nearly perfect\n // not fingers.\n posThreshold = 10,\n failWith,\n } = config.options ?? {}\n\n const { pointerUp$, pointerLeave$, pointerCancel$, pointerMove$ } =\n getPointerEvents({\n container,\n afterEventReceived,\n })\n\n const pointerDown$ = fromPointerDown({ container, afterEventReceived })\n const activePointers$ = pointerDown$.pipe(\n trackFingers({\n pointerCancel$,\n pointerLeave$,\n pointerMove$,\n pointerUp$,\n trackMove: false,\n }),\n shareReplay(1),\n )\n\n const hasMoreThanOneActivePointer$ = activePointers$.pipe(\n filter((pointers) => pointers.length > 1),\n )\n\n const onlyOnePointer = <T>(stream: Observable<T>) =>\n stream.pipe(\n withLatestFrom(activePointers$),\n filter(([, pointers]) => pointers.length === 1),\n map(([pointer]) => pointer),\n )\n\n const bufferPointerDowns = (stream: Observable<PointerEvent>) =>\n stream.pipe(\n buffer(pointerUp$.pipe(debounceTime(multiTapThreshold))),\n first(),\n )\n\n const failWith$ = fromFailWith(failWith)\n\n const tap$ = merge(\n pointerDown$,\n activePointers$.pipe(ignoreElements()),\n ).pipe(\n onlyOnePointer,\n exhaustMap((initialPointerEvent) => {\n const pointerDowns$ = merge(of(initialPointerEvent), pointerDown$)\n const subsequentPointerEvents$ = merge(\n pointerUp$,\n pointerLeave$,\n pointerCancel$,\n pointerMove$,\n )\n const pointerDownsBuffered$ = pointerDowns$.pipe(bufferPointerDowns)\n const subsequentPointersOutOfPositionThreshold$ =\n subsequentPointerEvents$.pipe(\n filter((event) =>\n isOutsidePosThreshold(\n initialPointerEvent,\n event,\n posThreshold,\n ),\n ),\n first(),\n )\n const waitedTooLong$ = activePointers$.pipe(\n switchMap(() => timer(maximumPressTime)),\n )\n\n const takeUntil$ = merge(\n failWith$,\n pointerCancel$,\n hasMoreThanOneActivePointer$,\n subsequentPointersOutOfPositionThreshold$,\n waitedTooLong$,\n )\n\n const rawEvent$ = pointerDownsBuffered$.pipe(\n filterNotEmpty,\n filter((events) => events.length <= maxTaps),\n map((events) => ({\n type: \"tap\" as const,\n taps: events.length,\n latestActivePointers: events,\n event: events[0],\n })),\n )\n\n return combineLatest([\n rawEvent$.pipe(mapToRecognizerEvent),\n rawEvent$,\n ]).pipe(\n map(([recognizerEvent, { type, taps }]) => ({\n ...recognizerEvent,\n type,\n taps,\n })),\n takeUntil(takeUntil$),\n )\n }),\n )\n\n return tap$\n }),\n share(),\n )\n }\n}\n","import { merge, share } from \"rxjs\"\nimport { TapRecognizer } from \"./tap/TapRecognizer\"\nimport { PanRecognizer } from \"./pan/PanRecognizer\"\nimport { SwipeRecognizer } from \"./swipe/SwipeRecognizer\"\nimport { RotateRecognizer } from \"./rotate/RotateRecognizer\"\nimport { PinchRecognizer } from \"./pinch/PinchRecognizer\"\n\nexport type Manager = ReturnType<typeof createManager>\n\nexport const createManager = ({\n afterEventReceived = (event) => event,\n recognizers,\n}: {\n recognizers: (\n | TapRecognizer\n | PanRecognizer\n | SwipeRecognizer\n | RotateRecognizer\n | PinchRecognizer\n )[]\n afterEventReceived?: (event: PointerEvent) => PointerEvent\n}) => {\n const events$ = merge(\n ...recognizers.map((recognizer) => recognizer.events$),\n ).pipe(share())\n\n const initialize = (container: HTMLElement) => {\n /**\n * We have to disable touch-action otherwise every events will be followed\n * by a cancel event since the browser will try to handle touch.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action\n */\n container.style.touchAction = `none`\n\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n */\n container.style.userSelect = `none`\n\n recognizers.forEach((recognizer) => {\n recognizer.initialize({ container, afterEventReceived })\n })\n }\n\n return { events$, initialize, recognizers }\n}\n"],"names":["calculateDistance","pointA","pointB","calculateAverageDistance","pointerEvents","n","totalDistance","sum","event1","i","innerSum","event2","numberOfPairs","calculateRadianAngleBetweenPoints","pointerA","pointerB","deltaX","deltaY","calculateDegreeAngleBetweenPoints","calculateCentroid","points","acc","point","numPoints","calculateAngleDelta","initialPoints","newPoints","initialCentroid","newCentroid","totalAngleDelta","initialAngle","angleDelta","radianDelta","degreesDelta","isDefined","arg","hasAtLeastOneItem","events","filterNotEmpty","stream","filter","isOutsidePosThreshold","startEvent","endEvent","posThreshold","start","end","fromFailWith","failWith","merge","start$","NEVER","calculateVelocity","delay","velocityX","velocityY","Recognizer","options","__publicField","BehaviorSubject","config","prevConfig","calculateNewDelta","newCenter","prevCenter","prevDeltaX","prevDeltaY","mapToRecognizerEvent","getCenterFromData","data","scan","curr","prevActivePointersNumber","_a","currActivePointersNumber","_b","hasAddedOrRemovedAFinger","hasAtLeastOneFinger","deltaPointersAngle","map","latestActivePointers","startTime","center","event","pointersAverageDistance","matchPointer","pointer","newPointer","getPointerEvents","container","afterEventReceived","pointerDown$","fromPointerDown","pointerUp$","fromEvent","pointerMove$","pointerLeave$","pointerCancel$","trackFingers","trackMove","mergeMap","pointerDown","pointerDownRelease$","defer","of","takeUntil","endWith","id","_deleted","rest","PanRecognizer","switchMap","exhaustMap","initialPointerDownEvent","pointerDowns$","pointerUpdate$","trackFingers$","shareReplay","panReleased$","withLatestFrom","_","pointers","first","share","panStart$","pointerMoveEvent","panEnd$","panUpdate$","skipUntil","rawEvent$","combineLatest","recognizerEvent","type","isRecognizedAsSwipe","escapeVelocity","SwipeRecognizer","initializedWith","panRecognizer","hasMoreThanOneFinger$","TapRecognizer","multiTapThreshold","maximumPressTime","maxTaps","activePointers$","hasMoreThanOneActivePointer$","onlyOnePointer","bufferPointerDowns","buffer","debounceTime","failWith$","ignoreElements","initialPointerEvent","subsequentPointerEvents$","pointerDownsBuffered$","subsequentPointersOutOfPositionThreshold$","waitedTooLong$","timer","takeUntil$","taps","createManager","recognizers","recognizer"],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ export declare const theme: Record<string, any>;
package/package.json CHANGED
@@ -1,24 +1,40 @@
1
1
  {
2
2
  "name": "gesturx",
3
3
  "private": false,
4
- "version": "0.0.0",
4
+ "version": "1.1.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "build": "tsc && vite build",
9
+ "build:lib": "tsc && cross-env LIB_MODE=true vite build",
9
10
  "preview": "vite preview",
10
- "lint": "prettier --write . && eslint --fix .",
11
+ "lint": "prettier --write . && eslint --fix . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
11
12
  "test": "vitest",
12
13
  "coverage": "vitest run --coverage"
13
14
  },
15
+ "files": [
16
+ "dist"
17
+ ],
14
18
  "devDependencies": {
19
+ "@chakra-ui/icons": "^2.1.1",
20
+ "@chakra-ui/react": "^2.8.2",
21
+ "@emotion/react": "^11.11.4",
22
+ "@emotion/styled": "^11.11.5",
15
23
  "@eslint/js": "^9.0.0",
16
24
  "@types/node": "^20.12.7",
25
+ "@types/react": "^18.3.2",
26
+ "@types/react-dom": "^18.3.0",
27
+ "@vitejs/plugin-react": "^4.3.0",
17
28
  "@vitest/coverage-v8": "^1.5.0",
29
+ "cross-env": "^7.0.3",
18
30
  "eslint": "^8.57.0",
31
+ "framer-motion": "^11.2.6",
19
32
  "happy-dom": "^14.7.1",
20
33
  "prettier": "3.2.5",
34
+ "react": "^18.3.1",
35
+ "react-dom": "^18.3.1",
21
36
  "rollup-plugin-node-externals": "^7.1.1",
37
+ "rxjs": "^7.8.1",
22
38
  "typescript": "^5.4.5",
23
39
  "typescript-eslint": "^7.7.0",
24
40
  "vite": "^5.2.0",
@@ -26,7 +42,7 @@
26
42
  "vite-plugin-eslint": "^1.8.1",
27
43
  "vitest": "^1.5.0"
28
44
  },
29
- "dependencies": {
45
+ "peerDependencies": {
30
46
  "rxjs": "^7.8.1"
31
47
  }
32
48
  }
@@ -1,17 +0,0 @@
1
- on:
2
- push:
3
- branches: main
4
-
5
- jobs:
6
- publish:
7
- runs-on: ubuntu-latest
8
- steps:
9
- - uses: actions/checkout@v4
10
- - uses: actions/setup-node@v3
11
- with:
12
- node-version: "20"
13
- - run: npm ci
14
- - run: npm test
15
- - uses: JS-DevTools/npm-publish@v3
16
- with:
17
- token: ${{ secrets.NPM_TOKEN }}
package/.prettierrc.json DELETED
@@ -1 +0,0 @@
1
- {}
package/eslint.config.js DELETED
@@ -1,9 +0,0 @@
1
- // @ts-check
2
-
3
- import eslint from "@eslint/js";
4
- import tseslint from "typescript-eslint";
5
-
6
- export default tseslint.config(
7
- eslint.configs.recommended,
8
- ...tseslint.configs.recommended,
9
- );
package/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>gesturx</title>
8
- </head>
9
- <body>
10
- <div id="app"></div>
11
- <script type="module" src="/src/main.ts"></script>
12
- </body>
13
- </html>
@@ -1,45 +0,0 @@
1
- import { map, merge } from "rxjs";
2
- import { createTapRecognizer } from "./tapRecognizer";
3
- import { getCenterFromEvent } from "./utils";
4
-
5
- export const createManager = ({
6
- container,
7
- afterEventReceived = (event) => event,
8
- recognizers,
9
- }: {
10
- container: HTMLElement;
11
- recognizers: ReturnType<typeof createTapRecognizer>[];
12
- afterEventReceived?: (event: PointerEvent) => PointerEvent;
13
- }) => {
14
- // user api
15
- // const dragRecognizer = createPanRecognizer();
16
- // const singleTapRecognizer = createTapRecognizer({
17
- // maxTaps: 2,
18
- // failWith: [dragRecognizer],
19
- // });
20
- // const pinchRecognizer = createPinchRecognizer();
21
-
22
- // internal api
23
- // dragRecognizer.initialize({ container, afterEventReceived });
24
-
25
- // const recognizers = [
26
- // singleTapRecognizer({ container, afterEventReceived }),
27
- // // pinchRecognizer({ container, afterEventReceived }),
28
- // // dragRecognizer,
29
- // ]
30
-
31
- const recognizerInstances = recognizers.map((recognizer) =>
32
- recognizer({ container, afterEventReceived }),
33
- );
34
-
35
- const events$ = merge(
36
- ...recognizerInstances.map((recognizer) => recognizer.events$),
37
- ).pipe(
38
- map((event) => ({
39
- ...event,
40
- center: getCenterFromEvent(event.srcEvent),
41
- })),
42
- );
43
-
44
- return { events$ };
45
- };