@shopify/react-native-skia 0.1.214 → 0.1.215

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 (112) hide show
  1. package/cpp/api/JsiSkMatrix.h +31 -0
  2. package/cpp/api/JsiSkPath.h +15 -7
  3. package/lib/commonjs/animation/functions/interpolatePaths.d.ts +1 -1
  4. package/lib/commonjs/animation/functions/interpolatePaths.js +4 -4
  5. package/lib/commonjs/animation/functions/interpolatePaths.js.map +1 -1
  6. package/lib/commonjs/external/reanimated/index.d.ts +2 -1
  7. package/lib/commonjs/external/reanimated/index.js +17 -4
  8. package/lib/commonjs/external/reanimated/index.js.map +1 -1
  9. package/lib/commonjs/external/reanimated/interpolators.d.ts +9 -0
  10. package/lib/commonjs/external/reanimated/interpolators.js +56 -0
  11. package/lib/commonjs/external/reanimated/interpolators.js.map +1 -0
  12. package/lib/commonjs/external/reanimated/moduleWrapper.d.ts +8 -6
  13. package/lib/commonjs/external/reanimated/moduleWrapper.js +6 -11
  14. package/lib/commonjs/external/reanimated/moduleWrapper.js.map +1 -1
  15. package/lib/commonjs/external/reanimated/renderHelpers.js.map +1 -1
  16. package/lib/commonjs/external/reanimated/useAnimatedImageValue.d.ts +2 -0
  17. package/lib/commonjs/external/reanimated/useAnimatedImageValue.js +53 -0
  18. package/lib/commonjs/external/reanimated/useAnimatedImageValue.js.map +1 -0
  19. package/lib/commonjs/external/reanimated/useDerivedValueOnJS.d.ts +1 -2
  20. package/lib/commonjs/external/reanimated/useDerivedValueOnJS.js +2 -1
  21. package/lib/commonjs/external/reanimated/useDerivedValueOnJS.js.map +1 -1
  22. package/lib/commonjs/mock/index.js +8 -0
  23. package/lib/commonjs/mock/index.js.map +1 -1
  24. package/lib/commonjs/renderer/HostConfig.js +5 -5
  25. package/lib/commonjs/renderer/HostConfig.js.map +1 -1
  26. package/lib/commonjs/skia/core/AnimatedImage.d.ts +0 -1
  27. package/lib/commonjs/skia/core/AnimatedImage.js +1 -45
  28. package/lib/commonjs/skia/core/AnimatedImage.js.map +1 -1
  29. package/lib/commonjs/skia/types/Matrix.d.ts +4 -0
  30. package/lib/commonjs/skia/types/Matrix.js.map +1 -1
  31. package/lib/commonjs/skia/types/Path/Path.d.ts +10 -9
  32. package/lib/commonjs/skia/types/Path/Path.js.map +1 -1
  33. package/lib/commonjs/skia/web/JsiSkMatrix.d.ts +6 -0
  34. package/lib/commonjs/skia/web/JsiSkMatrix.js +33 -5
  35. package/lib/commonjs/skia/web/JsiSkMatrix.js.map +1 -1
  36. package/lib/commonjs/skia/web/JsiSkPath.d.ts +9 -9
  37. package/lib/commonjs/skia/web/JsiSkPath.js +15 -2
  38. package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
  39. package/lib/module/animation/functions/interpolatePaths.d.ts +1 -1
  40. package/lib/module/animation/functions/interpolatePaths.js +4 -4
  41. package/lib/module/animation/functions/interpolatePaths.js.map +1 -1
  42. package/lib/module/external/reanimated/index.d.ts +2 -1
  43. package/lib/module/external/reanimated/index.js +2 -1
  44. package/lib/module/external/reanimated/index.js.map +1 -1
  45. package/lib/module/external/reanimated/interpolators.d.ts +9 -0
  46. package/lib/module/external/reanimated/interpolators.js +34 -0
  47. package/lib/module/external/reanimated/interpolators.js.map +1 -0
  48. package/lib/module/external/reanimated/moduleWrapper.d.ts +8 -6
  49. package/lib/module/external/reanimated/moduleWrapper.js +4 -7
  50. package/lib/module/external/reanimated/moduleWrapper.js.map +1 -1
  51. package/lib/module/external/reanimated/renderHelpers.js.map +1 -1
  52. package/lib/module/external/reanimated/useAnimatedImageValue.d.ts +2 -0
  53. package/lib/module/external/reanimated/useAnimatedImageValue.js +41 -0
  54. package/lib/module/external/reanimated/useAnimatedImageValue.js.map +1 -0
  55. package/lib/module/external/reanimated/useDerivedValueOnJS.d.ts +1 -2
  56. package/lib/module/external/reanimated/useDerivedValueOnJS.js +3 -2
  57. package/lib/module/external/reanimated/useDerivedValueOnJS.js.map +1 -1
  58. package/lib/module/mock/index.js +8 -0
  59. package/lib/module/mock/index.js.map +1 -1
  60. package/lib/module/renderer/HostConfig.js +1 -1
  61. package/lib/module/renderer/HostConfig.js.map +1 -1
  62. package/lib/module/skia/core/AnimatedImage.d.ts +0 -1
  63. package/lib/module/skia/core/AnimatedImage.js +0 -40
  64. package/lib/module/skia/core/AnimatedImage.js.map +1 -1
  65. package/lib/module/skia/types/Matrix.d.ts +4 -0
  66. package/lib/module/skia/types/Matrix.js.map +1 -1
  67. package/lib/module/skia/types/Path/Path.d.ts +10 -9
  68. package/lib/module/skia/types/Path/Path.js.map +1 -1
  69. package/lib/module/skia/web/JsiSkMatrix.d.ts +6 -0
  70. package/lib/module/skia/web/JsiSkMatrix.js +33 -5
  71. package/lib/module/skia/web/JsiSkMatrix.js.map +1 -1
  72. package/lib/module/skia/web/JsiSkPath.d.ts +9 -9
  73. package/lib/module/skia/web/JsiSkPath.js +15 -2
  74. package/lib/module/skia/web/JsiSkPath.js.map +1 -1
  75. package/lib/typescript/jestEnv.d.mts +5 -0
  76. package/lib/typescript/jestSetup.d.mts +1 -0
  77. package/lib/typescript/src/animation/functions/interpolatePaths.d.ts +1 -1
  78. package/lib/typescript/src/external/reanimated/index.d.ts +2 -1
  79. package/lib/typescript/src/external/reanimated/interpolators.d.ts +9 -0
  80. package/lib/typescript/src/external/reanimated/moduleWrapper.d.ts +8 -6
  81. package/lib/typescript/src/external/reanimated/useAnimatedImageValue.d.ts +2 -0
  82. package/lib/typescript/src/external/reanimated/useDerivedValueOnJS.d.ts +1 -2
  83. package/lib/typescript/src/skia/core/AnimatedImage.d.ts +0 -1
  84. package/lib/typescript/src/skia/types/Matrix.d.ts +4 -0
  85. package/lib/typescript/src/skia/types/Path/Path.d.ts +10 -9
  86. package/lib/typescript/src/skia/web/JsiSkMatrix.d.ts +6 -0
  87. package/lib/typescript/src/skia/web/JsiSkPath.d.ts +9 -9
  88. package/package.json +4 -3
  89. package/src/animation/functions/interpolatePaths.ts +7 -4
  90. package/src/external/reanimated/index.ts +2 -1
  91. package/src/external/reanimated/interpolators.ts +89 -0
  92. package/src/external/reanimated/moduleWrapper.ts +33 -16
  93. package/src/external/reanimated/renderHelpers.ts +2 -2
  94. package/src/external/reanimated/useAnimatedImageValue.ts +51 -0
  95. package/src/external/reanimated/useDerivedValueOnJS.ts +4 -3
  96. package/src/mock/index.ts +5 -0
  97. package/src/renderer/HostConfig.ts +1 -1
  98. package/src/skia/core/AnimatedImage.ts +0 -47
  99. package/src/skia/types/Matrix.ts +4 -0
  100. package/src/skia/types/Path/Path.ts +10 -9
  101. package/src/skia/web/JsiSkMatrix.ts +33 -27
  102. package/src/skia/web/JsiSkPath.ts +15 -2
  103. package/globalJestSetup.js +0 -6
  104. package/lib/commonjs/external/reanimated/useSharedValueEffect.d.ts +0 -8
  105. package/lib/commonjs/external/reanimated/useSharedValueEffect.js +0 -49
  106. package/lib/commonjs/external/reanimated/useSharedValueEffect.js.map +0 -1
  107. package/lib/module/external/reanimated/useSharedValueEffect.d.ts +0 -8
  108. package/lib/module/external/reanimated/useSharedValueEffect.js +0 -39
  109. package/lib/module/external/reanimated/useSharedValueEffect.js.map +0 -1
  110. package/lib/typescript/globalJestSetup.d.ts +0 -2
  111. package/lib/typescript/src/external/reanimated/useSharedValueEffect.d.ts +0 -8
  112. package/src/external/reanimated/useSharedValueEffect.ts +0 -55
@@ -0,0 +1,9 @@
1
+ import type { ExtrapolationType, SharedValue } from "react-native-reanimated";
2
+ import type { SkPath, SkPoint } from "../../skia/types";
3
+ export declare const notifyChange: (value: SharedValue<unknown>) => void;
4
+ export declare const useClock: () => SharedValue<number>;
5
+ export declare const usePathInterpolation: (value: SharedValue<number>, input: number[], outputRange: SkPath[], options?: ExtrapolationType) => SharedValue<SkPath>;
6
+ export declare const useVectorInterpolation: (value: SharedValue<number>, input: number[], outputRange: SkPoint[], options?: ExtrapolationType) => SharedValue<{
7
+ x: number;
8
+ y: number;
9
+ }>;
@@ -1,10 +1,12 @@
1
- import type { SharedValueType } from "../../renderer/processors/Animations";
1
+ import type { DependencyList } from "react";
2
+ import type { FrameCallback, FrameInfo, SharedValue } from "react-native-reanimated";
2
3
  export declare const HAS_REANIMATED2: boolean;
3
4
  export declare const HAS_REANIMATED3: boolean;
4
5
  export declare function throwOnMissingReanimated(): void;
5
- export declare const useSharedValue: any;
6
- export declare const useFrameCallback: (...args: any[]) => any;
7
- export declare const startMapper: any;
8
- export declare const stopMapper: any;
6
+ export declare const useSharedValue: <T>(init: T, oneWayReadsOnly?: boolean) => SharedValue<T>;
7
+ export declare const useFrameCallback: (callback: (frameInfo: FrameInfo) => void, autostart?: boolean) => FrameCallback;
8
+ export declare const startMapper: (worklet: () => void, inputs?: unknown[], outputs?: unknown[]) => number;
9
+ export declare const stopMapper: (mapperID: number) => void;
9
10
  export declare const runOnJS: any;
10
- export declare const isSharedValue: <T>(value: unknown) => value is SharedValueType<T>;
11
+ export declare const useAnimatedReaction: <T>(prepare: () => T, react: (v: T) => void, dependencies?: DependencyList) => void;
12
+ export declare const isSharedValue: <T>(value: unknown) => value is SharedValue<T>;
@@ -0,0 +1,2 @@
1
+ import type { DataSourceParam, SkImage } from "../../skia/types";
2
+ export declare const useAnimatedImageValue: (source: DataSourceParam) => import("react-native-reanimated").SharedValue<SkImage | null>;
@@ -1,2 +1 @@
1
- import { type DependencyList } from "react";
2
- export declare const useDerivedValueOnJS: (fn: () => any, deps?: DependencyList) => any;
1
+ export declare const useDerivedValueOnJS: (fn: () => any, deps: unknown[]) => import("react-native-reanimated").SharedValue<any>;
@@ -3,4 +3,3 @@ import type { DataSourceParam } from "../types";
3
3
  * Returns a Skia Animated Image object
4
4
  * */
5
5
  export declare const useAnimatedImage: (source: DataSourceParam, onError?: ((err: Error) => void) | undefined) => import("../types").SkAnimatedImage | null;
6
- export declare const useAnimatedImageValue: (source: DataSourceParam) => any;
@@ -18,6 +18,10 @@ export interface SkMatrix extends SkJSIInstance<"Matrix"> {
18
18
  scale: (x: number, y?: number) => SkMatrix;
19
19
  skew: (x: number, y: number) => SkMatrix;
20
20
  rotate: (theta: number) => SkMatrix;
21
+ postTranslate: (x: number, y: number) => SkMatrix;
22
+ postScale: (x: number, y?: number) => SkMatrix;
23
+ postSkew: (x: number, y: number) => SkMatrix;
24
+ postRotate: (theta: number) => SkMatrix;
21
25
  identity: () => SkMatrix;
22
26
  get: () => number[];
23
27
  }
@@ -167,7 +167,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
167
167
  * Sets FillType, the rule used to fill Path.
168
168
  * @param fill
169
169
  */
170
- setFillType(fill: FillType): void;
170
+ setFillType(fill: FillType): SkPath;
171
171
  /**
172
172
  * Specifies whether Path is volatile; whether it will be altered or discarded
173
173
  * by the caller after it is drawn. Path by default have volatile set false.
@@ -176,7 +176,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
176
176
  * Mark unchanging Path non-volatile to improve repeated rendering.
177
177
  * @param volatile
178
178
  */
179
- setIsVolatile(volatile: boolean): void;
179
+ setIsVolatile(volatile: boolean): SkPath;
180
180
  /**
181
181
  * Turns this path into the filled equivalent of the stroked path. Returns false if the operation
182
182
  * fails (e.g. the path is a hairline).
@@ -188,13 +188,13 @@ export interface SkPath extends SkJSIInstance<"Path"> {
188
188
  * Appends CLOSE_VERB to Path. A closed contour connects the first and last point
189
189
  * with a line, forming a continuous loop.
190
190
  */
191
- close(): void;
191
+ close(): SkPath;
192
192
  /**
193
193
  * Sets Path to its initial state.
194
194
  * Removes verb array, point array, and weights, and sets FillType to Winding.
195
195
  * Internal storage associated with Path is released
196
196
  */
197
- reset(): void;
197
+ reset(): SkPath;
198
198
  /**
199
199
  * Sets Path to its initial state.
200
200
  * Removes verb array, point array, and weights, and sets FillType to Winding.
@@ -202,7 +202,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
202
202
  * Use rewind() instead of reset() if Path storage will be reused and performance
203
203
  * is critical.
204
204
  */
205
- rewind(): void;
205
+ rewind(): SkPath;
206
206
  /**
207
207
  * Returns minimum and maximum axes values of the lines and curves in Path.
208
208
  * Returns (0, 0, 0, 0) if Path contains no points.
@@ -330,7 +330,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
330
330
  reference to SkPath
331
331
  example: https://fiddle.skia.org/c/@Path_quadTo
332
332
  */
333
- quadTo(x1: number, y1: number, x2: number, y2: number): void;
333
+ quadTo(x1: number, y1: number, x2: number, y2: number): SkPath;
334
334
  /**
335
335
  * Adds Rect to Path, appending kMove_Verb, three kLine_Verb, and kClose_Verb,
336
336
  * starting with top-left corner of Rect; followed by top-right, bottom-right,
@@ -340,7 +340,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
340
340
  * @param rect
341
341
  * @param isCCW
342
342
  */
343
- addRect(rect: SkRect, isCCW?: boolean): void;
343
+ addRect(rect: SkRect, isCCW?: boolean): SkPath;
344
344
  /**
345
345
  * Adds rrect to Path, creating a new closed contour.
346
346
  * Returns the modified path for easier chaining.
@@ -440,7 +440,7 @@ export interface SkPath extends SkJSIInstance<"Path"> {
440
440
  /**
441
441
  * Transforms the path by the specified matrix.
442
442
  */
443
- transform(m3: SkMatrix): void;
443
+ transform(m3: SkMatrix): SkPath;
444
444
  /**
445
445
  * Interpolates between Path with point array of equal size.
446
446
  * Copy verb array and weights to result, and set result path to a weighted
@@ -457,10 +457,11 @@ export interface SkPath extends SkJSIInstance<"Path"> {
457
457
  * @param ending path to interpolate with
458
458
  * @param weight contribution of this path, and
459
459
  * one minus contribution of ending path
460
+ * @param output path to be replaced with the interpolated averages
460
461
  * @return Path replaced by interpolated averages or null if
461
462
  * not interpolatable
462
463
  * */
463
- interpolate(end: SkPath, weight: number): SkPath | null;
464
+ interpolate(end: SkPath, weight: number, output?: SkPath): SkPath | null;
464
465
  /** Returns true if Path contain equal verbs and equal weights.
465
466
  * @param compare path to compare
466
467
  * @return true if Path can be interpolated equivalent
@@ -3,12 +3,18 @@ import type { SkMatrix } from "../types";
3
3
  import { HostObject } from "./Host";
4
4
  export declare class JsiSkMatrix extends HostObject<Matrix3x3, "Matrix"> implements SkMatrix {
5
5
  constructor(CanvasKit: CanvasKit, ref: Matrix3x3);
6
+ private preMultiply;
7
+ private postMultiply;
6
8
  dispose: () => void;
7
9
  concat(matrix: SkMatrix): this;
8
10
  translate(x: number, y: number): this;
11
+ postTranslate(x: number, y: number): this;
9
12
  scale(x: number, y?: number): this;
13
+ postScale(x: number, y?: number): this;
10
14
  skew(x: number, y: number): this;
15
+ postSkew(x: number, y: number): this;
11
16
  rotate(value: number): this;
17
+ postRotate(value: number): this;
12
18
  identity(): this;
13
19
  get(): number[];
14
20
  }
@@ -21,12 +21,12 @@ export declare class JsiSkPath extends HostObject<Path, "Path"> implements SkPat
21
21
  rMoveTo(x: number, y: number): this;
22
22
  rLineTo(x: number, y: number): this;
23
23
  rQuadTo(x1: number, y1: number, x2: number, y2: number): this;
24
- setFillType(fill: FillType): void;
25
- setIsVolatile(volatile: boolean): void;
24
+ setFillType(fill: FillType): this;
25
+ setIsVolatile(volatile: boolean): this;
26
26
  stroke(opts?: StrokeOpts): this | null;
27
- close(): void;
28
- reset(): void;
29
- rewind(): void;
27
+ close(): this;
28
+ reset(): this;
29
+ rewind(): this;
30
30
  computeTightBounds(): SkRect;
31
31
  arcToOval(oval: SkRect, startAngleInDegrees: number, sweepAngleInDegrees: number, forceMoveTo: boolean): this;
32
32
  arcToRotated(rx: number, ry: number, xAxisRotateInDegrees: number, useSmallArc: boolean, isCCW: boolean, x: number, y: number): this;
@@ -39,8 +39,8 @@ export declare class JsiSkPath extends HostObject<Path, "Path"> implements SkPat
39
39
  equals(other: SkPath): boolean;
40
40
  getBounds(): JsiSkRect;
41
41
  getFillType(): number;
42
- quadTo(x1: number, y1: number, x2: number, y2: number): void;
43
- addRect(rect: SkRect, isCCW?: boolean): void;
42
+ quadTo(x1: number, y1: number, x2: number, y2: number): this;
43
+ addRect(rect: SkRect, isCCW?: boolean): this;
44
44
  addRRect(rrect: SkRRect, isCCW?: boolean): this;
45
45
  getPoint(index: number): JsiSkPoint;
46
46
  isEmpty(): boolean;
@@ -51,8 +51,8 @@ export declare class JsiSkPath extends HostObject<Path, "Path"> implements SkPat
51
51
  simplify(): boolean;
52
52
  toSVGString(): string;
53
53
  trim(start: number, stop: number, isComplement: boolean): this | null;
54
- transform(m3: SkMatrix): void;
55
- interpolate(end: SkPath, t: number): JsiSkPath | null;
54
+ transform(m3: SkMatrix): this;
55
+ interpolate(end: SkPath, t: number, output?: SkPath): SkPath | JsiSkPath | null;
56
56
  isInterpolatable(path2: SkPath): boolean;
57
57
  toCmds(): PathCommand[];
58
58
  }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "setup-skia-web": "./scripts/setup-canvaskit.js"
8
8
  },
9
9
  "title": "React Native Skia",
10
- "version": "0.1.214",
10
+ "version": "0.1.215",
11
11
  "description": "High-performance React Native Graphics using Skia",
12
12
  "main": "lib/module/index.js",
13
13
  "files": [
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "devDependencies": {
85
85
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
86
- "@types/jest": "^28.1.6",
86
+ "@types/jest": "29.5.6",
87
87
  "@types/pixelmatch": "^5.2.4",
88
88
  "@types/pngjs": "^6.0.1",
89
89
  "@types/react-native": "0.70.6",
@@ -92,13 +92,14 @@
92
92
  "eslint": "8.21.0",
93
93
  "eslint-config-react-native-wcandillon": "3.9.0",
94
94
  "eslint-plugin-reanimated": "2.0.0",
95
- "jest": "28.1.3",
95
+ "jest": "29.6.4",
96
96
  "merge-dirs": "^0.2.1",
97
97
  "pixelmatch": "^5.3.0",
98
98
  "pngjs": "^6.0.0",
99
99
  "react": "18.1.0",
100
100
  "react-native": "0.71.7",
101
101
  "react-native-builder-bob": "^0.18.2",
102
+ "react-native-reanimated": "^3.5.4",
102
103
  "ts-jest": "^28.0.7",
103
104
  "typescript": "4.8.3",
104
105
  "ws": "^8.11.0"
@@ -9,11 +9,12 @@ const lerp = (
9
9
  from: number,
10
10
  to: number,
11
11
  p1: SkPath,
12
- p2: SkPath
12
+ p2: SkPath,
13
+ output?: SkPath
13
14
  ) => {
14
15
  "worklet";
15
16
  const t = (value - from) / (to - from);
16
- return p2.interpolate(p1, t)!;
17
+ return p2.interpolate(p1, t, output)!;
17
18
  };
18
19
 
19
20
  /**
@@ -36,7 +37,8 @@ export const interpolatePaths = (
36
37
  value: number,
37
38
  input: number[],
38
39
  outputRange: SkPath[],
39
- options?: ExtrapolationType
40
+ options?: ExtrapolationType,
41
+ output?: SkPath
40
42
  ) => {
41
43
  "worklet";
42
44
  const extrapolation = validateInterpolationOptions(options);
@@ -84,6 +86,7 @@ export const interpolatePaths = (
84
86
  input[i],
85
87
  input[i + 1],
86
88
  outputRange[i],
87
- outputRange[i + 1]
89
+ outputRange[i + 1],
90
+ output
88
91
  );
89
92
  };
@@ -1,3 +1,4 @@
1
- export * from "./useSharedValueEffect";
1
+ export * from "./useAnimatedImageValue";
2
2
  export * from "./useDerivedValueOnJS";
3
3
  export * from "./renderHelpers";
4
+ export * from "./interpolators";
@@ -0,0 +1,89 @@
1
+ import type { ExtrapolationType, SharedValue } from "react-native-reanimated";
2
+ import { useMemo } from "react";
3
+
4
+ import type { SkPath, SkPoint } from "../../skia/types";
5
+ import { interpolatePaths, interpolateVector } from "../../animation";
6
+ import { Skia } from "../../skia";
7
+
8
+ import {
9
+ useAnimatedReaction,
10
+ useFrameCallback,
11
+ useSharedValue,
12
+ } from "./moduleWrapper";
13
+
14
+ export const notifyChange = (value: SharedValue<unknown>) => {
15
+ "worklet";
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ (value as any)._value = value.value;
18
+ };
19
+
20
+ export const useClock = () => {
21
+ const clock = useSharedValue(0);
22
+ useFrameCallback((info) => {
23
+ clock.value = info.timeSinceFirstFrame;
24
+ });
25
+ return clock;
26
+ };
27
+
28
+ /**
29
+ * @worklet
30
+ */
31
+ type Interpolator<T> = (
32
+ value: number,
33
+ input: number[],
34
+ output: T[],
35
+ options: ExtrapolationType,
36
+ result: T
37
+ ) => T;
38
+
39
+ const useInterpolator = <T>(
40
+ factory: () => T,
41
+ value: SharedValue<number>,
42
+ interpolator: Interpolator<T>,
43
+ input: number[],
44
+ output: T[],
45
+ options?: ExtrapolationType
46
+ ) => {
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ const init = useMemo(() => factory(), []);
49
+ const result = useSharedValue(init);
50
+ useAnimatedReaction(
51
+ () => value.value,
52
+ (val) => {
53
+ result.value = interpolator(val, input, output, options, result.value);
54
+ notifyChange(result);
55
+ },
56
+ [input, output, options]
57
+ );
58
+ return result;
59
+ };
60
+
61
+ export const usePathInterpolation = (
62
+ value: SharedValue<number>,
63
+ input: number[],
64
+ outputRange: SkPath[],
65
+ options?: ExtrapolationType
66
+ ) =>
67
+ useInterpolator(
68
+ () => Skia.Path.Make(),
69
+ value,
70
+ interpolatePaths,
71
+ input,
72
+ outputRange,
73
+ options
74
+ );
75
+
76
+ export const useVectorInterpolation = (
77
+ value: SharedValue<number>,
78
+ input: number[],
79
+ outputRange: SkPoint[],
80
+ options?: ExtrapolationType
81
+ ) =>
82
+ useInterpolator(
83
+ () => Skia.Point(0, 0),
84
+ value,
85
+ interpolateVector,
86
+ input,
87
+ outputRange,
88
+ options
89
+ );
@@ -1,7 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { useMemo } from "react";
3
-
4
- import type { SharedValueType } from "../../renderer/processors/Animations";
2
+ import type { DependencyList } from "react";
3
+ import type {
4
+ FrameCallback,
5
+ FrameInfo,
6
+ SharedValue,
7
+ } from "react-native-reanimated";
5
8
 
6
9
  // This one is needed for the deprecated useSharedValue function
7
10
  // We can remove it once we remove the deprecation
@@ -13,9 +16,7 @@ let reanimatedVersion: string;
13
16
 
14
17
  try {
15
18
  Reanimated2 = require("react-native-reanimated");
16
- reanimatedVersion =
17
- // eslint-disable-next-line import/extensions
18
- require("react-native-reanimated/package.json").version;
19
+ reanimatedVersion = require("react-native-reanimated/package.json").version;
19
20
  if (
20
21
  reanimatedVersion &&
21
22
  (reanimatedVersion >= "3.0.0" || reanimatedVersion.includes("3.0.0-"))
@@ -36,18 +37,34 @@ export function throwOnMissingReanimated() {
36
37
  }
37
38
  }
38
39
 
39
- export const useSharedValue =
40
- Reanimated2?.useSharedValue ||
41
- ((value: number) => useMemo(() => ({ value }), [value]));
42
- export const useFrameCallback: (...args: any[]) => any =
43
- Reanimated2?.useFrameCallback || throwOnMissingReanimated;
40
+ export const useSharedValue: <T>(
41
+ init: T,
42
+ oneWayReadsOnly?: boolean
43
+ ) => SharedValue<T> = Reanimated2?.useSharedValue || throwOnMissingReanimated;
44
+
45
+ export const useFrameCallback: (
46
+ callback: (frameInfo: FrameInfo) => void,
47
+ autostart?: boolean
48
+ ) => FrameCallback = Reanimated2?.useFrameCallback || throwOnMissingReanimated;
49
+
50
+ export const startMapper: (
51
+ worklet: () => void,
52
+ inputs?: unknown[],
53
+ outputs?: unknown[]
54
+ ) => number = Reanimated2?.startMapper || throwOnMissingReanimated;
55
+
56
+ export const stopMapper: (mapperID: number) => void =
57
+ Reanimated2?.stopMapper || throwOnMissingReanimated;
44
58
 
45
- export const startMapper = Reanimated2?.startMapper || throwOnMissingReanimated;
46
- export const stopMapper = Reanimated2?.stopMapper || throwOnMissingReanimated;
47
59
  export const runOnJS = Reanimated2?.runOnJS || throwOnMissingReanimated;
48
- export const isSharedValue = <T>(
49
- value: unknown
50
- ): value is SharedValueType<T> => {
60
+
61
+ export const useAnimatedReaction: <T>(
62
+ prepare: () => T,
63
+ react: (v: T) => void,
64
+ dependencies?: DependencyList
65
+ ) => void = Reanimated2?.useAnimatedReaction || throwOnMissingReanimated;
66
+
67
+ export const isSharedValue = <T>(value: unknown): value is SharedValue<T> => {
51
68
  return (
52
69
  !!value &&
53
70
  (Reanimated3
@@ -44,7 +44,7 @@ function bindReanimatedProps2(
44
44
  const sharedValues = Object.values(reanimatedProps);
45
45
  const previousMapperId = _bindings.get(node);
46
46
  if (previousMapperId !== undefined) {
47
- stopMapper(previousMapperId);
47
+ stopMapper(previousMapperId as number);
48
48
  }
49
49
  if (sharedValues.length > 0) {
50
50
  const viewId = container.getNativeId();
@@ -85,7 +85,7 @@ export function bindReanimatedProps(
85
85
  const sharedValues = Object.values(reanimatedProps);
86
86
  const previousMapperId = _bindings.get(node);
87
87
  if (previousMapperId !== undefined) {
88
- stopMapper(previousMapperId);
88
+ stopMapper(previousMapperId as number);
89
89
  }
90
90
  if (sharedValues.length > 0) {
91
91
  const viewId = container.getNativeId();
@@ -0,0 +1,51 @@
1
+ import type { FrameInfo } from "react-native-reanimated";
2
+
3
+ import { useAnimatedImage } from "../../skia/core/AnimatedImage";
4
+ import type { DataSourceParam, SkImage } from "../../skia/types";
5
+
6
+ import {
7
+ throwOnMissingReanimated,
8
+ useFrameCallback,
9
+ useSharedValue,
10
+ } from "./moduleWrapper";
11
+
12
+ const DEFAULT_FRAME_DURATION = 60;
13
+
14
+ export const useAnimatedImageValue = (source: DataSourceParam) => {
15
+ throwOnMissingReanimated();
16
+ const currentFrame = useSharedValue<null | SkImage>(null);
17
+ const lastTimestamp = useSharedValue(0);
18
+ const animatedImage = useAnimatedImage(source, (err) => {
19
+ console.error(err);
20
+ throw new Error(`Could not load animated image - got '${err.message}'`);
21
+ });
22
+ const frameDuration =
23
+ animatedImage?.currentFrameDuration() || DEFAULT_FRAME_DURATION;
24
+
25
+ useFrameCallback((frameInfo: FrameInfo) => {
26
+ if (!animatedImage) {
27
+ currentFrame.value = null;
28
+ return;
29
+ }
30
+
31
+ const { timestamp } = frameInfo;
32
+ const elapsed = timestamp - lastTimestamp.value;
33
+
34
+ // Check if it's time to switch frames based on GIF frame duration
35
+ if (elapsed < frameDuration) {
36
+ return;
37
+ }
38
+
39
+ // Update the current frame
40
+ animatedImage.decodeNextFrame();
41
+ if (currentFrame.value) {
42
+ currentFrame.value.dispose();
43
+ }
44
+ currentFrame.value = animatedImage.getCurrentFrame();
45
+
46
+ // Update the last timestamp
47
+ lastTimestamp.value = timestamp;
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, true);
50
+ return currentFrame;
51
+ };
@@ -1,4 +1,4 @@
1
- import { useEffect, type DependencyList } from "react";
1
+ import { useEffect, useMemo } from "react";
2
2
 
3
3
  import {
4
4
  useSharedValue,
@@ -10,9 +10,10 @@ import {
10
10
  export const useDerivedValueOnJS = (
11
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
12
  fn: () => any,
13
- deps?: DependencyList
13
+ deps: unknown[]
14
14
  ) => {
15
- const value = useSharedValue(fn());
15
+ const init = useMemo(() => fn(), [fn]);
16
+ const value = useSharedValue(init);
16
17
  useEffect(() => {
17
18
  const mapperId = startMapper(() => {
18
19
  "worklet";
package/src/mock/index.ts CHANGED
@@ -6,6 +6,7 @@ import { ValueApi } from "../values/web";
6
6
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
7
  const Noop: () => any = () => undefined;
8
8
  const NoopValue = () => ({ current: 0 });
9
+ const NoopSharedValue = () => ({ value: 0 });
9
10
 
10
11
  export const Mock = (CanvasKit: CanvasKit) => {
11
12
  global.SkiaApi = JsiSkApi(CanvasKit);
@@ -21,6 +22,7 @@ export const Mock = (CanvasKit: CanvasKit) => {
21
22
  ...require("../dom/nodes"),
22
23
  // We could use the real Canvas if we mock the SkiaView component for node
23
24
  Canvas: Noop,
25
+ // Skia Animations
24
26
  useValue: NoopValue,
25
27
  useComputedValue: NoopValue,
26
28
  useTouchHandler: Noop,
@@ -29,6 +31,9 @@ export const Mock = (CanvasKit: CanvasKit) => {
29
31
  useSpring: NoopValue,
30
32
  useClockValue: NoopValue,
31
33
  useValueEffect: Noop,
34
+ // Reanimated hooks
35
+ useClock: NoopSharedValue,
36
+ usePathInterpolation: NoopSharedValue,
32
37
  useRawData: Noop,
33
38
  useData: Noop,
34
39
  useFont: () => Skia.Font(undefined, 0),
@@ -7,7 +7,7 @@ import type { SkiaValue } from "../values";
7
7
  import {
8
8
  bindReanimatedProps,
9
9
  extractReanimatedProps,
10
- } from "../external/reanimated";
10
+ } from "../external/reanimated/renderHelpers";
11
11
 
12
12
  import type { Container } from "./Container";
13
13
  import { createNode } from "./HostComponents";
@@ -1,8 +1,3 @@
1
- import {
2
- throwOnMissingReanimated,
3
- useFrameCallback,
4
- useSharedValue,
5
- } from "../../external/reanimated/moduleWrapper";
6
1
  import { Skia } from "../Skia";
7
2
  import type { DataSourceParam } from "../types";
8
3
 
@@ -19,45 +14,3 @@ export const useAnimatedImage = (
19
14
  source: DataSourceParam,
20
15
  onError?: (err: Error) => void
21
16
  ) => useRawData(source, animatedImgFactory, onError);
22
-
23
- const DEFAULT_FRAME_DURATION = 60;
24
-
25
- export const useAnimatedImageValue = (source: DataSourceParam) => {
26
- throwOnMissingReanimated();
27
- const currentFrame = useSharedValue(null);
28
- const lastTimestamp = useSharedValue(0);
29
- const animatedImage = useAnimatedImage(source, (err) => {
30
- console.error(err);
31
- throw new Error(`Could not load animated image - got '${err.message}'`);
32
- });
33
- const frameDuration =
34
- animatedImage?.currentFrameDuration() || DEFAULT_FRAME_DURATION;
35
-
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
- useFrameCallback((frameInfo: any) => {
38
- if (!animatedImage) {
39
- currentFrame.value = null;
40
- return;
41
- }
42
-
43
- const { timestamp } = frameInfo;
44
- const elapsed = timestamp - lastTimestamp.value;
45
-
46
- // Check if it's time to switch frames based on GIF frame duration
47
- if (elapsed < frameDuration) {
48
- return;
49
- }
50
-
51
- // Update the current frame
52
- animatedImage.decodeNextFrame();
53
- if (currentFrame.value) {
54
- currentFrame.value.dispose();
55
- }
56
- currentFrame.value = animatedImage.getCurrentFrame();
57
-
58
- // Update the last timestamp
59
- lastTimestamp.value = timestamp;
60
- // eslint-disable-next-line react-hooks/exhaustive-deps
61
- }, true);
62
- return currentFrame;
63
- };
@@ -21,6 +21,10 @@ export interface SkMatrix extends SkJSIInstance<"Matrix"> {
21
21
  scale: (x: number, y?: number) => SkMatrix;
22
22
  skew: (x: number, y: number) => SkMatrix;
23
23
  rotate: (theta: number) => SkMatrix;
24
+ postTranslate: (x: number, y: number) => SkMatrix;
25
+ postScale: (x: number, y?: number) => SkMatrix;
26
+ postSkew: (x: number, y: number) => SkMatrix;
27
+ postRotate: (theta: number) => SkMatrix;
24
28
  identity: () => SkMatrix;
25
29
  get: () => number[];
26
30
  }