@shopify/react-native-skia 0.1.115 → 0.1.119

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 (217) hide show
  1. package/README.md +39 -2
  2. package/cpp/api/JsiSkApi.h +13 -9
  3. package/cpp/api/JsiSkCanvas.h +9 -1
  4. package/cpp/api/JsiSkPicture.h +71 -0
  5. package/cpp/api/JsiSkPictureFactory.h +50 -0
  6. package/cpp/api/JsiSkPictureRecorder.h +53 -0
  7. package/lib/commonjs/renderer/Canvas.js +22 -36
  8. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  9. package/lib/commonjs/renderer/HostConfig.js +3 -25
  10. package/lib/commonjs/renderer/HostConfig.js.map +1 -1
  11. package/lib/commonjs/renderer/components/{Defs.js → Drawing.js} +13 -12
  12. package/lib/commonjs/renderer/components/Drawing.js.map +1 -0
  13. package/lib/commonjs/renderer/components/Group.js +31 -20
  14. package/lib/commonjs/renderer/components/Group.js.map +1 -1
  15. package/lib/commonjs/renderer/components/Paint.js +1 -21
  16. package/lib/commonjs/renderer/components/Paint.js.map +1 -1
  17. package/lib/commonjs/renderer/components/Picture.js +35 -0
  18. package/lib/commonjs/renderer/components/Picture.js.map +1 -0
  19. package/lib/commonjs/renderer/components/imageFilters/InnerShadow.js +5 -34
  20. package/lib/commonjs/renderer/components/imageFilters/InnerShadow.js.map +1 -1
  21. package/lib/commonjs/renderer/components/imageFilters/{DropShadow.js → Shadow.js} +19 -8
  22. package/lib/commonjs/renderer/components/imageFilters/Shadow.js.map +1 -0
  23. package/lib/commonjs/renderer/components/imageFilters/index.js +4 -17
  24. package/lib/commonjs/renderer/components/imageFilters/index.js.map +1 -1
  25. package/lib/commonjs/renderer/components/index.js +17 -4
  26. package/lib/commonjs/renderer/components/index.js.map +1 -1
  27. package/lib/commonjs/renderer/components/maskFilters/Blur.js +1 -1
  28. package/lib/commonjs/renderer/components/maskFilters/Blur.js.map +1 -1
  29. package/lib/commonjs/renderer/components/shapes/Box.js +126 -0
  30. package/lib/commonjs/renderer/components/shapes/Box.js.map +1 -0
  31. package/lib/commonjs/renderer/components/shapes/FitBox.js +9 -5
  32. package/lib/commonjs/renderer/components/shapes/FitBox.js.map +1 -1
  33. package/lib/commonjs/renderer/components/shapes/index.js +13 -0
  34. package/lib/commonjs/renderer/components/shapes/index.js.map +1 -1
  35. package/lib/commonjs/renderer/index.js +13 -0
  36. package/lib/commonjs/renderer/index.js.map +1 -1
  37. package/lib/commonjs/renderer/nodes/Declaration.js +12 -1
  38. package/lib/commonjs/renderer/nodes/Declaration.js.map +1 -1
  39. package/lib/commonjs/renderer/nodes/Drawing.js +9 -24
  40. package/lib/commonjs/renderer/nodes/Drawing.js.map +1 -1
  41. package/lib/commonjs/renderer/nodes/Node.js +9 -16
  42. package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
  43. package/lib/commonjs/renderer/processors/Paint.js +24 -26
  44. package/lib/commonjs/renderer/processors/Paint.js.map +1 -1
  45. package/lib/commonjs/renderer/processors/math/Math.js +19 -1
  46. package/lib/commonjs/renderer/processors/math/Math.js.map +1 -1
  47. package/lib/commonjs/renderer/processors/math/Matrix3.js +11 -5
  48. package/lib/commonjs/renderer/processors/math/Matrix3.js.map +1 -1
  49. package/lib/commonjs/renderer/typeddash.js +26 -2
  50. package/lib/commonjs/renderer/typeddash.js.map +1 -1
  51. package/lib/commonjs/renderer/useContextBridge.js +35 -0
  52. package/lib/commonjs/renderer/useContextBridge.js.map +1 -0
  53. package/lib/commonjs/skia/Canvas.js.map +1 -1
  54. package/lib/commonjs/skia/Picture/Picture.js +6 -0
  55. package/lib/commonjs/skia/Picture/Picture.js.map +1 -0
  56. package/lib/commonjs/skia/Picture/PictureFactory.js +6 -0
  57. package/lib/commonjs/skia/Picture/PictureFactory.js.map +1 -0
  58. package/lib/commonjs/skia/Picture/PictureRecorder.js +6 -0
  59. package/lib/commonjs/skia/Picture/PictureRecorder.js.map +1 -0
  60. package/lib/commonjs/skia/Picture/index.js +58 -0
  61. package/lib/commonjs/skia/Picture/index.js.map +1 -0
  62. package/lib/commonjs/skia/Picture/usePicture.js +30 -0
  63. package/lib/commonjs/skia/Picture/usePicture.js.map +1 -0
  64. package/lib/commonjs/skia/Skia.js +2 -0
  65. package/lib/commonjs/skia/Skia.js.map +1 -1
  66. package/lib/commonjs/skia/index.js +28 -0
  67. package/lib/commonjs/skia/index.js.map +1 -1
  68. package/lib/commonjs/values/hooks/useDerivedValue.js +2 -2
  69. package/lib/commonjs/values/hooks/useDerivedValue.js.map +1 -1
  70. package/lib/commonjs/views/SkiaView.js +6 -44
  71. package/lib/commonjs/views/SkiaView.js.map +1 -1
  72. package/lib/commonjs/views/types.js.map +1 -1
  73. package/lib/module/renderer/Canvas.js +20 -32
  74. package/lib/module/renderer/Canvas.js.map +1 -1
  75. package/lib/module/renderer/HostConfig.js +2 -24
  76. package/lib/module/renderer/HostConfig.js.map +1 -1
  77. package/lib/module/renderer/components/Drawing.js +17 -0
  78. package/lib/module/renderer/components/Drawing.js.map +1 -0
  79. package/lib/module/renderer/components/Group.js +32 -22
  80. package/lib/module/renderer/components/Group.js.map +1 -1
  81. package/lib/module/renderer/components/Paint.js +2 -22
  82. package/lib/module/renderer/components/Paint.js.map +1 -1
  83. package/lib/module/renderer/components/Picture.js +21 -0
  84. package/lib/module/renderer/components/Picture.js.map +1 -0
  85. package/lib/module/renderer/components/imageFilters/InnerShadow.js +4 -26
  86. package/lib/module/renderer/components/imageFilters/InnerShadow.js.map +1 -1
  87. package/lib/module/renderer/components/imageFilters/{DropShadow.js → Shadow.js} +16 -6
  88. package/lib/module/renderer/components/imageFilters/Shadow.js.map +1 -0
  89. package/lib/module/renderer/components/imageFilters/index.js +1 -2
  90. package/lib/module/renderer/components/imageFilters/index.js.map +1 -1
  91. package/lib/module/renderer/components/index.js +2 -1
  92. package/lib/module/renderer/components/index.js.map +1 -1
  93. package/lib/module/renderer/components/maskFilters/Blur.js +1 -1
  94. package/lib/module/renderer/components/maskFilters/Blur.js.map +1 -1
  95. package/lib/module/renderer/components/shapes/Box.js +102 -0
  96. package/lib/module/renderer/components/shapes/Box.js.map +1 -0
  97. package/lib/module/renderer/components/shapes/FitBox.js +5 -4
  98. package/lib/module/renderer/components/shapes/FitBox.js.map +1 -1
  99. package/lib/module/renderer/components/shapes/index.js +1 -0
  100. package/lib/module/renderer/components/shapes/index.js.map +1 -1
  101. package/lib/module/renderer/index.js +1 -0
  102. package/lib/module/renderer/index.js.map +1 -1
  103. package/lib/module/renderer/nodes/Declaration.js +4 -0
  104. package/lib/module/renderer/nodes/Declaration.js.map +1 -1
  105. package/lib/module/renderer/nodes/Drawing.js +8 -21
  106. package/lib/module/renderer/nodes/Drawing.js.map +1 -1
  107. package/lib/module/renderer/nodes/Node.js +9 -15
  108. package/lib/module/renderer/nodes/Node.js.map +1 -1
  109. package/lib/module/renderer/processors/Paint.js +22 -21
  110. package/lib/module/renderer/processors/Paint.js.map +1 -1
  111. package/lib/module/renderer/processors/math/Math.js +15 -0
  112. package/lib/module/renderer/processors/math/Math.js.map +1 -1
  113. package/lib/module/renderer/processors/math/Matrix3.js +6 -2
  114. package/lib/module/renderer/processors/math/Matrix3.js.map +1 -1
  115. package/lib/module/renderer/typeddash.js +21 -0
  116. package/lib/module/renderer/typeddash.js.map +1 -1
  117. package/lib/module/renderer/useContextBridge.js +21 -0
  118. package/lib/module/renderer/useContextBridge.js.map +1 -0
  119. package/lib/module/skia/Canvas.js.map +1 -1
  120. package/lib/module/skia/Picture/Picture.js +2 -0
  121. package/lib/module/skia/Picture/Picture.js.map +1 -0
  122. package/lib/module/skia/Picture/PictureFactory.js +2 -0
  123. package/lib/module/skia/Picture/PictureFactory.js.map +1 -0
  124. package/lib/module/skia/Picture/PictureRecorder.js +2 -0
  125. package/lib/module/skia/Picture/PictureRecorder.js.map +1 -0
  126. package/lib/module/skia/Picture/index.js +5 -0
  127. package/lib/module/skia/Picture/index.js.map +1 -0
  128. package/lib/module/skia/Picture/usePicture.js +19 -0
  129. package/lib/module/skia/Picture/usePicture.js.map +1 -0
  130. package/lib/module/skia/Skia.js +2 -0
  131. package/lib/module/skia/Skia.js.map +1 -1
  132. package/lib/module/skia/index.js +2 -0
  133. package/lib/module/skia/index.js.map +1 -1
  134. package/lib/module/values/hooks/useDerivedValue.js +1 -1
  135. package/lib/module/values/hooks/useDerivedValue.js.map +1 -1
  136. package/lib/module/views/SkiaView.js +6 -44
  137. package/lib/module/views/SkiaView.js.map +1 -1
  138. package/lib/module/views/types.js.map +1 -1
  139. package/lib/typescript/src/renderer/Canvas.d.ts +5 -10
  140. package/lib/typescript/src/renderer/components/Drawing.d.ts +7 -0
  141. package/lib/typescript/src/renderer/components/Picture.d.ts +6 -0
  142. package/lib/typescript/src/renderer/components/imageFilters/InnerShadow.d.ts +3 -12
  143. package/lib/typescript/src/renderer/components/imageFilters/{DropShadow.d.ts → Shadow.d.ts} +3 -2
  144. package/lib/typescript/src/renderer/components/imageFilters/index.d.ts +1 -2
  145. package/lib/typescript/src/renderer/components/index.d.ts +2 -1
  146. package/lib/typescript/src/renderer/components/shapes/Box.d.ts +23 -0
  147. package/lib/typescript/src/renderer/components/shapes/FitBox.d.ts +9 -0
  148. package/lib/typescript/src/renderer/components/shapes/index.d.ts +1 -0
  149. package/lib/typescript/src/renderer/index.d.ts +1 -0
  150. package/lib/typescript/src/renderer/nodes/Declaration.d.ts +3 -0
  151. package/lib/typescript/src/renderer/nodes/Drawing.d.ts +2 -2
  152. package/lib/typescript/src/renderer/nodes/Node.d.ts +2 -2
  153. package/lib/typescript/src/renderer/processors/Paint.d.ts +2 -2
  154. package/lib/typescript/src/renderer/processors/math/Math.d.ts +14 -0
  155. package/lib/typescript/src/renderer/processors/math/Matrix3.d.ts +1 -0
  156. package/lib/typescript/src/renderer/typeddash.d.ts +1 -0
  157. package/lib/typescript/src/renderer/useContextBridge.d.ts +5 -0
  158. package/lib/typescript/src/skia/Canvas.d.ts +6 -0
  159. package/lib/typescript/src/skia/Picture/Picture.d.ts +26 -0
  160. package/lib/typescript/src/skia/Picture/PictureFactory.d.ts +8 -0
  161. package/lib/typescript/src/skia/Picture/PictureRecorder.d.ts +15 -0
  162. package/lib/typescript/src/skia/Picture/index.d.ts +4 -0
  163. package/lib/typescript/src/skia/Picture/usePicture.d.ts +11 -0
  164. package/lib/typescript/src/skia/Skia.d.ts +5 -0
  165. package/lib/typescript/src/skia/index.d.ts +2 -0
  166. package/lib/typescript/src/views/SkiaView.d.ts +28 -13
  167. package/lib/typescript/src/views/types.d.ts +0 -23
  168. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  169. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  170. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  171. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  172. package/libs/ios/libsvg.xcframework/Info.plist +5 -5
  173. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  174. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  175. package/package.json +7 -7
  176. package/src/renderer/Canvas.tsx +14 -30
  177. package/src/renderer/HostConfig.ts +2 -20
  178. package/src/renderer/components/Drawing.tsx +16 -0
  179. package/src/renderer/components/Group.tsx +44 -27
  180. package/src/renderer/components/Paint.tsx +5 -35
  181. package/src/renderer/components/Picture.tsx +17 -0
  182. package/src/renderer/components/imageFilters/InnerShadow.tsx +33 -47
  183. package/src/renderer/components/imageFilters/Shadow.tsx +39 -0
  184. package/src/renderer/components/imageFilters/index.ts +1 -2
  185. package/src/renderer/components/index.ts +2 -1
  186. package/src/renderer/components/maskFilters/Blur.tsx +1 -1
  187. package/src/renderer/components/shapes/Box.tsx +98 -0
  188. package/src/renderer/components/shapes/FitBox.tsx +6 -4
  189. package/src/renderer/components/shapes/index.ts +1 -0
  190. package/src/renderer/index.ts +1 -0
  191. package/src/renderer/nodes/Declaration.tsx +14 -0
  192. package/src/renderer/nodes/Drawing.tsx +16 -26
  193. package/src/renderer/nodes/Node.ts +9 -12
  194. package/src/renderer/processors/Paint.ts +34 -31
  195. package/src/renderer/processors/math/Math.ts +16 -0
  196. package/src/renderer/processors/math/Matrix3.ts +35 -31
  197. package/src/renderer/typeddash.ts +18 -0
  198. package/src/renderer/useContextBridge.tsx +21 -0
  199. package/src/skia/Canvas.ts +7 -0
  200. package/src/skia/Picture/Picture.ts +34 -0
  201. package/src/skia/Picture/PictureFactory.ts +9 -0
  202. package/src/skia/Picture/PictureRecorder.ts +18 -0
  203. package/src/skia/Picture/index.ts +4 -0
  204. package/src/skia/Picture/usePicture.ts +28 -0
  205. package/src/skia/Skia.ts +5 -0
  206. package/src/skia/index.ts +2 -0
  207. package/src/values/hooks/useDerivedValue.ts +1 -1
  208. package/src/views/SkiaView.tsx +31 -41
  209. package/src/views/types.ts +0 -24
  210. package/lib/commonjs/renderer/components/Defs.js.map +0 -1
  211. package/lib/commonjs/renderer/components/imageFilters/DropShadow.js.map +0 -1
  212. package/lib/module/renderer/components/Defs.js +0 -16
  213. package/lib/module/renderer/components/Defs.js.map +0 -1
  214. package/lib/module/renderer/components/imageFilters/DropShadow.js.map +0 -1
  215. package/lib/typescript/src/renderer/components/Defs.d.ts +0 -5
  216. package/src/renderer/components/Defs.tsx +0 -19
  217. package/src/renderer/components/imageFilters/DropShadow.tsx +0 -31
@@ -1,15 +1,8 @@
1
1
  import type { ReactNode } from "react";
2
2
  import React, { useRef, useMemo, forwardRef, useImperativeHandle } from "react";
3
3
 
4
- import type { SkPaint, SkImageFilter } from "../../skia";
5
- import {
6
- isShader,
7
- isMaskFilter,
8
- isColorFilter,
9
- Skia,
10
- isImageFilter,
11
- isPathEffect,
12
- } from "../../skia";
4
+ import type { SkPaint } from "../../skia";
5
+ import { Skia } from "../../skia";
13
6
  import type { CustomPaintProps, AnimatedProps } from "../processors";
14
7
  import { processPaint } from "../processors";
15
8
  import { createDeclaration } from "../nodes";
@@ -26,32 +19,9 @@ export const Paint = forwardRef<SkPaint, AnimatedProps<PaintProps>>(
26
19
  useImperativeHandle(ref, () => paint, [paint]);
27
20
  const onDeclare = useMemo(
28
21
  () =>
29
- createDeclaration<PaintProps>((paintProps, children, ctx) => {
30
- processPaint(paint, ctx.opacity, paintProps);
31
- children.forEach((child) => {
32
- if (isShader(child)) {
33
- paint.setShader(child);
34
- } else if (isMaskFilter(child)) {
35
- paint.setMaskFilter(child);
36
- } else if (isColorFilter(child)) {
37
- paint.setColorFilter(child);
38
- } else if (isPathEffect(child)) {
39
- paint.setPathEffect(child);
40
- }
41
- });
42
- const filters = children.filter(isImageFilter);
43
- if (filters.length > 0) {
44
- paint.setImageFilter(
45
- filters
46
- .reverse()
47
- .reduce<SkImageFilter | null>(
48
- Skia.ImageFilter.MakeCompose,
49
- null
50
- )
51
- );
52
- }
53
- return paint;
54
- }),
22
+ createDeclaration<PaintProps>((paintProps, children, ctx) =>
23
+ processPaint(paint, ctx.opacity, paintProps, children)
24
+ ),
55
25
  [paint]
56
26
  );
57
27
  return <skDeclaration onDeclare={onDeclare} {...props} />;
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+
3
+ import type { SkPicture } from "../../skia";
4
+ import { createDrawing } from "../nodes/Drawing";
5
+
6
+ export interface PictureProps {
7
+ picture: SkPicture;
8
+ }
9
+
10
+ const onDraw = createDrawing<PictureProps>((ctx, { picture }) => {
11
+ const { canvas } = ctx;
12
+ canvas.drawPicture(picture);
13
+ });
14
+
15
+ export const Picture = (props: PictureProps) => {
16
+ return <skDrawing onDraw={onDraw} {...props} skipProcessing />;
17
+ };
@@ -1,50 +1,36 @@
1
- import React from "react";
1
+ import type { SkColor } from "../../../skia";
2
+ import { BlendMode, Skia, TileMode } from "../../../skia";
3
+ import type { SkImageFilter } from "../../../skia/ImageFilter/ImageFilter";
2
4
 
3
- import { BlendMode, Skia, TileMode, processColor } from "../../../skia";
4
- import { createDeclaration } from "../../nodes/Declaration";
5
- import type { AnimatedProps } from "../../processors";
6
- import type { Color } from "../../../skia";
7
-
8
- import { getInput } from "./getInput";
9
-
10
- export interface InnerShadowProps {
11
- dx: number;
12
- dy: number;
13
- blur: number;
14
- color: Color;
15
- shadowOnly?: boolean;
16
- inner?: boolean;
17
- }
18
-
19
- const onDeclare = createDeclaration<InnerShadowProps>(
20
- ({ dx, dy, blur, color, shadowOnly }, children, { opacity }) => {
21
- const input = getInput(children);
22
- const cl = processColor(color, opacity);
23
- const sourceGraphic = Skia.ImageFilter.MakeColorFilter(
24
- Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.Dst),
25
- null
26
- );
27
- const sourceAlpha = Skia.ImageFilter.MakeColorFilter(
28
- Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.SrcIn),
29
- null
30
- );
31
- const f1 = Skia.ImageFilter.MakeColorFilter(
32
- Skia.ColorFilter.MakeBlend(cl, BlendMode.SrcOut),
33
- null
34
- );
35
- const f2 = Skia.ImageFilter.MakeOffset(dx, dy, f1);
36
- const f3 = Skia.ImageFilter.MakeBlur(blur, blur, TileMode.Decal, f2);
37
- const f4 = Skia.ImageFilter.MakeBlend(BlendMode.SrcIn, sourceAlpha, f3);
38
- if (shadowOnly) {
39
- return f4;
40
- }
41
- return Skia.ImageFilter.MakeCompose(
42
- input,
43
- Skia.ImageFilter.MakeBlend(BlendMode.SrcOver, sourceGraphic, f4)
44
- );
5
+ export const MakeInnerShadow = (
6
+ shadowOnly: boolean | undefined,
7
+ dx: number,
8
+ dy: number,
9
+ sigmaX: number,
10
+ sigmaY: number,
11
+ color: SkColor,
12
+ input: SkImageFilter | null
13
+ ) => {
14
+ const sourceGraphic = Skia.ImageFilter.MakeColorFilter(
15
+ Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.Dst),
16
+ null
17
+ );
18
+ const sourceAlpha = Skia.ImageFilter.MakeColorFilter(
19
+ Skia.ColorFilter.MakeBlend(0xff000000, BlendMode.SrcIn),
20
+ null
21
+ );
22
+ const f1 = Skia.ImageFilter.MakeColorFilter(
23
+ Skia.ColorFilter.MakeBlend(color, BlendMode.SrcOut),
24
+ null
25
+ );
26
+ const f2 = Skia.ImageFilter.MakeOffset(dx, dy, f1);
27
+ const f3 = Skia.ImageFilter.MakeBlur(sigmaX, sigmaY, TileMode.Decal, f2);
28
+ const f4 = Skia.ImageFilter.MakeBlend(BlendMode.SrcIn, sourceAlpha, f3);
29
+ if (shadowOnly) {
30
+ return f4;
45
31
  }
46
- );
47
-
48
- export const InnerShadow = (props: AnimatedProps<InnerShadowProps>) => {
49
- return <skDeclaration onDeclare={onDeclare} {...props} />;
32
+ return Skia.ImageFilter.MakeCompose(
33
+ input,
34
+ Skia.ImageFilter.MakeBlend(BlendMode.SrcOver, sourceGraphic, f4)
35
+ );
50
36
  };
@@ -0,0 +1,39 @@
1
+ import React from "react";
2
+
3
+ import { Skia } from "../../../skia";
4
+ import { createDeclaration } from "../../nodes/Declaration";
5
+ import type { AnimatedProps } from "../../processors/Animations/Animations";
6
+ import type { Color } from "../../../skia/Color";
7
+ import { processColor } from "../../../skia/Color";
8
+
9
+ import { getInput } from "./getInput";
10
+ import { MakeInnerShadow } from "./InnerShadow";
11
+
12
+ export interface ShadowProps {
13
+ dx: number;
14
+ dy: number;
15
+ blur: number;
16
+ color: Color;
17
+ inner?: boolean;
18
+ shadowOnly?: boolean;
19
+ }
20
+
21
+ const onDeclare = createDeclaration<ShadowProps>(
22
+ ({ dx, dy, blur, color: cl, shadowOnly, inner }, children, { opacity }) => {
23
+ const input = getInput(children);
24
+ const color = processColor(cl, opacity);
25
+ let factory;
26
+ if (inner) {
27
+ factory = MakeInnerShadow.bind(null, shadowOnly);
28
+ } else {
29
+ factory = shadowOnly
30
+ ? Skia.ImageFilter.MakeDropShadowOnly
31
+ : Skia.ImageFilter.MakeDropShadow;
32
+ }
33
+ return factory(dx, dy, blur, blur, color, input);
34
+ }
35
+ );
36
+
37
+ export const Shadow = (props: AnimatedProps<ShadowProps>) => {
38
+ return <skDeclaration onDeclare={onDeclare} {...props} />;
39
+ };
@@ -1,6 +1,5 @@
1
1
  export * from "./Blur";
2
2
  export * from "./Offset";
3
3
  export * from "./DisplacementMap";
4
- export * from "./DropShadow";
5
- export * from "./InnerShadow";
4
+ export * from "./Shadow";
6
5
  export * from "./Morphology";
@@ -8,10 +8,11 @@ export * from "./maskFilters";
8
8
  export * from "./imageFilters";
9
9
  export * from "./pathEffects";
10
10
  export * from "../processors";
11
+ export * from "./Picture";
11
12
 
12
13
  export * from "./Group";
13
14
  export * from "./Mask";
14
15
  export * from "./Paint";
15
16
  export * from "./Compose";
16
17
  export * from "./Blend";
17
- export * from "./Defs";
18
+ export * from "./Drawing";
@@ -29,5 +29,5 @@ export const BlurMask = (props: AnimatedProps<BlurMaskProps>) => {
29
29
 
30
30
  BlurMask.defaultProps = {
31
31
  style: "normal",
32
- respectCTM: false,
32
+ respectCTM: true,
33
33
  };
@@ -0,0 +1,98 @@
1
+ import React from "react";
2
+
3
+ import type { Color, SkRRect } from "../../../skia";
4
+ import { ClipOp, BlurStyle, Skia, processColor } from "../../../skia";
5
+ import { createDrawing } from "../../nodes";
6
+ import type { AnimatedProps, CustomPaintProps } from "../../processors";
7
+ import { add, vec, rrect } from "../../processors";
8
+ import { rect, isRRect } from "../../processors/Rects";
9
+ import { createDeclaration } from "../../nodes/Declaration";
10
+ import type { SkJSIInstance } from "../../../skia/JsiInstance";
11
+ import type { SkRect } from "../../../skia/Rect";
12
+
13
+ const inflate = (box: SkRRect, dx: number, dy: number, tx = 0, ty = 0) =>
14
+ rrect(
15
+ rect(
16
+ box.rect.x - dx + tx,
17
+ box.rect.y - dy + ty,
18
+ box.rect.width + 2 * dx,
19
+ box.rect.height + 2 * dy
20
+ ),
21
+ box.rx + dx,
22
+ box.ry + dy
23
+ );
24
+
25
+ const deflate = (box: SkRRect, dx: number, dy: number, tx = 0, ty = 0) =>
26
+ inflate(box, -dx, -dy, tx, ty);
27
+
28
+ interface BoxShadowProps {
29
+ dx?: number;
30
+ dy?: number;
31
+ spread?: number;
32
+ blur: number;
33
+ color?: Color;
34
+ inner?: boolean;
35
+ }
36
+
37
+ interface BoxShadowDecl extends BoxShadowProps, SkJSIInstance<"BoxShadow"> {}
38
+
39
+ const onDeclare = createDeclaration<BoxShadowProps>(
40
+ ({ dx, dy, spread, blur, color, inner }) => {
41
+ return { dx, dy, spread, blur, color, inner, __typename__: "BoxShadow" };
42
+ }
43
+ );
44
+
45
+ export const BoxShadow = (props: AnimatedProps<BoxShadowProps>) => {
46
+ return <skDeclaration onDeclare={onDeclare} {...props} />;
47
+ };
48
+
49
+ const isBoxShadow = (s: SkJSIInstance<string>): s is BoxShadowDecl =>
50
+ s.__typename__ === "BoxShadow";
51
+
52
+ interface BoxProps extends CustomPaintProps {
53
+ box: SkRRect | SkRect;
54
+ }
55
+
56
+ const onDraw = createDrawing<BoxProps>((ctx, { box: defaultBox }, node) => {
57
+ const box = isRRect(defaultBox) ? defaultBox : rrect(defaultBox, 0, 0);
58
+ const { canvas, paint, opacity } = ctx;
59
+ const shadows = node.visit(ctx).filter<BoxShadowDecl>(isBoxShadow);
60
+ shadows
61
+ .filter((shadow) => !shadow.inner)
62
+ .map((shadow) => {
63
+ const { color = "black", blur, spread = 0, dx = 0, dy = 0 } = shadow;
64
+ const lPaint = Skia.Paint();
65
+ lPaint.setColor(processColor(color, opacity));
66
+ lPaint.setMaskFilter(
67
+ Skia.MaskFilter.MakeBlur(BlurStyle.Normal, blur, true)
68
+ );
69
+ canvas.drawRRect(inflate(box, spread, spread, dx, dy), lPaint);
70
+ });
71
+ canvas.drawRRect(box, paint);
72
+
73
+ shadows
74
+ .filter((shadow) => shadow.inner)
75
+ .map((shadow) => {
76
+ const { color = "black", blur, spread = 0, dx = 0, dy = 0 } = shadow;
77
+ const delta = add(vec(10, 10), vec(Math.abs(dx), Math.abs(dy)));
78
+ canvas.save();
79
+ canvas.clipRRect(box, ClipOp.Intersect, false);
80
+ const lPaint = Skia.Paint();
81
+ lPaint.setColor(processColor(color, opacity));
82
+ lPaint.setMaskFilter(
83
+ Skia.MaskFilter.MakeBlur(BlurStyle.Normal, blur, true)
84
+ );
85
+ const inner = deflate(box, spread, spread, dx, dy);
86
+ const outer = inflate(box, delta.x, delta.y);
87
+ canvas.drawDRRect(outer, inner, lPaint);
88
+ canvas.restore();
89
+ });
90
+ });
91
+
92
+ export const Box = (props: AnimatedProps<BoxProps>) => {
93
+ return <skDrawing onDraw={onDraw} {...props} />;
94
+ };
95
+
96
+ Box.defaultProps = {
97
+ shadows: [],
98
+ };
@@ -13,11 +13,13 @@ interface FitProps {
13
13
  children: ReactNode | ReactNode[];
14
14
  }
15
15
 
16
+ export const fitbox = (fit: Fit, src: SkRect, dst: SkRect) => {
17
+ const rects = fitRects(fit, src, dst);
18
+ return rect2rect(rects.src, rects.dst);
19
+ };
20
+
16
21
  export const FitBox = ({ fit, src, dst, children }: FitProps) => {
17
- const transform = useMemo(() => {
18
- const rects = fitRects(fit, src, dst);
19
- return rect2rect(rects.src, rects.dst);
20
- }, [dst, fit, src]);
22
+ const transform = useMemo(() => fitbox(fit, src, dst), [dst, fit, src]);
21
23
  return <Group transform={transform}>{children}</Group>;
22
24
  };
23
25
 
@@ -10,3 +10,4 @@ export * from "./Patch";
10
10
  export * from "./Vertices";
11
11
  export * from "./Fill";
12
12
  export * from "./FitBox";
13
+ export * from "./Box";
@@ -1,3 +1,4 @@
1
1
  export * from "./Canvas";
2
2
  export * from "./components";
3
3
  export * from "./nodes";
4
+ export * from "./useContextBridge";
@@ -1,3 +1,6 @@
1
+ import type { DependencyList } from "react";
2
+ import { useCallback } from "react";
3
+
1
4
  import type { DrawingContext } from "../DrawingContext";
2
5
  import type { SkJSIInstance } from "../../skia/JsiInstance";
3
6
  import type { AnimatedProps } from "../processors";
@@ -18,6 +21,17 @@ export const createDeclaration = <T,>(
18
21
  cb: DeclarationCallback<T>
19
22
  ): DeclarationCallback<T> => cb;
20
23
 
24
+ export const useDeclaration = <P,>(
25
+ cb: DeclarationCallback<P>,
26
+ deps?: DependencyList
27
+ ) =>
28
+ // eslint-disable-next-line react-hooks/exhaustive-deps
29
+ useCallback(cb, deps ?? []);
30
+
31
+ export const isDeclarationNode = (
32
+ node: Node
33
+ ): node is DeclarationNode<unknown> => node instanceof DeclarationNode;
34
+
21
35
  export interface DeclarationProps<P> {
22
36
  onDeclare: DeclarationCallback<P>;
23
37
  }
@@ -1,8 +1,8 @@
1
- import type { ReactNode } from "react";
2
- import React from "react";
1
+ import type { DependencyList, ReactNode } from "react";
2
+ import { useCallback } from "react";
3
3
 
4
4
  import type { DrawingContext } from "../DrawingContext";
5
- import { processPaint, selectPaint } from "../processors";
5
+ import { processPaint } from "../processors";
6
6
  import type { AnimatedProps } from "../processors/Animations/Animations";
7
7
  import { materialize } from "../processors/Animations/Animations";
8
8
  import { isPaint } from "../../skia";
@@ -21,16 +21,16 @@ type OnDrawCallback<P> = (ctx: DrawingContext, props: P, node: Node<P>) => void;
21
21
  export const createDrawing = <P,>(cb: OnDrawCallback<P>): DrawingCallback<P> =>
22
22
  cb;
23
23
 
24
+ export const useDrawing = <P,>(cb: OnDrawCallback<P>, deps?: DependencyList) =>
25
+ // eslint-disable-next-line react-hooks/exhaustive-deps
26
+ useCallback(cb, deps ?? []);
27
+
24
28
  export type DrawingProps<T> = {
25
29
  onDraw: DrawingCallback<T>;
26
30
  skipProcessing?: boolean;
27
31
  children?: ReactNode | ReactNode[];
28
32
  };
29
33
 
30
- export const Drawing = <P,>(props: DrawingProps<P>) => {
31
- return <skDrawing {...props} />;
32
- };
33
-
34
34
  export class DrawingNode<P> extends Node<P> {
35
35
  onDraw: DrawingCallback<P>;
36
36
  skipProcessing: boolean;
@@ -51,25 +51,15 @@ export class DrawingNode<P> extends Node<P> {
51
51
  if (this.skipProcessing) {
52
52
  this.onDraw(ctx, drawingProps, this);
53
53
  } else {
54
- const selectedPaint = selectPaint(ctx.paint, drawingProps);
55
- processPaint(selectedPaint, ctx.opacity, drawingProps);
56
- // to draw only once:
57
- // onDraw({ ...ctx, paint: selectedPaint }, children);
58
- [
59
- selectedPaint,
60
- ...this.children
61
- .map((child) => {
62
- //if (child.type === NodeType.Declaration) {
63
- const ret = child.draw(ctx);
64
- if (ret) {
65
- return ret;
66
- }
67
- //}
68
- return null;
69
- })
70
- .filter(isPaint),
71
- ].forEach((paint) => {
72
- this.onDraw({ ...ctx, paint }, drawingProps, this);
54
+ const declarations = this.visit(ctx);
55
+ const paint = processPaint(
56
+ ctx.paint.copy(),
57
+ ctx.opacity,
58
+ drawingProps,
59
+ declarations
60
+ );
61
+ [paint, ...declarations.filter(isPaint)].forEach((currentPaint) => {
62
+ this.onDraw({ ...ctx, paint: currentPaint }, drawingProps, this);
73
63
  });
74
64
  }
75
65
  }
@@ -1,4 +1,3 @@
1
- import { isPaint } from "../../skia";
2
1
  import type { SkJSIInstance } from "../../skia/JsiInstance";
3
2
  import type { DependencyManager } from "../DependencyManager";
4
3
  import type { DrawingContext } from "../DrawingContext";
@@ -15,7 +14,7 @@ export abstract class Node<P = unknown> {
15
14
  readonly children: Node[] = [];
16
15
  _props: AnimatedProps<P>;
17
16
  memoizable = false;
18
- memoized = false;
17
+ memoized: DeclarationResult | null = null;
19
18
  parent?: Node;
20
19
  depMgr: DependencyManager;
21
20
 
@@ -38,21 +37,19 @@ export abstract class Node<P = unknown> {
38
37
  return this._props;
39
38
  }
40
39
 
41
- visit(ctx: DrawingContext) {
40
+ visit(ctx: DrawingContext, children?: Node[]) {
42
41
  const returnedValues: Exclude<DeclarationResult, null>[] = [];
43
- let currentCtx = ctx;
44
- this.children.forEach((child) => {
42
+ (children ?? this.children).forEach((child) => {
45
43
  if (!child.memoized) {
46
- const ret = child.draw(currentCtx);
44
+ const ret = child.draw(ctx);
47
45
  if (ret) {
48
- if (isPaint(ret)) {
49
- currentCtx = { ...currentCtx, paint: ret };
50
- }
51
46
  returnedValues.push(ret);
47
+ if (child.memoizable) {
48
+ child.memoized = ret;
49
+ }
52
50
  }
53
- if (child.memoizable) {
54
- child.memoized = true;
55
- }
51
+ } else {
52
+ returnedValues.push(child.memoized);
56
53
  }
57
54
  });
58
55
  return returnedValues;
@@ -6,14 +6,22 @@ import {
6
6
  StrokeJoin,
7
7
  StrokeCap,
8
8
  processColor,
9
+ isShader,
10
+ isMaskFilter,
11
+ isColorFilter,
12
+ isPathEffect,
13
+ isImageFilter,
14
+ Skia,
9
15
  } from "../../skia";
10
- import type { SkPaint, Color } from "../../skia";
16
+ import type { SkPaint, Color, SkImageFilter } from "../../skia";
17
+ import type { DeclarationResult } from "../nodes";
11
18
  export type SkEnum<T> = Uncapitalize<keyof T extends string ? keyof T : never>;
12
19
 
13
20
  export interface ChildrenProps {
14
21
  children?: ReactNode | ReactNode[];
15
22
  }
16
23
 
24
+ // TODO: rename to paint props?
17
25
  export interface CustomPaintProps extends ChildrenProps {
18
26
  paint?: RefObject<SkPaint>;
19
27
  color?: Color;
@@ -33,6 +41,7 @@ export const processPaint = (
33
41
  paint: SkPaint,
34
42
  currentOpacity: number,
35
43
  {
44
+ paint: paintRef,
36
45
  color,
37
46
  blendMode,
38
47
  style,
@@ -41,8 +50,12 @@ export const processPaint = (
41
50
  strokeCap,
42
51
  strokeMiter,
43
52
  opacity,
44
- }: CustomPaintProps
53
+ }: CustomPaintProps,
54
+ children: DeclarationResult[]
45
55
  ) => {
56
+ if (paintRef && paintRef.current) {
57
+ return paintRef.current;
58
+ }
46
59
  if (color !== undefined) {
47
60
  const c = processColor(color, currentOpacity);
48
61
  paint.setShader(null);
@@ -72,34 +85,24 @@ export const processPaint = (
72
85
  if (opacity !== undefined) {
73
86
  paint.setAlphaf(opacity);
74
87
  }
75
- };
76
-
77
- export const selectPaint = (
78
- currentPaint: SkPaint,
79
- {
80
- paint,
81
- color: cl,
82
- blendMode,
83
- style: paintStyle,
84
- strokeWidth,
85
- strokeJoin,
86
- strokeCap,
87
- strokeMiter,
88
- opacity,
89
- }: CustomPaintProps
90
- ) => {
91
- const hasCustomPaint =
92
- cl !== undefined ||
93
- blendMode !== undefined ||
94
- paintStyle !== undefined ||
95
- strokeWidth !== undefined ||
96
- strokeJoin !== undefined ||
97
- opacity !== undefined ||
98
- strokeCap !== undefined ||
99
- strokeMiter !== undefined;
100
- const parentPaint = paint?.current ?? currentPaint;
101
- if (hasCustomPaint) {
102
- return parentPaint.copy();
88
+ children.forEach((child) => {
89
+ if (isShader(child)) {
90
+ paint.setShader(child);
91
+ } else if (isMaskFilter(child)) {
92
+ paint.setMaskFilter(child);
93
+ } else if (isColorFilter(child)) {
94
+ paint.setColorFilter(child);
95
+ } else if (isPathEffect(child)) {
96
+ paint.setPathEffect(child);
97
+ }
98
+ });
99
+ const filters = children.filter(isImageFilter);
100
+ if (filters.length > 0) {
101
+ paint.setImageFilter(
102
+ filters
103
+ .reverse()
104
+ .reduce<SkImageFilter | null>(Skia.ImageFilter.MakeCompose, null)
105
+ );
103
106
  }
104
- return parentPaint;
107
+ return paint;
105
108
  };
@@ -1,2 +1,18 @@
1
+ /**
2
+ * Linear interpolation
3
+ * @param value
4
+ * @param x
5
+ * @param y
6
+ */
1
7
  export const mix = (value: number, x: number, y: number) =>
2
8
  x * (1 - value) + y * value;
9
+
10
+ /**
11
+ * @summary Clamps a node with a lower and upper bound.
12
+ * @example
13
+ clamp(-1, 0, 100); // 0
14
+ clamp(1, 0, 100); // 1
15
+ clamp(101, 0, 100); // 100
16
+ */
17
+ export const clamp = (value: number, lowerBound: number, upperBound: number) =>
18
+ Math.min(Math.max(lowerBound, value), upperBound);