react-native-gesture-handler 2.1.0 → 2.1.1

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 (47) hide show
  1. package/lib/commonjs/handlers/gestures/GestureDetector.js +15 -1
  2. package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
  3. package/lib/commonjs/handlers/gestures/eventReceiver.js +11 -0
  4. package/lib/commonjs/handlers/gestures/eventReceiver.js.map +1 -1
  5. package/lib/commonjs/handlers/gestures/forceTouchGesture.js +26 -0
  6. package/lib/commonjs/handlers/gestures/forceTouchGesture.js.map +1 -1
  7. package/lib/commonjs/handlers/gestures/gesture.js +15 -7
  8. package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
  9. package/lib/commonjs/handlers/gestures/manualGesture.js +12 -0
  10. package/lib/commonjs/handlers/gestures/manualGesture.js.map +1 -1
  11. package/lib/commonjs/handlers/gestures/panGesture.js +28 -0
  12. package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -1
  13. package/lib/commonjs/handlers/gestures/pinchGesture.js +26 -0
  14. package/lib/commonjs/handlers/gestures/pinchGesture.js.map +1 -1
  15. package/lib/commonjs/handlers/gestures/rotationGesture.js +26 -0
  16. package/lib/commonjs/handlers/gestures/rotationGesture.js.map +1 -1
  17. package/lib/module/handlers/gestures/GestureDetector.js +14 -1
  18. package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
  19. package/lib/module/handlers/gestures/eventReceiver.js +11 -0
  20. package/lib/module/handlers/gestures/eventReceiver.js.map +1 -1
  21. package/lib/module/handlers/gestures/forceTouchGesture.js +27 -0
  22. package/lib/module/handlers/gestures/forceTouchGesture.js.map +1 -1
  23. package/lib/module/handlers/gestures/gesture.js +15 -7
  24. package/lib/module/handlers/gestures/gesture.js.map +1 -1
  25. package/lib/module/handlers/gestures/manualGesture.js +13 -0
  26. package/lib/module/handlers/gestures/manualGesture.js.map +1 -1
  27. package/lib/module/handlers/gestures/panGesture.js +29 -0
  28. package/lib/module/handlers/gestures/panGesture.js.map +1 -1
  29. package/lib/module/handlers/gestures/pinchGesture.js +27 -0
  30. package/lib/module/handlers/gestures/pinchGesture.js.map +1 -1
  31. package/lib/module/handlers/gestures/rotationGesture.js +27 -0
  32. package/lib/module/handlers/gestures/rotationGesture.js.map +1 -1
  33. package/lib/typescript/handlers/gestures/forceTouchGesture.d.ts +7 -1
  34. package/lib/typescript/handlers/gestures/gesture.d.ts +12 -8
  35. package/lib/typescript/handlers/gestures/manualGesture.d.ts +3 -1
  36. package/lib/typescript/handlers/gestures/panGesture.d.ts +8 -1
  37. package/lib/typescript/handlers/gestures/pinchGesture.d.ts +7 -1
  38. package/lib/typescript/handlers/gestures/rotationGesture.d.ts +7 -1
  39. package/package.json +1 -1
  40. package/src/handlers/gestures/GestureDetector.tsx +21 -0
  41. package/src/handlers/gestures/eventReceiver.ts +16 -0
  42. package/src/handlers/gestures/forceTouchGesture.ts +43 -1
  43. package/src/handlers/gestures/gesture.ts +26 -13
  44. package/src/handlers/gestures/manualGesture.ts +21 -1
  45. package/src/handlers/gestures/panGesture.ts +43 -1
  46. package/src/handlers/gestures/pinchGesture.ts +40 -1
  47. package/src/handlers/gestures/rotationGesture.ts +40 -1
@@ -1,9 +1,36 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
+
3
+ function changeEventCalculator(current, previous) {
4
+ 'worklet';
5
+
6
+ let changePayload;
7
+
8
+ if (previous === undefined) {
9
+ changePayload = {
10
+ scaleChange: current.scale
11
+ };
12
+ } else {
13
+ changePayload = {
14
+ scaleChange: current.scale / previous.scale
15
+ };
16
+ }
17
+
18
+ return { ...current,
19
+ ...changePayload
20
+ };
21
+ }
22
+
2
23
  export class PinchGesture extends ContinousBaseGesture {
3
24
  constructor() {
4
25
  super();
5
26
  this.handlerName = 'PinchGestureHandler';
6
27
  }
7
28
 
29
+ onChange(callback) {
30
+ // @ts-ignore TS being overprotective, PinchGestureHandlerEventPayload is Record
31
+ this.handlers.changeEventCalculator = changeEventCalculator;
32
+ return super.onChange(callback);
33
+ }
34
+
8
35
  }
9
36
  //# sourceMappingURL=pinchGesture.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["pinchGesture.ts"],"names":["ContinousBaseGesture","PinchGesture","constructor","handlerName"],"mappings":"AAAA,SAASA,oBAAT,QAAqC,WAArC;AAGA,OAAO,MAAMC,YAAN,SAA2BD,oBAA3B,CAAiF;AACtFE,EAAAA,WAAW,GAAG;AACZ;AAEA,SAAKC,WAAL,GAAmB,qBAAnB;AACD;;AALqF","sourcesContent":["import { ContinousBaseGesture } from './gesture';\nimport { PinchGestureHandlerEventPayload } from '../PinchGestureHandler';\n\nexport class PinchGesture extends ContinousBaseGesture<PinchGestureHandlerEventPayload> {\n constructor() {\n super();\n\n this.handlerName = 'PinchGestureHandler';\n }\n}\n\nexport type PinchGestureType = InstanceType<typeof PinchGesture>;\n"]}
1
+ {"version":3,"sources":["pinchGesture.ts"],"names":["ContinousBaseGesture","changeEventCalculator","current","previous","changePayload","undefined","scaleChange","scale","PinchGesture","constructor","handlerName","onChange","callback","handlers"],"mappings":"AAAA,SAASA,oBAAT,QAAqC,WAArC;;AAQA,SAASC,qBAAT,CACEC,OADF,EAEEC,QAFF,EAGE;AACA;;AACA,MAAIC,aAAJ;;AACA,MAAID,QAAQ,KAAKE,SAAjB,EAA4B;AAC1BD,IAAAA,aAAa,GAAG;AACdE,MAAAA,WAAW,EAAEJ,OAAO,CAACK;AADP,KAAhB;AAGD,GAJD,MAIO;AACLH,IAAAA,aAAa,GAAG;AACdE,MAAAA,WAAW,EAAEJ,OAAO,CAACK,KAAR,GAAgBJ,QAAQ,CAACI;AADxB,KAAhB;AAGD;;AAED,SAAO,EAAE,GAAGL,OAAL;AAAc,OAAGE;AAAjB,GAAP;AACD;;AAED,OAAO,MAAMI,YAAN,SAA2BR,oBAA3B,CAGL;AACAS,EAAAA,WAAW,GAAG;AACZ;AAEA,SAAKC,WAAL,GAAmB,qBAAnB;AACD;;AAEDC,EAAAA,QAAQ,CACNC,QADM,EAMN;AACA;AACA,SAAKC,QAAL,CAAcZ,qBAAd,GAAsCA,qBAAtC;AACA,WAAO,MAAMU,QAAN,CAAeC,QAAf,CAAP;AACD;;AAjBD","sourcesContent":["import { ContinousBaseGesture } from './gesture';\nimport { PinchGestureHandlerEventPayload } from '../PinchGestureHandler';\nimport { GestureUpdateEvent } from '../gestureHandlerCommon';\n\ntype PinchGestureChangeEventPayload = {\n scaleChange: number;\n};\n\nfunction changeEventCalculator(\n current: GestureUpdateEvent<PinchGestureHandlerEventPayload>,\n previous?: GestureUpdateEvent<PinchGestureHandlerEventPayload>\n) {\n 'worklet';\n let changePayload: PinchGestureChangeEventPayload;\n if (previous === undefined) {\n changePayload = {\n scaleChange: current.scale,\n };\n } else {\n changePayload = {\n scaleChange: current.scale / previous.scale,\n };\n }\n\n return { ...current, ...changePayload };\n}\n\nexport class PinchGesture extends ContinousBaseGesture<\n PinchGestureHandlerEventPayload,\n PinchGestureChangeEventPayload\n> {\n constructor() {\n super();\n\n this.handlerName = 'PinchGestureHandler';\n }\n\n onChange(\n callback: (\n event: GestureUpdateEvent<\n PinchGestureHandlerEventPayload & PinchGestureChangeEventPayload\n >\n ) => void\n ) {\n // @ts-ignore TS being overprotective, PinchGestureHandlerEventPayload is Record\n this.handlers.changeEventCalculator = changeEventCalculator;\n return super.onChange(callback);\n }\n}\n\nexport type PinchGestureType = InstanceType<typeof PinchGesture>;\n"]}
@@ -1,9 +1,36 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
+
3
+ function changeEventCalculator(current, previous) {
4
+ 'worklet';
5
+
6
+ let changePayload;
7
+
8
+ if (previous === undefined) {
9
+ changePayload = {
10
+ rotationChange: current.rotation
11
+ };
12
+ } else {
13
+ changePayload = {
14
+ rotationChange: current.rotation - previous.rotation
15
+ };
16
+ }
17
+
18
+ return { ...current,
19
+ ...changePayload
20
+ };
21
+ }
22
+
2
23
  export class RotationGesture extends ContinousBaseGesture {
3
24
  constructor() {
4
25
  super();
5
26
  this.handlerName = 'RotationGestureHandler';
6
27
  }
7
28
 
29
+ onChange(callback) {
30
+ // @ts-ignore TS being overprotective, RotationGestureHandlerEventPayload is Record
31
+ this.handlers.changeEventCalculator = changeEventCalculator;
32
+ return super.onChange(callback);
33
+ }
34
+
8
35
  }
9
36
  //# sourceMappingURL=rotationGesture.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["rotationGesture.ts"],"names":["ContinousBaseGesture","RotationGesture","constructor","handlerName"],"mappings":"AAAA,SAASA,oBAAT,QAAqC,WAArC;AAGA,OAAO,MAAMC,eAAN,SAA8BD,oBAA9B,CAAuF;AAC5FE,EAAAA,WAAW,GAAG;AACZ;AAEA,SAAKC,WAAL,GAAmB,wBAAnB;AACD;;AAL2F","sourcesContent":["import { ContinousBaseGesture } from './gesture';\nimport { RotationGestureHandlerEventPayload } from '../RotationGestureHandler';\n\nexport class RotationGesture extends ContinousBaseGesture<RotationGestureHandlerEventPayload> {\n constructor() {\n super();\n\n this.handlerName = 'RotationGestureHandler';\n }\n}\n\nexport type RotationGestureType = InstanceType<typeof RotationGesture>;\n"]}
1
+ {"version":3,"sources":["rotationGesture.ts"],"names":["ContinousBaseGesture","changeEventCalculator","current","previous","changePayload","undefined","rotationChange","rotation","RotationGesture","constructor","handlerName","onChange","callback","handlers"],"mappings":"AAAA,SAASA,oBAAT,QAAqC,WAArC;;AAQA,SAASC,qBAAT,CACEC,OADF,EAEEC,QAFF,EAGE;AACA;;AACA,MAAIC,aAAJ;;AACA,MAAID,QAAQ,KAAKE,SAAjB,EAA4B;AAC1BD,IAAAA,aAAa,GAAG;AACdE,MAAAA,cAAc,EAAEJ,OAAO,CAACK;AADV,KAAhB;AAGD,GAJD,MAIO;AACLH,IAAAA,aAAa,GAAG;AACdE,MAAAA,cAAc,EAAEJ,OAAO,CAACK,QAAR,GAAmBJ,QAAQ,CAACI;AAD9B,KAAhB;AAGD;;AAED,SAAO,EAAE,GAAGL,OAAL;AAAc,OAAGE;AAAjB,GAAP;AACD;;AAED,OAAO,MAAMI,eAAN,SAA8BR,oBAA9B,CAGL;AACAS,EAAAA,WAAW,GAAG;AACZ;AAEA,SAAKC,WAAL,GAAmB,wBAAnB;AACD;;AAEDC,EAAAA,QAAQ,CACNC,QADM,EAMN;AACA;AACA,SAAKC,QAAL,CAAcZ,qBAAd,GAAsCA,qBAAtC;AACA,WAAO,MAAMU,QAAN,CAAeC,QAAf,CAAP;AACD;;AAjBD","sourcesContent":["import { ContinousBaseGesture } from './gesture';\nimport { RotationGestureHandlerEventPayload } from '../RotationGestureHandler';\nimport { GestureUpdateEvent } from '../gestureHandlerCommon';\n\ntype RotationGestureChangeEventPayload = {\n rotationChange: number;\n};\n\nfunction changeEventCalculator(\n current: GestureUpdateEvent<RotationGestureHandlerEventPayload>,\n previous?: GestureUpdateEvent<RotationGestureHandlerEventPayload>\n) {\n 'worklet';\n let changePayload: RotationGestureChangeEventPayload;\n if (previous === undefined) {\n changePayload = {\n rotationChange: current.rotation,\n };\n } else {\n changePayload = {\n rotationChange: current.rotation - previous.rotation,\n };\n }\n\n return { ...current, ...changePayload };\n}\n\nexport class RotationGesture extends ContinousBaseGesture<\n RotationGestureHandlerEventPayload,\n RotationGestureChangeEventPayload\n> {\n constructor() {\n super();\n\n this.handlerName = 'RotationGestureHandler';\n }\n\n onChange(\n callback: (\n event: GestureUpdateEvent<\n RotationGestureHandlerEventPayload & RotationGestureChangeEventPayload\n >\n ) => void\n ) {\n // @ts-ignore TS being overprotective, RotationGestureHandlerEventPayload is Record\n this.handlers.changeEventCalculator = changeEventCalculator;\n return super.onChange(callback);\n }\n}\n\nexport type RotationGestureType = InstanceType<typeof RotationGesture>;\n"]}
@@ -1,10 +1,16 @@
1
1
  import { BaseGestureConfig, ContinousBaseGesture } from './gesture';
2
2
  import { ForceTouchGestureConfig, ForceTouchGestureHandlerEventPayload } from '../ForceTouchGestureHandler';
3
- export declare class ForceTouchGesture extends ContinousBaseGesture<ForceTouchGestureHandlerEventPayload> {
3
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
4
+ declare type ForceTouchGestureChangeEventPayload = {
5
+ forceChange: number;
6
+ };
7
+ export declare class ForceTouchGesture extends ContinousBaseGesture<ForceTouchGestureHandlerEventPayload, ForceTouchGestureChangeEventPayload> {
4
8
  config: BaseGestureConfig & ForceTouchGestureConfig;
5
9
  constructor();
6
10
  minForce(force: number): this;
7
11
  maxForce(force: number): this;
8
12
  feedbackOnActivation(value: boolean): this;
13
+ onChange(callback: (event: GestureUpdateEvent<GestureUpdateEvent<ForceTouchGestureHandlerEventPayload & ForceTouchGestureChangeEventPayload>>) => void): this;
9
14
  }
10
15
  export declare type ForceTouchGestureType = InstanceType<typeof ForceTouchGesture>;
16
+ export {};
@@ -25,10 +25,12 @@ export declare type HandlerCallbacks<EventPayloadT extends Record<string, unknow
25
25
  onEnd?: (event: GestureStateChangeEvent<EventPayloadT>, success: boolean) => void;
26
26
  onFinalize?: (event: GestureStateChangeEvent<EventPayloadT>, success: boolean) => void;
27
27
  onUpdate?: (event: GestureUpdateEvent<EventPayloadT>) => void;
28
+ onChange?: (event: any) => void;
28
29
  onTouchesDown?: TouchEventHandlerType;
29
30
  onTouchesMove?: TouchEventHandlerType;
30
31
  onTouchesUp?: TouchEventHandlerType;
31
32
  onTouchesCancelled?: TouchEventHandlerType;
33
+ changeEventCalculator?: (current: GestureUpdateEvent<Record<string, unknown>>, previous?: GestureUpdateEvent<Record<string, unknown>>) => GestureUpdateEvent<Record<string, unknown>>;
32
34
  isWorklet: boolean[];
33
35
  };
34
36
  export declare const CALLBACK_TYPE: {
@@ -36,12 +38,13 @@ export declare const CALLBACK_TYPE: {
36
38
  readonly BEGAN: 1;
37
39
  readonly START: 2;
38
40
  readonly UPDATE: 3;
39
- readonly END: 4;
40
- readonly FINALIZE: 5;
41
- readonly TOUCHES_DOWN: 6;
42
- readonly TOUCHES_MOVE: 7;
43
- readonly TOUCHES_UP: 8;
44
- readonly TOUCHES_CANCELLED: 9;
41
+ readonly CHANGE: 4;
42
+ readonly END: 5;
43
+ readonly FINALIZE: 6;
44
+ readonly TOUCHES_DOWN: 7;
45
+ readonly TOUCHES_MOVE: 8;
46
+ readonly TOUCHES_UP: 9;
47
+ readonly TOUCHES_CANCELLED: 10;
45
48
  };
46
49
  export declare type CALLBACK_TYPE = typeof CALLBACK_TYPE[keyof typeof CALLBACK_TYPE];
47
50
  export declare abstract class Gesture {
@@ -68,7 +71,7 @@ export declare abstract class BaseGesture<EventPayloadT extends Record<string, u
68
71
  handlers: HandlerCallbacks<EventPayloadT>;
69
72
  private addDependency;
70
73
  withRef(ref: React.MutableRefObject<GestureType | undefined>): this;
71
- protected isWorklet(callback: TouchEventHandlerType | ((event: GestureUpdateEvent<EventPayloadT>) => void) | ((event: GestureStateChangeEvent<EventPayloadT>) => void)): boolean;
74
+ protected isWorklet(callback: Function): boolean;
72
75
  onBegin(callback: (event: GestureStateChangeEvent<EventPayloadT>) => void): this;
73
76
  onStart(callback: (event: GestureStateChangeEvent<EventPayloadT>) => void): this;
74
77
  onEnd(callback: (event: GestureStateChangeEvent<EventPayloadT>, success: boolean) => void): this;
@@ -86,8 +89,9 @@ export declare abstract class BaseGesture<EventPayloadT extends Record<string, u
86
89
  toGestureArray(): GestureType[];
87
90
  prepare(): void;
88
91
  }
89
- export declare abstract class ContinousBaseGesture<EventPayloadT extends Record<string, unknown>> extends BaseGesture<EventPayloadT> {
92
+ export declare abstract class ContinousBaseGesture<EventPayloadT extends Record<string, unknown>, EventChangePayloadT extends Record<string, unknown>> extends BaseGesture<EventPayloadT> {
90
93
  onUpdate(callback: (event: GestureUpdateEvent<EventPayloadT>) => void): this;
94
+ onChange(callback: (event: GestureUpdateEvent<EventPayloadT & EventChangePayloadT>) => void): this;
91
95
  manualActivation(manualActivation: boolean): this;
92
96
  }
93
97
  export {};
@@ -1,5 +1,7 @@
1
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
1
2
  import { ContinousBaseGesture } from './gesture';
2
- export declare class ManualGesture extends ContinousBaseGesture<Record<string, never>> {
3
+ export declare class ManualGesture extends ContinousBaseGesture<Record<string, never>, Record<string, never>> {
3
4
  constructor();
5
+ onChange(callback: (event: GestureUpdateEvent<Record<string, never>>) => void): this;
4
6
  }
5
7
  export declare type ManualGestureType = InstanceType<typeof ManualGesture>;
@@ -1,6 +1,11 @@
1
1
  import { BaseGestureConfig, ContinousBaseGesture } from './gesture';
2
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
2
3
  import { PanGestureConfig, PanGestureHandlerEventPayload } from '../PanGestureHandler';
3
- export declare class PanGesture extends ContinousBaseGesture<PanGestureHandlerEventPayload> {
4
+ declare type PanGestureChangeEventPayload = {
5
+ changeX: number;
6
+ changeY: number;
7
+ };
8
+ export declare class PanGesture extends ContinousBaseGesture<PanGestureHandlerEventPayload, PanGestureChangeEventPayload> {
4
9
  config: BaseGestureConfig & PanGestureConfig;
5
10
  constructor();
6
11
  activeOffsetY(offset: number | number[]): this;
@@ -15,5 +20,7 @@ export declare class PanGesture extends ContinousBaseGesture<PanGestureHandlerEv
15
20
  minVelocityY(velocity: number): this;
16
21
  averageTouches(value: boolean): this;
17
22
  enableTrackpadTwoFingerGesture(value: boolean): this;
23
+ onChange(callback: (event: GestureUpdateEvent<PanGestureHandlerEventPayload & PanGestureChangeEventPayload>) => void): this;
18
24
  }
19
25
  export declare type PanGestureType = InstanceType<typeof PanGesture>;
26
+ export {};
@@ -1,6 +1,12 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
2
  import { PinchGestureHandlerEventPayload } from '../PinchGestureHandler';
3
- export declare class PinchGesture extends ContinousBaseGesture<PinchGestureHandlerEventPayload> {
3
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
4
+ declare type PinchGestureChangeEventPayload = {
5
+ scaleChange: number;
6
+ };
7
+ export declare class PinchGesture extends ContinousBaseGesture<PinchGestureHandlerEventPayload, PinchGestureChangeEventPayload> {
4
8
  constructor();
9
+ onChange(callback: (event: GestureUpdateEvent<PinchGestureHandlerEventPayload & PinchGestureChangeEventPayload>) => void): this;
5
10
  }
6
11
  export declare type PinchGestureType = InstanceType<typeof PinchGesture>;
12
+ export {};
@@ -1,6 +1,12 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
2
  import { RotationGestureHandlerEventPayload } from '../RotationGestureHandler';
3
- export declare class RotationGesture extends ContinousBaseGesture<RotationGestureHandlerEventPayload> {
3
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
4
+ declare type RotationGestureChangeEventPayload = {
5
+ rotationChange: number;
6
+ };
7
+ export declare class RotationGesture extends ContinousBaseGesture<RotationGestureHandlerEventPayload, RotationGestureChangeEventPayload> {
4
8
  constructor();
9
+ onChange(callback: (event: GestureUpdateEvent<RotationGestureHandlerEventPayload & RotationGestureChangeEventPayload>) => void): this;
5
10
  }
6
11
  export declare type RotationGestureType = InstanceType<typeof RotationGesture>;
12
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-gesture-handler",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Experimental implementation of a new declarative API for gesture handling in react-native",
5
5
  "scripts": {
6
6
  "prepare": "bob build",
@@ -256,6 +256,8 @@ function useAnimatedGesture(preparedGesture: GestureConfigReference) {
256
256
  return gesture.onStart;
257
257
  case CALLBACK_TYPE.UPDATE:
258
258
  return gesture.onUpdate;
259
+ case CALLBACK_TYPE.CHANGE:
260
+ return gesture.onChange;
259
261
  case CALLBACK_TYPE.END:
260
262
  return gesture.onEnd;
261
263
  case CALLBACK_TYPE.FINALIZE:
@@ -310,6 +312,11 @@ function useAnimatedGesture(preparedGesture: GestureConfigReference) {
310
312
  HandlerCallbacks<Record<string, unknown>>[] | null
311
313
  >(null);
312
314
 
315
+ // eslint-disable-next-line react-hooks/rules-of-hooks
316
+ const lastUpdateEvent = Reanimated.useSharedValue<
317
+ (GestureUpdateEvent | undefined)[]
318
+ >([]);
319
+
313
320
  // not every gesture needs a state controller, init them lazily
314
321
  const stateControllers: GestureStateManagerType[] = [];
315
322
 
@@ -339,6 +346,7 @@ function useAnimatedGesture(preparedGesture: GestureConfigReference) {
339
346
  event.state === State.ACTIVE
340
347
  ) {
341
348
  runWorklet(CALLBACK_TYPE.START, gesture, event);
349
+ lastUpdateEvent.value[gesture.handlerTag] = undefined;
342
350
  } else if (
343
351
  event.oldState !== event.state &&
344
352
  event.state === State.END
@@ -371,6 +379,19 @@ function useAnimatedGesture(preparedGesture: GestureConfigReference) {
371
379
  }
372
380
  } else {
373
381
  runWorklet(CALLBACK_TYPE.UPDATE, gesture, event);
382
+
383
+ if (gesture.onChange && gesture.changeEventCalculator) {
384
+ runWorklet(
385
+ CALLBACK_TYPE.CHANGE,
386
+ gesture,
387
+ gesture.changeEventCalculator?.(
388
+ event,
389
+ lastUpdateEvent.value[gesture.handlerTag]
390
+ )
391
+ );
392
+
393
+ lastUpdateEvent.value[gesture.handlerTag] = event;
394
+ }
374
395
  }
375
396
  }
376
397
  }
@@ -36,6 +36,8 @@ const dummyStateManager: GestureStateManagerType = {
36
36
  },
37
37
  };
38
38
 
39
+ const lastUpdateEvent: (GestureUpdateEvent | undefined)[] = [];
40
+
39
41
  function isStateChangeEvent(
40
42
  event: GestureUpdateEvent | GestureStateChangeEvent | GestureTouchEvent
41
43
  ): event is GestureStateChangeEvent {
@@ -69,11 +71,13 @@ function onGestureHandlerEvent(
69
71
  event.state === State.ACTIVE
70
72
  ) {
71
73
  handler.handlers.onStart?.(event);
74
+ lastUpdateEvent[handler.handlers.handlerTag] = event;
72
75
  } else if (event.oldState !== event.state && event.state === State.END) {
73
76
  if (event.oldState === State.ACTIVE) {
74
77
  handler.handlers.onEnd?.(event, true);
75
78
  }
76
79
  handler.handlers.onFinalize?.(event, true);
80
+ lastUpdateEvent[handler.handlers.handlerTag] = undefined;
77
81
  } else if (
78
82
  (event.state === State.FAILED || event.state === State.CANCELLED) &&
79
83
  event.oldState !== event.state
@@ -82,6 +86,7 @@ function onGestureHandlerEvent(
82
86
  handler.handlers.onEnd?.(event, false);
83
87
  }
84
88
  handler.handlers.onFinalize?.(event, false);
89
+ lastUpdateEvent[handler.handlers.handlerTag] = undefined;
85
90
  }
86
91
  } else if (isTouchEvent(event)) {
87
92
  switch (event.eventType) {
@@ -100,6 +105,17 @@ function onGestureHandlerEvent(
100
105
  }
101
106
  } else {
102
107
  handler.handlers.onUpdate?.(event);
108
+
109
+ if (handler.handlers.onChange && handler.handlers.changeEventCalculator) {
110
+ handler.handlers.onChange?.(
111
+ handler.handlers.changeEventCalculator?.(
112
+ event,
113
+ lastUpdateEvent[handler.handlers.handlerTag]
114
+ )
115
+ );
116
+
117
+ lastUpdateEvent[handler.handlers.handlerTag] = event;
118
+ }
103
119
  }
104
120
  }
105
121
  }
@@ -3,8 +3,35 @@ import {
3
3
  ForceTouchGestureConfig,
4
4
  ForceTouchGestureHandlerEventPayload,
5
5
  } from '../ForceTouchGestureHandler';
6
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
6
7
 
7
- export class ForceTouchGesture extends ContinousBaseGesture<ForceTouchGestureHandlerEventPayload> {
8
+ type ForceTouchGestureChangeEventPayload = {
9
+ forceChange: number;
10
+ };
11
+
12
+ function changeEventCalculator(
13
+ current: GestureUpdateEvent<ForceTouchGestureHandlerEventPayload>,
14
+ previous?: GestureUpdateEvent<ForceTouchGestureHandlerEventPayload>
15
+ ) {
16
+ 'worklet';
17
+ let changePayload: ForceTouchGestureChangeEventPayload;
18
+ if (previous === undefined) {
19
+ changePayload = {
20
+ forceChange: current.force,
21
+ };
22
+ } else {
23
+ changePayload = {
24
+ forceChange: current.force - previous.force,
25
+ };
26
+ }
27
+
28
+ return { ...current, ...changePayload };
29
+ }
30
+
31
+ export class ForceTouchGesture extends ContinousBaseGesture<
32
+ ForceTouchGestureHandlerEventPayload,
33
+ ForceTouchGestureChangeEventPayload
34
+ > {
8
35
  public config: BaseGestureConfig & ForceTouchGestureConfig = {};
9
36
 
10
37
  constructor() {
@@ -27,6 +54,21 @@ export class ForceTouchGesture extends ContinousBaseGesture<ForceTouchGestureHan
27
54
  this.config.feedbackOnActivation = value;
28
55
  return this;
29
56
  }
57
+
58
+ onChange(
59
+ callback: (
60
+ event: GestureUpdateEvent<
61
+ GestureUpdateEvent<
62
+ ForceTouchGestureHandlerEventPayload &
63
+ ForceTouchGestureChangeEventPayload
64
+ >
65
+ >
66
+ ) => void
67
+ ) {
68
+ // @ts-ignore TS being overprotective, ForceTouchGestureHandlerEventPayload is Record
69
+ this.handlers.changeEventCalculator = changeEventCalculator;
70
+ return super.onChange(callback);
71
+ }
30
72
  }
31
73
 
32
74
  export type ForceTouchGestureType = InstanceType<typeof ForceTouchGesture>;
@@ -61,10 +61,15 @@ export type HandlerCallbacks<EventPayloadT extends Record<string, unknown>> = {
61
61
  success: boolean
62
62
  ) => void;
63
63
  onUpdate?: (event: GestureUpdateEvent<EventPayloadT>) => void;
64
+ onChange?: (event: any) => void;
64
65
  onTouchesDown?: TouchEventHandlerType;
65
66
  onTouchesMove?: TouchEventHandlerType;
66
67
  onTouchesUp?: TouchEventHandlerType;
67
68
  onTouchesCancelled?: TouchEventHandlerType;
69
+ changeEventCalculator?: (
70
+ current: GestureUpdateEvent<Record<string, unknown>>,
71
+ previous?: GestureUpdateEvent<Record<string, unknown>>
72
+ ) => GestureUpdateEvent<Record<string, unknown>>;
68
73
  isWorklet: boolean[];
69
74
  };
70
75
 
@@ -73,12 +78,13 @@ export const CALLBACK_TYPE = {
73
78
  BEGAN: 1,
74
79
  START: 2,
75
80
  UPDATE: 3,
76
- END: 4,
77
- FINALIZE: 5,
78
- TOUCHES_DOWN: 6,
79
- TOUCHES_MOVE: 7,
80
- TOUCHES_UP: 8,
81
- TOUCHES_CANCELLED: 9,
81
+ CHANGE: 4,
82
+ END: 5,
83
+ FINALIZE: 6,
84
+ TOUCHES_DOWN: 7,
85
+ TOUCHES_MOVE: 8,
86
+ TOUCHES_UP: 9,
87
+ TOUCHES_CANCELLED: 10,
82
88
  } as const;
83
89
 
84
90
  // Allow using CALLBACK_TYPE as object and type
@@ -131,12 +137,8 @@ export abstract class BaseGesture<
131
137
  return this;
132
138
  }
133
139
 
134
- protected isWorklet(
135
- callback:
136
- | TouchEventHandlerType
137
- | ((event: GestureUpdateEvent<EventPayloadT>) => void)
138
- | ((event: GestureStateChangeEvent<EventPayloadT>) => void)
139
- ) {
140
+ // eslint-disable-next-line @typescript-eslint/ban-types
141
+ protected isWorklet(callback: Function) {
140
142
  //@ts-ignore if callback is a worklet, the property will be available, if not then the check will return false
141
143
  return callback.__workletHash !== undefined;
142
144
  }
@@ -264,7 +266,8 @@ export abstract class BaseGesture<
264
266
  }
265
267
 
266
268
  export abstract class ContinousBaseGesture<
267
- EventPayloadT extends Record<string, unknown>
269
+ EventPayloadT extends Record<string, unknown>,
270
+ EventChangePayloadT extends Record<string, unknown>
268
271
  > extends BaseGesture<EventPayloadT> {
269
272
  onUpdate(callback: (event: GestureUpdateEvent<EventPayloadT>) => void) {
270
273
  this.handlers.onUpdate = callback;
@@ -272,6 +275,16 @@ export abstract class ContinousBaseGesture<
272
275
  return this;
273
276
  }
274
277
 
278
+ onChange(
279
+ callback: (
280
+ event: GestureUpdateEvent<EventPayloadT & EventChangePayloadT>
281
+ ) => void
282
+ ) {
283
+ this.handlers.onChange = callback;
284
+ this.handlers.isWorklet[CALLBACK_TYPE.CHANGE] = this.isWorklet(callback);
285
+ return this;
286
+ }
287
+
275
288
  manualActivation(manualActivation: boolean) {
276
289
  this.config.manualActivation = manualActivation;
277
290
  return this;
@@ -1,11 +1,31 @@
1
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
1
2
  import { ContinousBaseGesture } from './gesture';
2
3
 
3
- export class ManualGesture extends ContinousBaseGesture<Record<string, never>> {
4
+ function changeEventCalculator(
5
+ current: GestureUpdateEvent<Record<string, never>>,
6
+ _previous?: GestureUpdateEvent<Record<string, never>>
7
+ ) {
8
+ 'worklet';
9
+ return current;
10
+ }
11
+
12
+ export class ManualGesture extends ContinousBaseGesture<
13
+ Record<string, never>,
14
+ Record<string, never>
15
+ > {
4
16
  constructor() {
5
17
  super();
6
18
 
7
19
  this.handlerName = 'ManualGestureHandler';
8
20
  }
21
+
22
+ onChange(
23
+ callback: (event: GestureUpdateEvent<Record<string, never>>) => void
24
+ ) {
25
+ // @ts-ignore TS being overprotective, Record<string, never> is Record
26
+ this.handlers.changeEventCalculator = changeEventCalculator;
27
+ return super.onChange(callback);
28
+ }
9
29
  }
10
30
 
11
31
  export type ManualGestureType = InstanceType<typeof ManualGesture>;
@@ -1,10 +1,40 @@
1
1
  import { BaseGestureConfig, ContinousBaseGesture } from './gesture';
2
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
2
3
  import {
3
4
  PanGestureConfig,
4
5
  PanGestureHandlerEventPayload,
5
6
  } from '../PanGestureHandler';
6
7
 
7
- export class PanGesture extends ContinousBaseGesture<PanGestureHandlerEventPayload> {
8
+ type PanGestureChangeEventPayload = {
9
+ changeX: number;
10
+ changeY: number;
11
+ };
12
+
13
+ function changeEventCalculator(
14
+ current: GestureUpdateEvent<PanGestureHandlerEventPayload>,
15
+ previous?: GestureUpdateEvent<PanGestureHandlerEventPayload>
16
+ ) {
17
+ 'worklet';
18
+ let changePayload: PanGestureChangeEventPayload;
19
+ if (previous === undefined) {
20
+ changePayload = {
21
+ changeX: current.translationX,
22
+ changeY: current.translationY,
23
+ };
24
+ } else {
25
+ changePayload = {
26
+ changeX: current.translationX - previous.translationX,
27
+ changeY: current.translationY - previous.translationY,
28
+ };
29
+ }
30
+
31
+ return { ...current, ...changePayload };
32
+ }
33
+
34
+ export class PanGesture extends ContinousBaseGesture<
35
+ PanGestureHandlerEventPayload,
36
+ PanGestureChangeEventPayload
37
+ > {
8
38
  public config: BaseGestureConfig & PanGestureConfig = {};
9
39
 
10
40
  constructor() {
@@ -100,6 +130,18 @@ export class PanGesture extends ContinousBaseGesture<PanGestureHandlerEventPaylo
100
130
  this.config.enableTrackpadTwoFingerGesture = value;
101
131
  return this;
102
132
  }
133
+
134
+ onChange(
135
+ callback: (
136
+ event: GestureUpdateEvent<
137
+ PanGestureHandlerEventPayload & PanGestureChangeEventPayload
138
+ >
139
+ ) => void
140
+ ) {
141
+ // @ts-ignore TS being overprotective, PanGestureHandlerEventPayload is Record
142
+ this.handlers.changeEventCalculator = changeEventCalculator;
143
+ return super.onChange(callback);
144
+ }
103
145
  }
104
146
 
105
147
  export type PanGestureType = InstanceType<typeof PanGesture>;
@@ -1,12 +1,51 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
2
  import { PinchGestureHandlerEventPayload } from '../PinchGestureHandler';
3
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
3
4
 
4
- export class PinchGesture extends ContinousBaseGesture<PinchGestureHandlerEventPayload> {
5
+ type PinchGestureChangeEventPayload = {
6
+ scaleChange: number;
7
+ };
8
+
9
+ function changeEventCalculator(
10
+ current: GestureUpdateEvent<PinchGestureHandlerEventPayload>,
11
+ previous?: GestureUpdateEvent<PinchGestureHandlerEventPayload>
12
+ ) {
13
+ 'worklet';
14
+ let changePayload: PinchGestureChangeEventPayload;
15
+ if (previous === undefined) {
16
+ changePayload = {
17
+ scaleChange: current.scale,
18
+ };
19
+ } else {
20
+ changePayload = {
21
+ scaleChange: current.scale / previous.scale,
22
+ };
23
+ }
24
+
25
+ return { ...current, ...changePayload };
26
+ }
27
+
28
+ export class PinchGesture extends ContinousBaseGesture<
29
+ PinchGestureHandlerEventPayload,
30
+ PinchGestureChangeEventPayload
31
+ > {
5
32
  constructor() {
6
33
  super();
7
34
 
8
35
  this.handlerName = 'PinchGestureHandler';
9
36
  }
37
+
38
+ onChange(
39
+ callback: (
40
+ event: GestureUpdateEvent<
41
+ PinchGestureHandlerEventPayload & PinchGestureChangeEventPayload
42
+ >
43
+ ) => void
44
+ ) {
45
+ // @ts-ignore TS being overprotective, PinchGestureHandlerEventPayload is Record
46
+ this.handlers.changeEventCalculator = changeEventCalculator;
47
+ return super.onChange(callback);
48
+ }
10
49
  }
11
50
 
12
51
  export type PinchGestureType = InstanceType<typeof PinchGesture>;
@@ -1,12 +1,51 @@
1
1
  import { ContinousBaseGesture } from './gesture';
2
2
  import { RotationGestureHandlerEventPayload } from '../RotationGestureHandler';
3
+ import { GestureUpdateEvent } from '../gestureHandlerCommon';
3
4
 
4
- export class RotationGesture extends ContinousBaseGesture<RotationGestureHandlerEventPayload> {
5
+ type RotationGestureChangeEventPayload = {
6
+ rotationChange: number;
7
+ };
8
+
9
+ function changeEventCalculator(
10
+ current: GestureUpdateEvent<RotationGestureHandlerEventPayload>,
11
+ previous?: GestureUpdateEvent<RotationGestureHandlerEventPayload>
12
+ ) {
13
+ 'worklet';
14
+ let changePayload: RotationGestureChangeEventPayload;
15
+ if (previous === undefined) {
16
+ changePayload = {
17
+ rotationChange: current.rotation,
18
+ };
19
+ } else {
20
+ changePayload = {
21
+ rotationChange: current.rotation - previous.rotation,
22
+ };
23
+ }
24
+
25
+ return { ...current, ...changePayload };
26
+ }
27
+
28
+ export class RotationGesture extends ContinousBaseGesture<
29
+ RotationGestureHandlerEventPayload,
30
+ RotationGestureChangeEventPayload
31
+ > {
5
32
  constructor() {
6
33
  super();
7
34
 
8
35
  this.handlerName = 'RotationGestureHandler';
9
36
  }
37
+
38
+ onChange(
39
+ callback: (
40
+ event: GestureUpdateEvent<
41
+ RotationGestureHandlerEventPayload & RotationGestureChangeEventPayload
42
+ >
43
+ ) => void
44
+ ) {
45
+ // @ts-ignore TS being overprotective, RotationGestureHandlerEventPayload is Record
46
+ this.handlers.changeEventCalculator = changeEventCalculator;
47
+ return super.onChange(callback);
48
+ }
10
49
  }
11
50
 
12
51
  export type RotationGestureType = InstanceType<typeof RotationGesture>;