react-native-skia-gesture 0.2.0 → 0.3.2
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.
- package/README.md +77 -20
- package/lib/commonjs/canvas/canvas.js +68 -56
- package/lib/commonjs/canvas/canvas.js.map +1 -1
- package/lib/commonjs/canvas/context.js +1 -1
- package/lib/commonjs/canvas/context.js.map +1 -1
- package/lib/commonjs/components/index.js +4 -4
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/hoc/with-touchable-handler.js +29 -34
- package/lib/commonjs/hoc/with-touchable-handler.js.map +1 -1
- package/lib/commonjs/hooks/use-gesture-handler.js +11 -5
- package/lib/commonjs/hooks/use-gesture-handler.js.map +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/get-circle-path.js +2 -0
- package/lib/commonjs/utils/get-circle-path.js.map +1 -1
- package/lib/commonjs/utils/get-rect-path.js +8 -5
- package/lib/commonjs/utils/get-rect-path.js.map +1 -1
- package/lib/commonjs/utils/unwrap-animated-value.js +7 -0
- package/lib/commonjs/utils/unwrap-animated-value.js.map +1 -1
- package/lib/module/canvas/canvas.js +70 -58
- package/lib/module/canvas/canvas.js.map +1 -1
- package/lib/module/canvas/context.js +1 -1
- package/lib/module/canvas/context.js.map +1 -1
- package/lib/module/components/index.js +4 -4
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/hoc/with-touchable-handler.js +28 -34
- package/lib/module/hoc/with-touchable-handler.js.map +1 -1
- package/lib/module/hooks/use-gesture-handler.js +11 -5
- package/lib/module/hooks/use-gesture-handler.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/get-circle-path.js +2 -0
- package/lib/module/utils/get-circle-path.js.map +1 -1
- package/lib/module/utils/get-rect-path.js +9 -6
- package/lib/module/utils/get-rect-path.js.map +1 -1
- package/lib/module/utils/unwrap-animated-value.js +7 -0
- package/lib/module/utils/unwrap-animated-value.js.map +1 -1
- package/lib/typescript/canvas/canvas.d.ts +7 -2
- package/lib/typescript/canvas/canvas.d.ts.map +1 -1
- package/lib/typescript/canvas/context.d.ts +6 -5
- package/lib/typescript/canvas/context.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +2 -2
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/hoc/with-touchable-handler.d.ts +7 -9
- package/lib/typescript/hoc/with-touchable-handler.d.ts.map +1 -1
- package/lib/typescript/hooks/use-gesture-handler.d.ts +7 -8
- package/lib/typescript/hooks/use-gesture-handler.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/utils/get-circle-path.d.ts.map +1 -1
- package/lib/typescript/utils/get-rect-path.d.ts.map +1 -1
- package/lib/typescript/utils/unwrap-animated-value.d.ts +2 -1
- package/lib/typescript/utils/unwrap-animated-value.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/canvas/canvas.tsx +109 -81
- package/src/canvas/context.tsx +19 -10
- package/src/components/index.ts +5 -4
- package/src/hoc/with-touchable-handler.tsx +40 -35
- package/src/hooks/use-gesture-handler.ts +25 -16
- package/src/index.ts +1 -1
- package/src/utils/get-circle-path.ts +1 -0
- package/src/utils/get-rect-path.ts +11 -6
- package/src/utils/unwrap-animated-value.ts +9 -1
@@ -1,10 +1,11 @@
|
|
1
|
-
import type { ExtendedTouchInfo, TouchInfo, Vector } from '@shopify/react-native-skia';
|
2
1
|
import React from 'react';
|
2
|
+
import type { Vector } from '@shopify/react-native-skia';
|
3
|
+
import type { GestureStateChangeEvent, GestureUpdateEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
|
3
4
|
export type TouchableHandlerContextType = {
|
4
|
-
|
5
|
-
onStart: (touchInfo:
|
6
|
-
onActive: (touchInfo:
|
7
|
-
onEnd: (touchInfo:
|
5
|
+
value: Record<string, {
|
6
|
+
onStart: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
7
|
+
onActive: (touchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>) => void;
|
8
|
+
onEnd: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
8
9
|
isPointInPath: (point: Vector) => boolean;
|
9
10
|
}>;
|
10
11
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/canvas/context.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/canvas/context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,MAAM,CACX,MAAM,EACN;QACE,OAAO,EAAE,CACP,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,KAC9D,IAAI,CAAC;QACV,QAAQ,EAAE,CACR,SAAS,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,KACzD,IAAI,CAAC;QACV,KAAK,EAAE,CACL,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,KAC9D,IAAI,CAAC;QACV,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;KAC3C,CACF,CAAC;CACH,CAAC;AAEF,QAAA,MAAM,mBAAmB,4CAEvB,CAAC;AAEH,QAAA,MAAM,sBAAsB,mCAE3B,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,CAAC"}
|
@@ -2,8 +2,8 @@ export { Canvas } from '../canvas';
|
|
2
2
|
export declare const Circle: ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: import("@shopify/react-native-skia").AnimatedProps<import("@shopify/react-native-skia").CircleProps, never> & Partial<import("../hoc").TouchableHandlerProps>) => JSX.Element;
|
3
3
|
export declare const RoundedRect: ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: import("@shopify/react-native-skia").AnimatedProps<import("@shopify/react-native-skia").RoundedRectProps, never> & Partial<import("../hoc").TouchableHandlerProps>) => JSX.Element;
|
4
4
|
export declare const Rect: ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: import("@shopify/react-native-skia").AnimatedProps<import("@shopify/react-native-skia").RectProps, never> & Partial<import("../hoc").TouchableHandlerProps>) => JSX.Element;
|
5
|
-
export declare const Path: ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: Omit<import("@shopify/react-native-skia").AnimatedProps<import("@shopify/react-native-skia").PathProps, never>, "
|
6
|
-
start?: import("@shopify/react-native-skia").AnimatedProp<number, any> | undefined;
|
5
|
+
export declare const Path: ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: Omit<import("@shopify/react-native-skia").AnimatedProps<import("@shopify/react-native-skia").PathProps, never>, "end" | "start"> & {
|
7
6
|
end?: import("@shopify/react-native-skia").AnimatedProp<number, any> | undefined;
|
7
|
+
start?: import("@shopify/react-native-skia").AnimatedProp<number, any> | undefined;
|
8
8
|
} & Partial<import("../hoc").TouchableHandlerProps>) => JSX.Element;
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,eAAO,MAAM,MAAM,6QAA6C,CAAC;AACjE,eAAO,MAAM,WAAW,kRAAuD,CAAC;AAChF,eAAO,MAAM,IAAI,2QAAyC,CAAC;AAC3D,eAAO,MAAM,IAAI;;;mEAAyC,CAAC"}
|
@@ -1,15 +1,13 @@
|
|
1
|
-
import { type
|
2
|
-
|
3
|
-
translationX: number;
|
4
|
-
translationY: number;
|
5
|
-
};
|
1
|
+
import { type SkiaValue, type SkPath } from '@shopify/react-native-skia';
|
2
|
+
import type { GestureStateChangeEvent, GestureUpdateEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
|
6
3
|
export type TouchableHandlerProps = {
|
7
|
-
onStart: (touchInfo:
|
8
|
-
onActive: (touchInfo:
|
9
|
-
onEnd: (touchInfo:
|
4
|
+
onStart: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
5
|
+
onActive: (touchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>) => void;
|
6
|
+
onEnd: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
10
7
|
touchablePath: SkPath | SkiaValue<SkPath>;
|
11
8
|
};
|
12
9
|
type WithTouchableHandlerProps<T> = T & Partial<TouchableHandlerProps>;
|
13
|
-
declare const
|
10
|
+
export declare const getSkiaPath: (key: string, props: any) => any;
|
11
|
+
declare const withTouchableHandler: <T>(Component: (props: WithTouchableHandlerProps<T>) => JSX.Element, componentName?: string) => ({ onStart: onStartProp, onActive: onActiveProp, onEnd: onEndProp, touchablePath, ...props }: WithTouchableHandlerProps<T>) => JSX.Element;
|
14
12
|
export { withTouchableHandler };
|
15
13
|
//# sourceMappingURL=with-touchable-handler.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"with-touchable-handler.d.ts","sourceRoot":"","sources":["../../../src/hoc/with-touchable-handler.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,
|
1
|
+
{"version":3,"file":"with-touchable-handler.d.ts","sourceRoot":"","sources":["../../../src/hoc/with-touchable-handler.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,MAAM,EAEZ,MAAM,4BAA4B,CAAC;AAWpC,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,CACP,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,KAC9D,IAAI,CAAC;IACV,QAAQ,EAAE,CACR,SAAS,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,KACzD,IAAI,CAAC;IACV,KAAK,EAAE,CACL,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,KAC9D,IAAI,CAAC;IACV,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,yBAAyB,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEvE,eAAO,MAAM,WAAW,QAAS,MAAM,SAAS,GAAG,QAgBlD,CAAC;AAEF,QAAA,MAAM,oBAAoB,0DAC4B,WAAW,kBAC/C,MAAM,+IAyEvB,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
@@ -1,14 +1,13 @@
|
|
1
|
-
import {
|
2
|
-
import type { TranslationInfo } from '../hoc';
|
1
|
+
import type { GestureStateChangeEvent, GestureUpdateEvent, PanGestureHandlerEventPayload } from 'react-native-gesture-handler';
|
3
2
|
type UseGestureHandlerParams<ContextType> = {
|
4
|
-
onStart?: (touchInfo:
|
5
|
-
onActive?: (
|
6
|
-
onEnd?: (
|
3
|
+
onStart?: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>, context: ContextType) => void;
|
4
|
+
onActive?: (touchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>, context: ContextType) => void;
|
5
|
+
onEnd?: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>, context: ContextType) => void;
|
7
6
|
};
|
8
7
|
declare const useGestureHandler: <ContextType>(gestureHandlers: UseGestureHandlerParams<ContextType>) => {
|
9
|
-
onStart: (touchInfo:
|
10
|
-
onActive: (extendedTouchInfo:
|
11
|
-
onEnd: (extendedTouchInfo:
|
8
|
+
onStart: (touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
9
|
+
onActive: (extendedTouchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>) => void;
|
10
|
+
onEnd: (extendedTouchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => void;
|
12
11
|
};
|
13
12
|
export { useGestureHandler };
|
14
13
|
//# sourceMappingURL=use-gesture-handler.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"use-gesture-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-gesture-handler.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"use-gesture-handler.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-gesture-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,8BAA8B,CAAC;AAEtC,KAAK,uBAAuB,CAAC,WAAW,IAAI;IAC1C,OAAO,CAAC,EAAE,CACR,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,EACjE,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;IACV,QAAQ,CAAC,EAAE,CACT,SAAS,EAAE,kBAAkB,CAAC,6BAA6B,CAAC,EAC5D,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;IACV,KAAK,CAAC,EAAE,CACN,SAAS,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,EACjE,OAAO,EAAE,WAAW,KACjB,IAAI,CAAC;CACX,CAAC;AAEF,QAAA,MAAM,iBAAiB;yBAQP,wBAAwB,6BAA6B,CAAC;kCAS9C,mBAAmB,6BAA6B,CAAC;+BAUhD,wBAAwB,6BAA6B,CAAC;CAc9E,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,cAAc,CAAC;AAC1C,cAAc,OAAO,CAAC;AACtB,cAAc,6BAA6B,CAAC;AAE5C,eAAe,SAAS,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"get-circle-path.d.ts","sourceRoot":"","sources":["../../../src/utils/get-circle-path.ts"],"names":[],"mappings":"AAEA,KAAK,mBAAmB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,aAAa,kBAAmB,mBAAmB,
|
1
|
+
{"version":3,"file":"get-circle-path.d.ts","sourceRoot":"","sources":["../../../src/utils/get-circle-path.ts"],"names":[],"mappings":"AAEA,KAAK,mBAAmB,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,aAAa,kBAAmB,mBAAmB,gDAG/D,CAAC"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"get-rect-path.d.ts","sourceRoot":"","sources":["../../../src/utils/get-rect-path.ts"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"get-rect-path.d.ts","sourceRoot":"","sources":["../../../src/utils/get-rect-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAE/D,KAAK,iBAAiB,GAClB;IACE,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,QAAA,MAAM,WAAW,WAAY,iBAAiB,gDAc7C,CAAC;AAEF,KAAK,wBAAwB,GAAG,iBAAiB,GAAG;IAClD,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,QAAA,MAAM,kBAAkB,WAAY,wBAAwB,gDAgB3D,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC"}
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import type { SkiaValue } from '@shopify/react-native-skia';
|
2
|
+
import type Animated from 'react-native-reanimated';
|
2
3
|
type SkiaValueWithSelector<T> = {
|
3
4
|
value: SkiaValue<T>;
|
4
5
|
selector: (v: T) => T;
|
5
6
|
};
|
6
|
-
declare const unwrapAnimatedValue: <T>(value: T | SkiaValue<T> | SkiaValueWithSelector<T>) => T;
|
7
|
+
declare const unwrapAnimatedValue: <T>(value: T | SkiaValue<T> | SkiaValueWithSelector<T> | Animated.SharedValue<T>) => T;
|
7
8
|
declare const unwrapAnimatedValueObject: <T>(value: Record<any, T | SkiaValue<T>>) => Record<any, T>;
|
8
9
|
export { unwrapAnimatedValue, unwrapAnimatedValueObject };
|
9
10
|
//# sourceMappingURL=unwrap-animated-value.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"unwrap-animated-value.d.ts","sourceRoot":"","sources":["../../../src/utils/unwrap-animated-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;
|
1
|
+
{"version":3,"file":"unwrap-animated-value.d.ts","sourceRoot":"","sources":["../../../src/utils/unwrap-animated-value.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAEpD,KAAK,qBAAqB,CAAC,CAAC,IAAI;IAC9B,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;CACvB,CAAC;AACF,QAAA,MAAM,mBAAmB,wFAmBxB,CAAC;AAEF,QAAA,MAAM,yBAAyB,6DAO9B,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "react-native-skia-gesture",
|
3
|
-
"version": "0.2
|
3
|
+
"version": "0.3.2",
|
4
4
|
"description": "A detection system for React Native Skia components",
|
5
5
|
"main": "lib/commonjs/index",
|
6
6
|
"module": "lib/module/index",
|
@@ -55,7 +55,7 @@
|
|
55
55
|
"@evilmartians/lefthook": "^1.2.2",
|
56
56
|
"@react-native-community/eslint-config": "^3.0.2",
|
57
57
|
"@release-it/conventional-changelog": "^5.0.0",
|
58
|
-
"@shopify/react-native-skia": "0.1.
|
58
|
+
"@shopify/react-native-skia": "0.1.221",
|
59
59
|
"@types/jest": "^28.1.2",
|
60
60
|
"@types/react": "18.0.26",
|
61
61
|
"@types/react-native": "0.70.0",
|
@@ -70,6 +70,8 @@
|
|
70
70
|
"react": "18.1.0",
|
71
71
|
"react-native": "0.70.5",
|
72
72
|
"react-native-builder-bob": "^0.20.0",
|
73
|
+
"react-native-gesture-handler": "~2.14.0",
|
74
|
+
"react-native-reanimated": "~3.6.2",
|
73
75
|
"release-it": "^15.0.0",
|
74
76
|
"typescript": "^4.5.2"
|
75
77
|
},
|
@@ -81,9 +83,9 @@
|
|
81
83
|
"react-native": "*"
|
82
84
|
},
|
83
85
|
"engines": {
|
84
|
-
"node": ">=
|
86
|
+
"node": ">= 18.0.0"
|
85
87
|
},
|
86
|
-
"packageManager": "
|
88
|
+
"packageManager": "yarn@1.22.21",
|
87
89
|
"jest": {
|
88
90
|
"preset": "react-native",
|
89
91
|
"modulePathIgnorePatterns": [
|
package/src/canvas/canvas.tsx
CHANGED
@@ -1,92 +1,120 @@
|
|
1
|
+
import { Canvas as SkiaCanvas } from '@shopify/react-native-skia';
|
2
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
1
3
|
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
import React, { useEffect } from 'react';
|
4
|
+
Gesture,
|
5
|
+
GestureDetector,
|
6
|
+
PanGesture,
|
7
|
+
} from 'react-native-gesture-handler';
|
8
|
+
import Animated, { useSharedValue } from 'react-native-reanimated';
|
9
|
+
|
9
10
|
import {
|
10
11
|
TouchHandlerContext,
|
11
12
|
type TouchableHandlerContextType,
|
12
13
|
} from './context';
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
);
|
63
|
-
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
15
|
+
import type { CanvasProps } from '@shopify/react-native-skia';
|
16
|
+
|
17
|
+
type TouchableCanvasProps = CanvasProps & {
|
18
|
+
panGesture?: PanGesture;
|
19
|
+
timeoutBeforeCollectingRefs?: number; // default 100
|
20
|
+
};
|
21
|
+
|
22
|
+
const AnimatedSkiaCanvas = Animated.createAnimatedComponent(SkiaCanvas);
|
23
|
+
|
24
|
+
const Canvas: React.FC<TouchableCanvasProps> = ({
|
25
|
+
children,
|
26
|
+
panGesture = Gesture.Pan(),
|
27
|
+
timeoutBeforeCollectingRefs = 100,
|
28
|
+
...props
|
29
|
+
}) => {
|
30
|
+
// Instead of value, provide a subscribe method and reload the refs
|
31
|
+
const touchableRefs: TouchableHandlerContextType = useMemo(() => {
|
32
|
+
return { value: {} };
|
33
|
+
}, []);
|
34
|
+
|
35
|
+
const activeKey = useSharedValue<string[]>([]);
|
36
|
+
|
37
|
+
// This must be improved, it's a hack to wait for the refs to be loaded
|
38
|
+
const [loadedRefs, prepareLoadedRefs] = useState<
|
39
|
+
TouchableHandlerContextType['value']
|
40
|
+
>({});
|
41
|
+
|
42
|
+
const ref = useRef<NodeJS.Timeout>();
|
43
|
+
|
44
|
+
useEffect(() => {
|
45
|
+
ref.current = setTimeout(() => {
|
46
|
+
prepareLoadedRefs(touchableRefs.value);
|
47
|
+
}, timeoutBeforeCollectingRefs);
|
48
|
+
|
49
|
+
return () => {
|
50
|
+
clearTimeout(ref.current);
|
51
|
+
};
|
52
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
53
|
+
}, [timeoutBeforeCollectingRefs]);
|
54
|
+
|
55
|
+
const mainGesture = panGesture
|
56
|
+
.onBegin((event) => {
|
57
|
+
const keys = Object.keys(loadedRefs);
|
58
|
+
for (let i = 0; i < keys.length; i++) {
|
59
|
+
const key = keys[i] as string;
|
60
|
+
const touchableItem = loadedRefs[key];
|
61
|
+
const isPointInPath = touchableItem?.isPointInPath(event);
|
62
|
+
if (isPointInPath && touchableItem?.onStart) {
|
63
|
+
activeKey.value.push(`${key}__${event.handlerTag}`);
|
64
|
+
touchableItem.onStart?.(event);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
})
|
68
|
+
.onUpdate((event) => {
|
69
|
+
const activatedKey = activeKey.value.find((key) =>
|
70
|
+
key.includes(event.handlerTag.toString())
|
71
|
+
);
|
72
|
+
|
73
|
+
if (!activatedKey) {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
const indexedKey = activatedKey.split('__')?.[0];
|
77
|
+
|
78
|
+
if (!indexedKey) {
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
const touchableItem = loadedRefs[indexedKey];
|
82
|
+
|
83
|
+
return touchableItem?.onActive?.(event);
|
84
|
+
})
|
85
|
+
.onFinalize((event) => {
|
86
|
+
const activatedKey = activeKey.value.find((key) =>
|
87
|
+
key.includes(event.handlerTag.toString())
|
88
|
+
);
|
89
|
+
if (!activatedKey) {
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
const indexedKey = activatedKey.split('__')?.[0];
|
93
|
+
if (!indexedKey) {
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
const touchableItem = loadedRefs[indexedKey];
|
97
|
+
activeKey.value = activeKey.value.filter(
|
98
|
+
(key) => !key.includes(event.handlerTag.toString())
|
99
|
+
);
|
100
|
+
return touchableItem?.onEnd?.(event as any);
|
101
|
+
});
|
102
|
+
|
103
|
+
useEffect(() => {
|
104
|
+
return () => {
|
105
|
+
touchableRefs.value = {};
|
106
|
+
};
|
107
|
+
}, [touchableRefs]);
|
108
|
+
|
109
|
+
return (
|
110
|
+
<GestureDetector gesture={mainGesture}>
|
111
|
+
<AnimatedSkiaCanvas {...props}>
|
84
112
|
<TouchHandlerContext.Provider value={touchableRefs}>
|
85
113
|
{children}
|
86
114
|
</TouchHandlerContext.Provider>
|
87
|
-
</
|
88
|
-
|
89
|
-
|
90
|
-
|
115
|
+
</AnimatedSkiaCanvas>
|
116
|
+
</GestureDetector>
|
117
|
+
);
|
118
|
+
};
|
91
119
|
|
92
120
|
export { Canvas };
|
package/src/canvas/context.tsx
CHANGED
@@ -1,23 +1,32 @@
|
|
1
|
-
import type {
|
2
|
-
ExtendedTouchInfo,
|
3
|
-
TouchInfo,
|
4
|
-
Vector,
|
5
|
-
} from '@shopify/react-native-skia';
|
6
1
|
import React, { useContext } from 'react';
|
7
2
|
|
3
|
+
import type { Vector } from '@shopify/react-native-skia';
|
4
|
+
import type {
|
5
|
+
GestureStateChangeEvent,
|
6
|
+
GestureUpdateEvent,
|
7
|
+
PanGestureHandlerEventPayload,
|
8
|
+
} from 'react-native-gesture-handler';
|
9
|
+
|
8
10
|
export type TouchableHandlerContextType = {
|
9
|
-
|
11
|
+
value: Record<
|
10
12
|
string,
|
11
13
|
{
|
12
|
-
onStart: (
|
13
|
-
|
14
|
-
|
14
|
+
onStart: (
|
15
|
+
touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
16
|
+
) => void;
|
17
|
+
onActive: (
|
18
|
+
touchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>
|
19
|
+
) => void;
|
20
|
+
onEnd: (
|
21
|
+
touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
22
|
+
) => void;
|
15
23
|
isPointInPath: (point: Vector) => boolean;
|
16
24
|
}
|
17
25
|
>;
|
18
26
|
};
|
27
|
+
|
19
28
|
const TouchHandlerContext = React.createContext<TouchableHandlerContextType>({
|
20
|
-
|
29
|
+
value: {},
|
21
30
|
});
|
22
31
|
|
23
32
|
const useTouchHandlerContext = () => {
|
package/src/components/index.ts
CHANGED
@@ -4,11 +4,12 @@ import {
|
|
4
4
|
Rect as SkiaRect,
|
5
5
|
Path as SkiaPath,
|
6
6
|
} from '@shopify/react-native-skia';
|
7
|
+
|
7
8
|
import { withTouchableHandler } from '../hoc';
|
8
9
|
|
9
10
|
export { Canvas } from '../canvas';
|
10
11
|
|
11
|
-
export const Circle = withTouchableHandler(SkiaCircle);
|
12
|
-
export const RoundedRect = withTouchableHandler(SkiaRoundedRect);
|
13
|
-
export const Rect = withTouchableHandler(SkiaRect);
|
14
|
-
export const Path = withTouchableHandler(SkiaPath);
|
12
|
+
export const Circle = withTouchableHandler(SkiaCircle, 'Circle');
|
13
|
+
export const RoundedRect = withTouchableHandler(SkiaRoundedRect, 'RoundedRect');
|
14
|
+
export const Rect = withTouchableHandler(SkiaRect, 'Rect');
|
15
|
+
export const Path = withTouchableHandler(SkiaPath, 'Path');
|
@@ -1,37 +1,43 @@
|
|
1
1
|
import {
|
2
|
-
type ExtendedTouchInfo,
|
3
2
|
type SkiaValue,
|
4
3
|
type SkPath,
|
5
|
-
type TouchInfo,
|
6
4
|
type Vector,
|
7
|
-
useValue,
|
8
5
|
} from '@shopify/react-native-skia';
|
9
6
|
import { useCallback, useEffect, useId } from 'react';
|
7
|
+
|
8
|
+
import { useTouchHandlerContext } from '../canvas/context';
|
10
9
|
import { getCirclePath } from '../utils/get-circle-path';
|
11
10
|
import { getRectPath, getRoundedRectPath } from '../utils/get-rect-path';
|
12
11
|
import {
|
13
12
|
unwrapAnimatedValue,
|
14
13
|
unwrapAnimatedValueObject,
|
15
14
|
} from '../utils/unwrap-animated-value';
|
16
|
-
import { useTouchHandlerContext } from '../canvas/context';
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
import type {
|
17
|
+
GestureStateChangeEvent,
|
18
|
+
GestureUpdateEvent,
|
19
|
+
PanGestureHandlerEventPayload,
|
20
|
+
} from 'react-native-gesture-handler';
|
22
21
|
|
23
22
|
export type TouchableHandlerProps = {
|
24
|
-
onStart: (
|
25
|
-
|
26
|
-
|
23
|
+
onStart: (
|
24
|
+
touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
25
|
+
) => void;
|
26
|
+
onActive: (
|
27
|
+
touchInfo: GestureUpdateEvent<PanGestureHandlerEventPayload>
|
28
|
+
) => void;
|
29
|
+
onEnd: (
|
30
|
+
touchInfo: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
31
|
+
) => void;
|
27
32
|
touchablePath: SkPath | SkiaValue<SkPath>;
|
28
33
|
};
|
29
34
|
|
30
35
|
type WithTouchableHandlerProps<T> = T & Partial<TouchableHandlerProps>;
|
31
36
|
|
32
|
-
const getSkiaPath = (key: string, props: any) => {
|
33
|
-
|
37
|
+
export const getSkiaPath = (key: string, props: any) => {
|
38
|
+
'worklet';
|
34
39
|
|
40
|
+
const unwrappedProps = unwrapAnimatedValueObject(props) as any;
|
35
41
|
switch (key) {
|
36
42
|
case 'Circle':
|
37
43
|
return getCirclePath(unwrappedProps);
|
@@ -47,7 +53,8 @@ const getSkiaPath = (key: string, props: any) => {
|
|
47
53
|
};
|
48
54
|
|
49
55
|
const withTouchableHandler = <T,>(
|
50
|
-
Component: (props: WithTouchableHandlerProps<T>) => JSX.Element
|
56
|
+
Component: (props: WithTouchableHandlerProps<T>) => JSX.Element,
|
57
|
+
componentName?: string
|
51
58
|
) => {
|
52
59
|
return ({
|
53
60
|
onStart: onStartProp,
|
@@ -59,42 +66,37 @@ const withTouchableHandler = <T,>(
|
|
59
66
|
const id = useId();
|
60
67
|
const ref = useTouchHandlerContext();
|
61
68
|
|
62
|
-
const startingPoint = useValue<Vector | null>(null);
|
63
|
-
|
64
69
|
const onStart: TouchableHandlerProps['onStart'] = useCallback(
|
65
70
|
(event) => {
|
66
|
-
|
71
|
+
'worklet';
|
67
72
|
return onStartProp?.(event);
|
68
73
|
},
|
69
|
-
[onStartProp
|
74
|
+
[onStartProp]
|
70
75
|
);
|
71
76
|
const onActive: TouchableHandlerProps['onActive'] = useCallback(
|
72
77
|
(event) => {
|
73
|
-
|
74
|
-
|
75
|
-
return onActiveProp?.({
|
76
|
-
...event,
|
77
|
-
translationX,
|
78
|
-
translationY,
|
79
|
-
});
|
78
|
+
'worklet';
|
79
|
+
return onActiveProp?.(event);
|
80
80
|
},
|
81
|
-
[onActiveProp
|
81
|
+
[onActiveProp]
|
82
82
|
);
|
83
83
|
const onEnd: TouchableHandlerProps['onEnd'] = useCallback(
|
84
84
|
(event) => {
|
85
|
-
|
86
|
-
|
87
|
-
return onEndProp?.({ ...event, translationX, translationY });
|
85
|
+
'worklet';
|
86
|
+
return onEndProp?.(event);
|
88
87
|
},
|
89
|
-
[onEndProp
|
88
|
+
[onEndProp]
|
90
89
|
);
|
91
90
|
|
92
91
|
const isPointInPath = useCallback(
|
93
92
|
(point: Vector) => {
|
93
|
+
'worklet';
|
94
94
|
if (touchablePath) {
|
95
95
|
return unwrapAnimatedValue(touchablePath).contains(point.x, point.y);
|
96
96
|
}
|
97
|
-
|
97
|
+
|
98
|
+
if (!componentName) return false;
|
99
|
+
const path = getSkiaPath(componentName, props);
|
98
100
|
|
99
101
|
if (!path) {
|
100
102
|
throw Error('No touchablePath provided');
|
@@ -105,20 +107,23 @@ const withTouchableHandler = <T,>(
|
|
105
107
|
);
|
106
108
|
|
107
109
|
useEffect(() => {
|
108
|
-
ref.
|
110
|
+
ref.value = {
|
109
111
|
[`id:${id}`]: {
|
110
112
|
isPointInPath,
|
111
113
|
onStart,
|
112
114
|
onActive,
|
113
115
|
onEnd,
|
114
116
|
},
|
115
|
-
...ref.
|
117
|
+
...ref.value,
|
116
118
|
} as any;
|
119
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
120
|
+
}, [id, isPointInPath, onActive, onEnd, onStart]);
|
117
121
|
|
122
|
+
useEffect(() => {
|
118
123
|
return () => {
|
119
|
-
delete ref.
|
124
|
+
delete ref.value?.[`id:${id}`];
|
120
125
|
};
|
121
|
-
}, [id,
|
126
|
+
}, [id, props, ref, touchablePath]);
|
122
127
|
|
123
128
|
return Component(props as any);
|
124
129
|
};
|