@shopify/react-native-skia 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/android/CMakeLists.txt +1 -1
  2. package/android/cpp/rnskia-android/OpenGLWindowContext.h +1 -1
  3. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +1 -1
  4. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +1 -1
  5. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +1 -1
  6. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +1 -1
  7. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureViewManager.java +6 -0
  8. package/apple/MetalContext.h +2 -2
  9. package/apple/MetalWindowContext.h +2 -2
  10. package/apple/MetalWindowContext.mm +7 -4
  11. package/apple/RNSkApplePlatformContext.mm +1 -1
  12. package/apple/RNSkAppleView.h +7 -1
  13. package/apple/RNSkMetalCanvasProvider.h +4 -1
  14. package/apple/RNSkMetalCanvasProvider.mm +9 -4
  15. package/apple/SkiaPictureView.mm +4 -0
  16. package/apple/SkiaUIView.h +1 -0
  17. package/apple/SkiaUIView.mm +9 -0
  18. package/cpp/api/JsiSkImage.h +1 -1
  19. package/cpp/api/JsiSkSurface.h +1 -1
  20. package/cpp/api/JsiSkiaContext.h +1 -1
  21. package/cpp/api/recorder/Convertor.h +16 -0
  22. package/cpp/api/recorder/ImageFilters.h +20 -0
  23. package/cpp/api/recorder/Paint.h +4 -0
  24. package/cpp/api/recorder/RNRecorder.h +6 -0
  25. package/cpp/rnskia/{DawnContext.h → RNDawnContext.h} +3 -3
  26. package/cpp/rnskia/{DawnWindowContext.cpp → RNDawnWindowContext.cpp} +3 -3
  27. package/cpp/rnskia/{DawnWindowContext.h → RNDawnWindowContext.h} +2 -2
  28. package/cpp/rnskia/RNSkPlatformContext.h +1 -1
  29. package/lib/commonjs/dom/types/Drawings.d.ts +4 -1
  30. package/lib/commonjs/dom/types/Drawings.js.map +1 -1
  31. package/lib/commonjs/dom/types/NodeType.d.ts +2 -1
  32. package/lib/commonjs/dom/types/NodeType.js +2 -0
  33. package/lib/commonjs/dom/types/NodeType.js.map +1 -1
  34. package/lib/commonjs/renderer/Canvas.d.ts +2 -1
  35. package/lib/commonjs/renderer/Canvas.js +2 -0
  36. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  37. package/lib/commonjs/renderer/__tests__/e2e/ImageFilter.spec.d.ts +1 -0
  38. package/lib/commonjs/renderer/components/ImageFilter.d.ts +4 -0
  39. package/lib/commonjs/renderer/components/ImageFilter.js +13 -0
  40. package/lib/commonjs/renderer/components/ImageFilter.js.map +1 -0
  41. package/lib/commonjs/renderer/components/index.d.ts +1 -0
  42. package/lib/commonjs/renderer/components/index.js +11 -0
  43. package/lib/commonjs/renderer/components/index.js.map +1 -1
  44. package/lib/commonjs/skia/types/Matrix4.d.ts +4 -0
  45. package/lib/commonjs/skia/types/Matrix4.js +18 -1
  46. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  47. package/lib/commonjs/sksg/Elements.d.ts +2 -1
  48. package/lib/commonjs/sksg/Elements.js.map +1 -1
  49. package/lib/commonjs/sksg/Node.d.ts +1 -1
  50. package/lib/commonjs/sksg/Node.js +1 -1
  51. package/lib/commonjs/sksg/Node.js.map +1 -1
  52. package/lib/commonjs/sksg/Recorder/Player.js +9 -3
  53. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  54. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js +11 -1
  55. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  56. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  57. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  58. package/lib/module/dom/types/Drawings.d.ts +4 -1
  59. package/lib/module/dom/types/Drawings.js.map +1 -1
  60. package/lib/module/dom/types/NodeType.d.ts +2 -1
  61. package/lib/module/dom/types/NodeType.js +2 -0
  62. package/lib/module/dom/types/NodeType.js.map +1 -1
  63. package/lib/module/renderer/Canvas.d.ts +2 -1
  64. package/lib/module/renderer/Canvas.js +2 -0
  65. package/lib/module/renderer/Canvas.js.map +1 -1
  66. package/lib/module/renderer/__tests__/e2e/ImageFilter.spec.d.ts +1 -0
  67. package/lib/module/renderer/components/ImageFilter.d.ts +4 -0
  68. package/lib/module/renderer/components/ImageFilter.js +5 -0
  69. package/lib/module/renderer/components/ImageFilter.js.map +1 -0
  70. package/lib/module/renderer/components/index.d.ts +1 -0
  71. package/lib/module/renderer/components/index.js +1 -0
  72. package/lib/module/renderer/components/index.js.map +1 -1
  73. package/lib/module/skia/types/Matrix4.d.ts +4 -0
  74. package/lib/module/skia/types/Matrix4.js +16 -0
  75. package/lib/module/skia/types/Matrix4.js.map +1 -1
  76. package/lib/module/sksg/Elements.d.ts +2 -1
  77. package/lib/module/sksg/Elements.js.map +1 -1
  78. package/lib/module/sksg/Node.d.ts +1 -1
  79. package/lib/module/sksg/Node.js +1 -1
  80. package/lib/module/sksg/Node.js.map +1 -1
  81. package/lib/module/sksg/Recorder/Player.js +9 -3
  82. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  83. package/lib/module/sksg/Recorder/commands/ImageFilters.js +11 -1
  84. package/lib/module/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  85. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  86. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  87. package/lib/typescript/lib/commonjs/renderer/Canvas.d.ts +2 -1
  88. package/lib/typescript/lib/commonjs/renderer/components/ImageFilter.d.ts +2 -0
  89. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +1 -0
  90. package/lib/typescript/lib/module/mock/index.d.ts +2 -0
  91. package/lib/typescript/lib/module/renderer/Canvas.d.ts +2 -1
  92. package/lib/typescript/lib/module/renderer/components/ImageFilter.d.ts +2 -0
  93. package/lib/typescript/lib/module/renderer/components/index.d.ts +1 -0
  94. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  95. package/lib/typescript/src/dom/types/Drawings.d.ts +4 -1
  96. package/lib/typescript/src/dom/types/NodeType.d.ts +2 -1
  97. package/lib/typescript/src/renderer/Canvas.d.ts +2 -1
  98. package/lib/typescript/src/renderer/__tests__/e2e/ImageFilter.spec.d.ts +1 -0
  99. package/lib/typescript/src/renderer/components/ImageFilter.d.ts +4 -0
  100. package/lib/typescript/src/renderer/components/index.d.ts +1 -0
  101. package/lib/typescript/src/skia/types/Matrix4.d.ts +4 -0
  102. package/lib/typescript/src/sksg/Elements.d.ts +2 -1
  103. package/lib/typescript/src/sksg/Node.d.ts +1 -1
  104. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  105. package/libs/android/arm64-v8a/libskia.a +0 -0
  106. package/libs/android/armeabi-v7a/libskia.a +0 -0
  107. package/libs/android/x86/libskia.a +0 -0
  108. package/libs/android/x86_64/libskia.a +0 -0
  109. package/libs/apple/libpathops.xcframework/Info.plist +15 -15
  110. package/libs/apple/libskia.xcframework/Info.plist +11 -11
  111. package/libs/apple/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  112. package/libs/apple/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  113. package/libs/apple/libskia.xcframework/macos-arm64_x86_64/libskia.a +0 -0
  114. package/libs/apple/libskia.xcframework/tvos-arm64_arm64e/libskia.a +0 -0
  115. package/libs/apple/libskia.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  116. package/libs/apple/libskottie.xcframework/Info.plist +16 -16
  117. package/libs/apple/libskparagraph.xcframework/Info.plist +8 -8
  118. package/libs/apple/libsksg.xcframework/Info.plist +6 -6
  119. package/libs/apple/libskshaper.xcframework/Info.plist +10 -10
  120. package/libs/apple/libskunicode_core.xcframework/Info.plist +10 -10
  121. package/libs/apple/libskunicode_libgrapheme.xcframework/Info.plist +14 -14
  122. package/libs/apple/libsvg.xcframework/Info.plist +15 -15
  123. package/package.json +1 -1
  124. package/react-native-skia.podspec +5 -5
  125. package/src/dom/types/Drawings.ts +5 -0
  126. package/src/dom/types/NodeType.ts +2 -0
  127. package/src/renderer/Canvas.tsx +3 -0
  128. package/src/renderer/__tests__/FitBox.spec.tsx +556 -4
  129. package/src/renderer/__tests__/e2e/ImageFilter.spec.tsx +99 -0
  130. package/src/renderer/__tests__/e2e/Paint.spec.tsx +18 -0
  131. package/src/renderer/__tests__/e2e/Skottie.spec.tsx +24 -1
  132. package/src/renderer/__tests__/setup.tsx +10 -0
  133. package/src/renderer/components/ImageFilter.tsx +8 -0
  134. package/src/renderer/components/index.ts +1 -0
  135. package/src/skia/types/Matrix4.ts +16 -0
  136. package/src/sksg/Elements.tsx +2 -0
  137. package/src/sksg/Node.ts +1 -0
  138. package/src/sksg/Recorder/Player.ts +7 -7
  139. package/src/sksg/Recorder/commands/ImageFilters.ts +11 -1
  140. package/src/specs/SkiaPictureViewNativeComponent.ts +1 -0
  141. /package/cpp/rnskia/{DawnUtils.h → RNDawnUtils.h} +0 -0
  142. /package/cpp/rnskia/{ImageProvider.h → RNImageProvider.h} +0 -0
  143. /package/cpp/rnskia/{WindowContext.h → RNWindowContext.h} +0 -0
@@ -9,6 +9,7 @@ import {
9
9
  LinearGradient,
10
10
  Paint,
11
11
  Path,
12
+ SweepGradient,
12
13
  } from "../../components";
13
14
  import { checkImage, docPath } from "../../../__tests__/setup";
14
15
  import { fitbox } from "../../components/shapes/FitBox";
@@ -210,4 +211,21 @@ describe("Paint", () => {
210
211
  );
211
212
  checkImage(result, docPath("paint/semi-transparent-circle.png"));
212
213
  });
214
+ it("test paint", async () => {
215
+ const { vec, Skia } = importSkia();
216
+ const strokeWidth = 10;
217
+ const { width, height } = surface;
218
+ const c = vec(width / 2, height / 2);
219
+ const r = (width - strokeWidth) / 2;
220
+ const path = Skia.Path.Make();
221
+ path.addCircle(c.x, c.y, r);
222
+ const result = await surface.draw(
223
+ <Path path={path} color="transparent">
224
+ <Paint style="stroke" strokeWidth={20} strokeCap="round">
225
+ <SweepGradient c={c} colors={["#64BC65", "#4488ff"]} />
226
+ </Paint>
227
+ </Path>
228
+ );
229
+ checkImage(result, docPath("paint/test-paint.png"));
230
+ });
213
231
  });
@@ -3,7 +3,7 @@ import React from "react";
3
3
 
4
4
  import { checkImage, docPath } from "../../../__tests__/setup";
5
5
  import { dataAssets, importSkia, surface } from "../setup";
6
- import { Group, Skottie } from "../../components";
6
+ import { Blur, Group, Paint, Skottie } from "../../components";
7
7
 
8
8
  const legoLoaderJSON = require("./setup/skottie/lego_loader.json");
9
9
  const drinksJSON = require("./setup/skottie/drinks.json");
@@ -30,6 +30,29 @@ describe("Skottie", () => {
30
30
  );
31
31
  checkImage(img, docPath("skottie/skottie-component-lego.png"));
32
32
  });
33
+ it("Should render Skottie component with raster effect", async () => {
34
+ const { Skia } = importSkia();
35
+ const source = JSON.stringify(legoLoaderJSON);
36
+ const legoAnimation = Skia.Skottie.Make(source);
37
+ // THIS IS FOR INTERNAL TESTING ONLY
38
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
+ // @ts-expect-error
40
+ legoAnimation.source = source;
41
+ // END OF INTERNAL TESTING ONLY
42
+ const img = await surface.draw(
43
+ <Group
44
+ transform={[{ scale: 0.5 }]}
45
+ layer={
46
+ <Paint>
47
+ <Blur blur={10} />
48
+ </Paint>
49
+ }
50
+ >
51
+ <Skottie animation={legoAnimation} frame={41} />
52
+ </Group>
53
+ );
54
+ checkImage(img, docPath("skottie/skottie-component-lego-blur.png"));
55
+ });
33
56
  it("Should render Skottie component with drinks animation", async () => {
34
57
  const { Skia } = importSkia();
35
58
  const source = JSON.stringify(drinksJSON);
@@ -174,6 +174,7 @@ export const importSkia = (): typeof SkiaExports => {
174
174
  const skia = require("../../skia");
175
175
  const renderer = require("../../renderer");
176
176
  const offscreen = require("../Offscreen");
177
+ const nodes = require("../../dom/nodes");
177
178
  // TODO: to remove
178
179
  const animation = require("../../animation");
179
180
  return {
@@ -181,6 +182,7 @@ export const importSkia = (): typeof SkiaExports => {
181
182
  ...renderer,
182
183
  ...animation,
183
184
  ...offscreen,
185
+ ...nodes,
184
186
  };
185
187
  };
186
188
 
@@ -322,6 +324,14 @@ const serializeSkOjects = (obj: any): any => {
322
324
  source: obj.source,
323
325
  assets: obj.assets,
324
326
  };
327
+ } else if (obj.__typename__ === "ImageFilter") {
328
+ if (!obj.source) {
329
+ throw new Error("ImageFilter must have a source");
330
+ }
331
+ return {
332
+ __typename__: "Function",
333
+ source: obj.source,
334
+ };
325
335
  }
326
336
  } else if (obj && typeof obj === "object") {
327
337
  const result = Object.keys(obj).reduce((acc, key) => {
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+
3
+ import type { ImageFilterProps } from "../../dom/types";
4
+ import type { SkiaProps } from "../processors";
5
+
6
+ export const ImageFilter = (props: SkiaProps<ImageFilterProps>) => {
7
+ return <skImageFilter {...props} />;
8
+ };
@@ -15,5 +15,6 @@ export * from "./Mask";
15
15
  export * from "./Paint";
16
16
  export * from "./Blend";
17
17
  export * from "./Skottie";
18
+ export * from "./ImageFilter";
18
19
 
19
20
  export * from "./paragraph";
@@ -354,6 +354,22 @@ export const convertToColumnMajor = (rowMajorMatrix: Matrix4) => {
354
354
  return colMajorMatrix as unknown as Matrix4;
355
355
  };
356
356
 
357
+ /**
358
+ * @worklet
359
+ */
360
+ export const convertToColumnMajor3 = (rowMajorMatrix: Matrix3 | number[]) => {
361
+ "worklet";
362
+
363
+ const colMajorMatrix = new Array<number>(9);
364
+ const size = 3;
365
+ for (let row = 0; row < size; row++) {
366
+ for (let col = 0; col < size; col++) {
367
+ colMajorMatrix[col * size + row] = rowMajorMatrix[row * size + col];
368
+ }
369
+ }
370
+ return colMajorMatrix as unknown as Matrix3;
371
+ };
372
+
357
373
  /**
358
374
  * @worklet
359
375
  */
@@ -52,6 +52,7 @@ import type {
52
52
  MorphologyImageFilterProps,
53
53
  BlendProps,
54
54
  SkottieProps,
55
+ ImageFilterProps,
55
56
  } from "../dom/types";
56
57
  import type { SkiaProps } from "../renderer";
57
58
 
@@ -89,6 +90,7 @@ declare module "react" {
89
90
  skBlurMaskFilter: SkiaProps<BlurMaskFilterProps>;
90
91
 
91
92
  // ImageFilters
93
+ skImageFilter: SkiaProps<ImageFilterProps>;
92
94
  skBlendImageFilter: SkiaProps<BlendImageFilterProps>;
93
95
  skBlurImageFilter: SkiaProps<BlurImageFilterProps>;
94
96
  skOffsetImageFilter: SkiaProps<OffsetImageFilterProps>;
package/src/sksg/Node.ts CHANGED
@@ -34,6 +34,7 @@ export const isPathEffect = (type: NodeType) => {
34
34
  export const isImageFilter = (type: NodeType) => {
35
35
  "worklet";
36
36
  return (
37
+ type === NodeType.ImageFilter ||
37
38
  type === NodeType.OffsetImageFilter ||
38
39
  type === NodeType.DisplacementMapImageFilter ||
39
40
  type === NodeType.BlurImageFilter ||
@@ -67,14 +67,14 @@ function play(ctx: DrawingContext, _command: Command) {
67
67
  if (command.props.paint) {
68
68
  ctx.paints.push(command.props.paint);
69
69
  } else {
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ const { standalone } = command as any;
70
72
  ctx.savePaint();
71
- setPaintProperties(
72
- ctx.Skia,
73
- ctx,
74
- command.props,
75
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
- (command as any).standalone
77
- );
73
+ if (standalone) {
74
+ const freshPaint = ctx.Skia.Paint();
75
+ ctx.paint.assign(freshPaint);
76
+ }
77
+ setPaintProperties(ctx.Skia, ctx, command.props, standalone);
78
78
  }
79
79
  } else if (isCommand(command, CommandType.RestorePaint)) {
80
80
  ctx.restorePaint();
@@ -5,6 +5,7 @@ import type {
5
5
  BlurMaskFilterProps,
6
6
  DisplacementMapImageFilterProps,
7
7
  DropShadowImageFilterProps,
8
+ ImageFilterProps,
8
9
  MorphologyImageFilterProps,
9
10
  OffsetImageFilterProps,
10
11
  RuntimeShaderImageFilterProps,
@@ -176,6 +177,12 @@ const declareRuntimeShaderImageFilter = (
176
177
  ctx.imageFilters.push(imgf);
177
178
  };
178
179
 
180
+ const declareImageFilter = (ctx: DrawingContext, props: ImageFilterProps) => {
181
+ "worklet";
182
+ const { filter } = props;
183
+ ctx.imageFilters.push(filter);
184
+ };
185
+
179
186
  export const composeImageFilters = (ctx: DrawingContext) => {
180
187
  "worklet";
181
188
  if (ctx.imageFilters.length > 1) {
@@ -207,6 +214,7 @@ export const isPushImageFilter = (
207
214
  };
208
215
 
209
216
  type Props = {
217
+ [NodeType.ImageFilter]: ImageFilterProps;
210
218
  [NodeType.OffsetImageFilter]: OffsetImageFilterProps;
211
219
  [NodeType.DisplacementMapImageFilter]: DisplacementMapImageFilterProps;
212
220
  [NodeType.BlurImageFilter]: BlurImageFilterProps;
@@ -235,7 +243,9 @@ export const pushImageFilter = (
235
243
  command: Command<CommandType.PushImageFilter>
236
244
  ) => {
237
245
  "worklet";
238
- if (isImageFilter(command, NodeType.BlurImageFilter)) {
246
+ if (isImageFilter(command, NodeType.ImageFilter)) {
247
+ declareImageFilter(ctx, command.props);
248
+ } else if (isImageFilter(command, NodeType.BlurImageFilter)) {
239
249
  declareBlurImageFilter(ctx, command.props);
240
250
  } else if (isImageFilter(command, NodeType.MorphologyImageFilter)) {
241
251
  declareMorphologyImageFilter(ctx, command.props);
@@ -4,6 +4,7 @@ import type { ViewProps } from "react-native";
4
4
  export interface NativeProps extends ViewProps {
5
5
  debug?: boolean;
6
6
  opaque?: boolean;
7
+ colorSpace?: string;
7
8
  }
8
9
 
9
10
  // eslint-disable-next-line import/no-default-export
File without changes