@shopify/react-native-skia 1.8.2 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- package/android/cpp/rnskia-android/MainThreadDispatcher.h +1 -1
- package/android/cpp/rnskia-android/OpenGLContext.h +4 -4
- package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +3 -3
- package/cpp/api/JsiSkCanvas.h +27 -25
- package/cpp/api/JsiSkImage.h +24 -0
- package/cpp/api/JsiSkPaint.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiAtlasNode.h +5 -1
- package/cpp/rnskia/dom/nodes/JsiImageNode.h +8 -4
- package/cpp/rnskia/dom/nodes/JsiShaderNodes.h +9 -38
- package/cpp/rnskia/dom/props/SamplingProp.h +54 -0
- package/ios/RNSkia-iOS/SkiaManager.mm +2 -4
- package/lib/commonjs/dom/types/Drawings.d.ts +3 -1
- package/lib/commonjs/dom/types/Drawings.js.map +1 -1
- package/lib/commonjs/dom/types/Shaders.d.ts +2 -3
- package/lib/commonjs/dom/types/Shaders.js.map +1 -1
- package/lib/commonjs/renderer/components/image/ImageShader.d.ts +1 -1
- package/lib/commonjs/renderer/components/image/ImageShader.js +0 -4
- package/lib/commonjs/renderer/components/image/ImageShader.js.map +1 -1
- package/lib/commonjs/skia/types/Canvas.d.ts +2 -2
- package/lib/commonjs/skia/types/Canvas.js.map +1 -1
- package/lib/commonjs/skia/types/Image/Image.d.ts +18 -0
- package/lib/commonjs/skia/types/Image/Image.js +24 -1
- package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
- package/lib/commonjs/skia/types/Picture/PictureRecorder.d.ts +2 -1
- package/lib/commonjs/skia/types/Picture/PictureRecorder.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkCanvas.d.ts +2 -2
- package/lib/commonjs/skia/web/JsiSkCanvas.js +15 -2
- package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/commonjs/sksg/Container.d.ts +17 -14
- package/lib/commonjs/sksg/Container.js +59 -61
- package/lib/commonjs/sksg/Container.js.map +1 -1
- package/lib/commonjs/sksg/HostConfig.js +4 -9
- package/lib/commonjs/sksg/HostConfig.js.map +1 -1
- package/lib/commonjs/sksg/Reconciler.js +1 -2
- package/lib/commonjs/sksg/Reconciler.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/Recorder.d.ts +11 -0
- package/lib/commonjs/sksg/Recorder/Recorder.js +9 -0
- package/lib/commonjs/sksg/Recorder/Recorder.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/commands/Drawing.js +11 -4
- package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
- package/lib/commonjs/sksg/Recorder/commands/Shaders.js +8 -3
- package/lib/commonjs/sksg/Recorder/commands/Shaders.js.map +1 -1
- package/lib/module/dom/types/Drawings.d.ts +3 -1
- package/lib/module/dom/types/Drawings.js.map +1 -1
- package/lib/module/dom/types/Shaders.d.ts +2 -3
- package/lib/module/dom/types/Shaders.js.map +1 -1
- package/lib/module/renderer/components/image/ImageShader.d.ts +1 -1
- package/lib/module/renderer/components/image/ImageShader.js +0 -4
- package/lib/module/renderer/components/image/ImageShader.js.map +1 -1
- package/lib/module/skia/types/Canvas.d.ts +2 -2
- package/lib/module/skia/types/Canvas.js.map +1 -1
- package/lib/module/skia/types/Image/Image.d.ts +18 -0
- package/lib/module/skia/types/Image/Image.js +21 -0
- package/lib/module/skia/types/Image/Image.js.map +1 -1
- package/lib/module/skia/types/Picture/PictureRecorder.d.ts +2 -1
- package/lib/module/skia/types/Picture/PictureRecorder.js.map +1 -1
- package/lib/module/skia/web/JsiSkCanvas.d.ts +2 -2
- package/lib/module/skia/web/JsiSkCanvas.js +15 -2
- package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
- package/lib/module/sksg/Container.d.ts +17 -14
- package/lib/module/sksg/Container.js +56 -59
- package/lib/module/sksg/Container.js.map +1 -1
- package/lib/module/sksg/HostConfig.js +4 -9
- package/lib/module/sksg/HostConfig.js.map +1 -1
- package/lib/module/sksg/Reconciler.js +2 -3
- package/lib/module/sksg/Reconciler.js.map +1 -1
- package/lib/module/sksg/Recorder/Recorder.d.ts +11 -0
- package/lib/module/sksg/Recorder/Recorder.js +9 -0
- package/lib/module/sksg/Recorder/Recorder.js.map +1 -1
- package/lib/module/sksg/Recorder/commands/Drawing.js +12 -5
- package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
- package/lib/module/sksg/Recorder/commands/Shaders.js +9 -4
- package/lib/module/sksg/Recorder/commands/Shaders.js.map +1 -1
- package/lib/typescript/lib/commonjs/renderer/components/image/ImageShader.d.ts +1 -3
- package/lib/typescript/lib/commonjs/skia/types/Image/Image.d.ts +21 -0
- package/lib/typescript/lib/commonjs/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/typescript/lib/commonjs/sksg/Container.d.ts +15 -10
- package/lib/typescript/lib/commonjs/sksg/HostConfig.d.ts +4 -4
- package/lib/typescript/lib/commonjs/sksg/Reconciler.d.ts +21 -2
- package/lib/typescript/lib/commonjs/sksg/Recorder/Recorder.d.ts +5 -0
- package/lib/typescript/lib/module/mock/index.d.ts +18 -3
- package/lib/typescript/lib/module/renderer/components/image/ImageShader.d.ts +1 -3
- package/lib/typescript/lib/module/skia/types/Image/Image.d.ts +21 -0
- package/lib/typescript/lib/module/skia/web/JsiSkCanvas.d.ts +1 -1
- package/lib/typescript/lib/module/sksg/Container.d.ts +15 -10
- package/lib/typescript/lib/module/sksg/HostConfig.d.ts +4 -4
- package/lib/typescript/lib/module/sksg/Reconciler.d.ts +21 -2
- package/lib/typescript/lib/module/sksg/Recorder/Recorder.d.ts +5 -0
- package/lib/typescript/src/dom/types/Drawings.d.ts +3 -1
- package/lib/typescript/src/dom/types/Shaders.d.ts +2 -3
- package/lib/typescript/src/renderer/components/image/ImageShader.d.ts +1 -1
- package/lib/typescript/src/skia/types/Canvas.d.ts +2 -2
- package/lib/typescript/src/skia/types/Image/Image.d.ts +18 -0
- package/lib/typescript/src/skia/types/Picture/PictureRecorder.d.ts +2 -1
- package/lib/typescript/src/skia/web/JsiSkCanvas.d.ts +2 -2
- package/lib/typescript/src/sksg/Container.d.ts +17 -14
- package/lib/typescript/src/sksg/Recorder/Recorder.d.ts +11 -0
- package/libs/apple/libskia.xcframework/Info.plist +35 -2
- package/libs/apple/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
- package/libs/apple/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/apple/libskia.xcframework/macos-arm64_x86_64/libskia.a +0 -0
- package/libs/apple/libskia.xcframework/tvos-arm64_arm64e/libskia.a +0 -0
- package/libs/apple/libskia.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
- package/libs/apple/libskottie.xcframework/Info.plist +36 -3
- package/libs/apple/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
- package/libs/apple/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
- package/libs/apple/libskottie.xcframework/macos-arm64_x86_64/libskottie.a +0 -0
- package/libs/apple/libskottie.xcframework/tvos-arm64_arm64e/libskottie.a +0 -0
- package/libs/apple/libskottie.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
- package/libs/apple/libskparagraph.xcframework/Info.plist +40 -7
- package/libs/apple/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
- package/libs/apple/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
- package/libs/apple/libskparagraph.xcframework/macos-arm64_x86_64/libskparagraph.a +0 -0
- package/libs/apple/libskparagraph.xcframework/tvos-arm64_arm64e/libskparagraph.a +0 -0
- package/libs/apple/libskparagraph.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
- package/libs/apple/libsksg.xcframework/Info.plist +35 -2
- package/libs/apple/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
- package/libs/apple/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
- package/libs/apple/libsksg.xcframework/macos-arm64_x86_64/libsksg.a +0 -0
- package/libs/apple/libsksg.xcframework/tvos-arm64_arm64e/libsksg.a +0 -0
- package/libs/apple/libsksg.xcframework/tvos-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
- package/libs/apple/libskshaper.xcframework/Info.plist +33 -0
- package/libs/apple/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
- package/libs/apple/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/apple/libskshaper.xcframework/macos-arm64_x86_64/libskshaper.a +0 -0
- package/libs/apple/libskshaper.xcframework/tvos-arm64_arm64e/libskshaper.a +0 -0
- package/libs/apple/libskshaper.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
- package/libs/apple/libskunicode_core.xcframework/Info.plist +36 -3
- package/libs/apple/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
- package/libs/apple/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
- package/libs/apple/libskunicode_core.xcframework/macos-arm64_x86_64/libskunicode_core.a +0 -0
- package/libs/apple/libskunicode_core.xcframework/tvos-arm64_arm64e/libskunicode_core.a +0 -0
- package/libs/apple/libskunicode_core.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
- package/libs/apple/libskunicode_libgrapheme.xcframework/Info.plist +35 -2
- package/libs/apple/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
- package/libs/apple/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
- package/libs/apple/libskunicode_libgrapheme.xcframework/macos-arm64_x86_64/libskunicode_libgrapheme.a +0 -0
- package/libs/apple/libskunicode_libgrapheme.xcframework/tvos-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
- package/libs/apple/libskunicode_libgrapheme.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
- package/libs/apple/libsvg.xcframework/Info.plist +36 -3
- package/libs/apple/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
- package/libs/apple/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/libs/apple/libsvg.xcframework/macos-arm64_x86_64/libsvg.a +0 -0
- package/libs/apple/libsvg.xcframework/tvos-arm64_arm64e/libsvg.a +0 -0
- package/libs/apple/libsvg.xcframework/tvos-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
- package/package.json +1 -1
- package/react-native-skia.podspec +2 -2
- package/src/__tests__/snapshots/animated-images/bird.png +0 -0
- package/src/__tests__/snapshots/demos/product.png +0 -0
- package/src/__tests__/snapshots/demos/product2.png +0 -0
- package/src/__tests__/snapshots/images/bundle-android.png +0 -0
- package/src/__tests__/snapshots/images/bundle-ios.png +0 -0
- package/src/__tests__/snapshots/images/bundle-node.png +0 -0
- package/src/__tests__/snapshots/images/filter.png +0 -0
- package/src/dom/types/Drawings.ts +3 -0
- package/src/dom/types/Shaders.ts +2 -4
- package/src/renderer/__tests__/e2e/Text.spec.tsx +1 -1
- package/src/renderer/components/image/ImageShader.tsx +2 -15
- package/src/skia/types/Canvas.ts +2 -3
- package/src/skia/types/Image/Image.ts +14 -0
- package/src/skia/types/Picture/PictureRecorder.ts +2 -1
- package/src/skia/web/JsiSkCanvas.ts +50 -29
- package/src/sksg/Container.ts +64 -67
- package/src/sksg/HostConfig.ts +4 -9
- package/src/sksg/Reconciler.ts +3 -3
- package/src/sksg/Recorder/Recorder.ts +20 -0
- package/src/sksg/Recorder/commands/Drawing.ts +33 -4
- package/src/sksg/Recorder/commands/Shaders.ts +21 -8
- package/lib/commonjs/sksg/Recorder/Recording.d.ts +0 -7
- package/lib/commonjs/sksg/Recorder/Recording.js +0 -12
- package/lib/commonjs/sksg/Recorder/Recording.js.map +0 -1
- package/lib/module/sksg/Recorder/Recording.d.ts +0 -7
- package/lib/module/sksg/Recorder/Recording.js +0 -5
- package/lib/module/sksg/Recorder/Recording.js.map +0 -1
- package/lib/typescript/lib/commonjs/sksg/Recorder/Recording.d.ts +0 -5
- package/lib/typescript/lib/module/sksg/Recorder/Recording.d.ts +0 -4
- package/lib/typescript/src/sksg/Recorder/Recording.d.ts +0 -7
- package/src/sksg/Recorder/Recording.ts +0 -13
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -17,6 +17,7 @@ import type {
|
|
17
17
|
SkRect,
|
18
18
|
SkRSXform,
|
19
19
|
SkColor,
|
20
|
+
SamplingOptions,
|
20
21
|
} from "../../skia/types";
|
21
22
|
|
22
23
|
import type {
|
@@ -37,6 +38,7 @@ export type ImageProps = DrawingNodeProps &
|
|
37
38
|
RectDef & {
|
38
39
|
fit?: Fit;
|
39
40
|
image: SkImage | null;
|
41
|
+
sampling?: SamplingOptions;
|
40
42
|
};
|
41
43
|
|
42
44
|
export type CircleProps = CircleDef & DrawingNodeProps;
|
@@ -65,6 +67,7 @@ export interface AtlasProps extends DrawingNodeProps {
|
|
65
67
|
sprites: SkRect[];
|
66
68
|
transforms: SkRSXform[];
|
67
69
|
colors?: SkColor[];
|
70
|
+
sampling?: SamplingOptions;
|
68
71
|
}
|
69
72
|
|
70
73
|
export interface CubicBezierHandle {
|
package/src/dom/types/Shaders.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import type {
|
2
2
|
Color,
|
3
|
-
|
4
|
-
MipmapMode,
|
3
|
+
SamplingOptions,
|
5
4
|
SkImage,
|
6
5
|
SkRect,
|
7
6
|
SkRuntimeEffect,
|
@@ -26,11 +25,10 @@ export interface ShaderProps extends TransformProps, ChildrenProps {
|
|
26
25
|
export interface ImageShaderProps extends TransformProps, Partial<RectCtor> {
|
27
26
|
tx: SkEnum<typeof TileMode>;
|
28
27
|
ty: SkEnum<typeof TileMode>;
|
29
|
-
fm: SkEnum<typeof FilterMode>;
|
30
|
-
mm: SkEnum<typeof MipmapMode>;
|
31
28
|
fit: Fit;
|
32
29
|
rect?: SkRect;
|
33
30
|
image: SkImage | null;
|
31
|
+
sampling?: SamplingOptions;
|
34
32
|
}
|
35
33
|
|
36
34
|
export interface ColorProps {
|
@@ -18,7 +18,7 @@ describe("Text", () => {
|
|
18
18
|
},
|
19
19
|
{ font }
|
20
20
|
);
|
21
|
-
expect(result).toEqual([892, 896]);
|
21
|
+
expect(result).toEqual(surface.OS === "ios" ? [0, 0] : [892, 896]);
|
22
22
|
});
|
23
23
|
it("Should calculate chinese text width correctly", async () => {
|
24
24
|
const font = fonts.NotoSansSCRegular;
|
@@ -6,24 +6,11 @@ import type { SkiaDefaultProps } from "../../processors";
|
|
6
6
|
export const ImageShader = ({
|
7
7
|
tx = "decal",
|
8
8
|
ty = "decal",
|
9
|
-
fm = "nearest",
|
10
|
-
mm = "none",
|
11
9
|
fit = "none",
|
12
10
|
transform = [],
|
13
11
|
...props
|
14
|
-
}: SkiaDefaultProps<
|
15
|
-
ImageShaderProps,
|
16
|
-
"tx" | "ty" | "fm" | "mm" | "fit" | "transform"
|
17
|
-
>) => {
|
12
|
+
}: SkiaDefaultProps<ImageShaderProps, "tx" | "ty" | "fit" | "transform">) => {
|
18
13
|
return (
|
19
|
-
<skImageShader
|
20
|
-
tx={tx}
|
21
|
-
ty={ty}
|
22
|
-
fm={fm}
|
23
|
-
mm={mm}
|
24
|
-
fit={fit}
|
25
|
-
transform={transform}
|
26
|
-
{...props}
|
27
|
-
/>
|
14
|
+
<skImageShader tx={tx} ty={ty} fit={fit} transform={transform} {...props} />
|
28
15
|
);
|
29
16
|
};
|
package/src/skia/types/Canvas.ts
CHANGED
@@ -7,8 +7,7 @@ import type {
|
|
7
7
|
MipmapMode,
|
8
8
|
FilterMode,
|
9
9
|
ImageInfo,
|
10
|
-
|
11
|
-
FilterOptions,
|
10
|
+
SamplingOptions,
|
12
11
|
} from "./Image";
|
13
12
|
import type { SkSVG } from "./SVG";
|
14
13
|
import type { SkColor } from "./Color";
|
@@ -521,7 +520,7 @@ export interface SkCanvas {
|
|
521
520
|
paint: SkPaint,
|
522
521
|
blendMode?: BlendMode,
|
523
522
|
colors?: SkColor[],
|
524
|
-
sampling?:
|
523
|
+
sampling?: SamplingOptions
|
525
524
|
): void;
|
526
525
|
|
527
526
|
/** Read Image pixels
|
@@ -32,6 +32,20 @@ export enum ImageFormat {
|
|
32
32
|
WEBP = 6,
|
33
33
|
}
|
34
34
|
|
35
|
+
export type SamplingOptions = CubicResampler | FilterOptions;
|
36
|
+
|
37
|
+
export const isCubicSampling = (
|
38
|
+
sampling: SamplingOptions
|
39
|
+
): sampling is CubicResampler => {
|
40
|
+
"worklet";
|
41
|
+
return "B" in sampling && "C" in sampling;
|
42
|
+
};
|
43
|
+
|
44
|
+
export const MitchellCubicSampling = { B: 1 / 3.0, C: 1 / 3.0 };
|
45
|
+
export const CatmullRomCubicSampling = { B: 0, C: 1 / 2.0 };
|
46
|
+
export const CubicSampling = { B: 0, C: 0 };
|
47
|
+
export const MakeCubic = (B: number, C: number) => ({ B, C });
|
48
|
+
|
35
49
|
export interface SkImage extends SkJSIInstance<"Image"> {
|
36
50
|
/**
|
37
51
|
* Returns the possibly scaled height of the image.
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import type { SkCanvas } from "../Canvas";
|
2
|
+
import type { SkJSIInstance } from "../JsiInstance";
|
2
3
|
import type { SkRect } from "../Rect";
|
3
4
|
|
4
5
|
import type { SkPicture } from "./Picture";
|
5
6
|
|
6
|
-
export interface SkPictureRecorder {
|
7
|
+
export interface SkPictureRecorder extends SkJSIInstance<"PictureRecorder"> {
|
7
8
|
/**
|
8
9
|
* Returns a canvas on which to draw. When done drawing, call finishRecordingAsPicture()
|
9
10
|
*
|
@@ -1,31 +1,37 @@
|
|
1
|
-
import type { Canvas, CanvasKit } from "canvaskit-wasm";
|
2
|
-
|
3
1
|
import type {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
2
|
+
Canvas,
|
3
|
+
CanvasKit,
|
4
|
+
CubicResampler as CKCubicResampler,
|
5
|
+
FilterOptions as CKFilterOptions,
|
6
|
+
} from "canvaskit-wasm";
|
7
|
+
|
8
|
+
import {
|
9
|
+
type BlendMode,
|
10
|
+
type ClipOp,
|
11
|
+
type FilterMode,
|
12
|
+
type MipmapMode,
|
13
|
+
type PointMode,
|
14
|
+
type SaveLayerFlag,
|
15
|
+
type ImageInfo,
|
16
|
+
type SkCanvas,
|
17
|
+
type SkColor,
|
18
|
+
type SkFont,
|
19
|
+
type SkImage,
|
20
|
+
type SkImageFilter,
|
21
|
+
type SkMatrix,
|
22
|
+
type SkPaint,
|
23
|
+
type SkPath,
|
24
|
+
type SkPicture,
|
25
|
+
type SkPoint,
|
26
|
+
type SkRect,
|
27
|
+
type InputRRect,
|
28
|
+
type SkSVG,
|
29
|
+
type SkTextBlob,
|
30
|
+
type SkVertices,
|
31
|
+
type SkRSXform,
|
32
|
+
type CubicResampler,
|
33
|
+
type FilterOptions,
|
34
|
+
isCubicSampling,
|
29
35
|
} from "../types";
|
30
36
|
|
31
37
|
import { getEnum, HostObject } from "./Host";
|
@@ -398,7 +404,7 @@ export class JsiSkCanvas
|
|
398
404
|
paint: SkPaint,
|
399
405
|
blendMode?: BlendMode,
|
400
406
|
colors?: SkColor[],
|
401
|
-
|
407
|
+
sampling?: CubicResampler | FilterOptions
|
402
408
|
) {
|
403
409
|
const src = srcs.flatMap((s) =>
|
404
410
|
Array.from(JsiSkRect.fromValue(this.CanvasKit, s))
|
@@ -412,6 +418,20 @@ export class JsiSkCanvas
|
|
412
418
|
cls[i] = this.CanvasKit.ColorAsInt(r * 255, g * 255, b * 255, a * 255);
|
413
419
|
}
|
414
420
|
}
|
421
|
+
let ckSampling: CKCubicResampler | CKFilterOptions = {
|
422
|
+
filter: this.CanvasKit.FilterMode.Linear,
|
423
|
+
mipmap: this.CanvasKit.MipmapMode.None,
|
424
|
+
};
|
425
|
+
if (sampling && isCubicSampling(sampling)) {
|
426
|
+
ckSampling = sampling;
|
427
|
+
} else if (sampling) {
|
428
|
+
ckSampling = {
|
429
|
+
filter: getEnum(this.CanvasKit.FilterMode, sampling.filter),
|
430
|
+
mipmap: sampling.mipmap
|
431
|
+
? getEnum(this.CanvasKit.MipmapMode, sampling.mipmap)
|
432
|
+
: this.CanvasKit.MipmapMode.None,
|
433
|
+
};
|
434
|
+
}
|
415
435
|
this.ref.drawAtlas(
|
416
436
|
JsiSkImage.fromValue(atlas),
|
417
437
|
src,
|
@@ -420,7 +440,8 @@ export class JsiSkCanvas
|
|
420
440
|
blendMode
|
421
441
|
? getEnum(this.CanvasKit.BlendMode, blendMode)
|
422
442
|
: this.CanvasKit.BlendMode.DstOver,
|
423
|
-
cls
|
443
|
+
cls,
|
444
|
+
ckSampling
|
424
445
|
);
|
425
446
|
}
|
426
447
|
|
package/src/sksg/Container.ts
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
-
import { type SharedValue } from "react-native-reanimated";
|
2
|
-
|
3
1
|
import Rea from "../external/reanimated/ReanimatedProxy";
|
4
2
|
import type { Skia, SkCanvas } from "../skia/types";
|
3
|
+
import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers";
|
5
4
|
|
6
5
|
import type { Node } from "./Node";
|
7
|
-
import {
|
6
|
+
import type { Recording } from "./Recorder/Recorder";
|
8
7
|
import { Recorder } from "./Recorder/Recorder";
|
9
8
|
import { visit } from "./Recorder/Visitor";
|
10
9
|
import { replay } from "./Recorder/Player";
|
11
10
|
import { createDrawingContext } from "./Recorder/DrawingContext";
|
12
|
-
import { createRecording, type Recording } from "./Recorder/Recording";
|
13
11
|
|
14
12
|
const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
|
15
13
|
"worklet";
|
14
|
+
|
16
15
|
const rec = Skia.PictureRecorder();
|
17
16
|
const canvas = rec.beginRecording();
|
18
17
|
// const start = performance.now();
|
19
18
|
|
20
|
-
// TODO: because the pool is not a shared value here, it is copied on every frame
|
21
19
|
const ctx = createDrawingContext(Skia, recording.paintPool, canvas);
|
22
20
|
//console.log(recording.commands);
|
23
21
|
replay(ctx, recording.commands);
|
@@ -25,84 +23,83 @@ const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
|
|
25
23
|
//const end = performance.now();
|
26
24
|
//console.log("Recording time: ", end - start);
|
27
25
|
SkiaViewApi.setJsiProperty(nativeId, "picture", picture);
|
26
|
+
rec.dispose();
|
27
|
+
picture.dispose();
|
28
28
|
};
|
29
29
|
|
30
|
-
export class Container {
|
31
|
-
|
32
|
-
|
33
|
-
public unmounted = false;
|
34
|
-
|
35
|
-
private values = new Set<SharedValue<unknown>>();
|
36
|
-
private mapperId: number | null = null;
|
37
|
-
|
38
|
-
constructor(public Skia: Skia, private nativeId: number) {}
|
30
|
+
export abstract class Container {
|
31
|
+
public root: Node[] = [];
|
32
|
+
protected recording: Recording | null = null;
|
39
33
|
|
40
|
-
|
41
|
-
return this._root;
|
42
|
-
}
|
34
|
+
constructor(protected Skia: Skia, protected nativeId: number) {}
|
43
35
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
if (this.mapperId !== null) {
|
48
|
-
Rea.stopMapper(this.mapperId);
|
49
|
-
}
|
50
|
-
const { nativeId, Skia, _recording } = this;
|
51
|
-
this.mapperId = Rea.startMapper(() => {
|
52
|
-
"worklet";
|
53
|
-
drawOnscreen(Skia, nativeId, _recording!);
|
54
|
-
}, Array.from(this.values));
|
36
|
+
drawOnCanvas(canvas: SkCanvas) {
|
37
|
+
if (!this.recording) {
|
38
|
+
throw new Error("No recording to draw");
|
55
39
|
}
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
40
|
+
const ctx = createDrawingContext(
|
41
|
+
this.Skia,
|
42
|
+
this.recording.paintPool,
|
43
|
+
canvas
|
44
|
+
);
|
45
|
+
//console.log(this._recording);
|
46
|
+
replay(ctx, this.recording.commands);
|
60
47
|
}
|
61
48
|
|
62
|
-
|
63
|
-
|
49
|
+
abstract redraw(): void;
|
50
|
+
}
|
51
|
+
|
52
|
+
class StaticContainer extends Container {
|
53
|
+
constructor(Skia: Skia, nativeId: number) {
|
54
|
+
super(Skia, nativeId);
|
64
55
|
}
|
65
56
|
|
66
57
|
redraw() {
|
67
|
-
const
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
58
|
+
const recorder = new Recorder();
|
59
|
+
visit(recorder, this.root);
|
60
|
+
this.recording = recorder.getRecording();
|
61
|
+
const isOnScreen = this.nativeId !== -1;
|
62
|
+
if (isOnScreen) {
|
63
|
+
const rec = this.Skia.PictureRecorder();
|
64
|
+
const canvas = rec.beginRecording();
|
65
|
+
this.drawOnCanvas(canvas);
|
66
|
+
const picture = rec.finishRecordingAsPicture();
|
67
|
+
SkiaViewApi.setJsiProperty(this.nativeId, "picture", picture);
|
73
68
|
}
|
74
69
|
}
|
70
|
+
}
|
75
71
|
|
76
|
-
|
77
|
-
|
78
|
-
}
|
79
|
-
|
80
|
-
unregisterValues(values: object) {
|
81
|
-
Object.values(values)
|
82
|
-
.filter(isSharedValue)
|
83
|
-
.forEach((value) => {
|
84
|
-
this.values.delete(value);
|
85
|
-
});
|
86
|
-
}
|
72
|
+
class ReanimatedContainer extends Container {
|
73
|
+
private mapperId: number | null = null;
|
87
74
|
|
88
|
-
|
89
|
-
|
90
|
-
.filter(isSharedValue)
|
91
|
-
.forEach((value) => {
|
92
|
-
this.values.add(value);
|
93
|
-
});
|
75
|
+
constructor(Skia: Skia, nativeId: number) {
|
76
|
+
super(Skia, nativeId);
|
94
77
|
}
|
95
78
|
|
96
|
-
|
97
|
-
if (
|
98
|
-
|
79
|
+
redraw() {
|
80
|
+
if (this.mapperId !== null) {
|
81
|
+
Rea.stopMapper(this.mapperId);
|
82
|
+
}
|
83
|
+
const recorder = new Recorder();
|
84
|
+
visit(recorder, this.root);
|
85
|
+
const record = recorder.getRecording();
|
86
|
+
const { animationValues } = record;
|
87
|
+
this.recording = {
|
88
|
+
commands: record.commands,
|
89
|
+
paintPool: record.paintPool,
|
90
|
+
};
|
91
|
+
if (animationValues.size > 0) {
|
92
|
+
const { nativeId, Skia, recording } = this;
|
93
|
+
this.mapperId = Rea.startMapper(() => {
|
94
|
+
"worklet";
|
95
|
+
drawOnscreen(Skia, nativeId, recording!);
|
96
|
+
}, Array.from(animationValues));
|
99
97
|
}
|
100
|
-
const ctx = createDrawingContext(
|
101
|
-
this.Skia,
|
102
|
-
this._recording.paintPool,
|
103
|
-
canvas
|
104
|
-
);
|
105
|
-
//console.log(this._recording);
|
106
|
-
replay(ctx, this._recording.commands);
|
107
98
|
}
|
108
99
|
}
|
100
|
+
|
101
|
+
export const createContainer = (Skia: Skia, nativeId: number) => {
|
102
|
+
return HAS_REANIMATED_3 && nativeId !== -1
|
103
|
+
? new ReanimatedContainer(Skia, nativeId)
|
104
|
+
: new StaticContainer(Skia, nativeId);
|
105
|
+
};
|
package/src/sksg/HostConfig.ts
CHANGED
@@ -85,14 +85,13 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
85
85
|
createInstance(
|
86
86
|
type,
|
87
87
|
propsWithChildren,
|
88
|
-
|
88
|
+
_container,
|
89
89
|
_hostContext,
|
90
90
|
_internalInstanceHandle
|
91
91
|
) {
|
92
92
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
93
93
|
const { children, ...props } = propsWithChildren as any;
|
94
94
|
debug("createInstance", type);
|
95
|
-
container.registerValues(props);
|
96
95
|
const instance = {
|
97
96
|
type,
|
98
97
|
props,
|
@@ -121,7 +120,7 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
121
120
|
debug("commitMount");
|
122
121
|
},
|
123
122
|
|
124
|
-
prepareForCommit(
|
123
|
+
prepareForCommit(_container: Container) {
|
125
124
|
debug("prepareForCommit");
|
126
125
|
return null;
|
127
126
|
},
|
@@ -144,9 +143,8 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
144
143
|
// textInstance.instance = newText;
|
145
144
|
},
|
146
145
|
|
147
|
-
clearContainer: (
|
146
|
+
clearContainer: (_container) => {
|
148
147
|
debug("clearContainer");
|
149
|
-
container.clear();
|
150
148
|
},
|
151
149
|
|
152
150
|
prepareUpdate(
|
@@ -162,8 +160,6 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
162
160
|
if (propsAreEqual) {
|
163
161
|
return null;
|
164
162
|
}
|
165
|
-
container.unregisterValues(oldProps);
|
166
|
-
container.registerValues(newProps);
|
167
163
|
return container;
|
168
164
|
},
|
169
165
|
|
@@ -208,7 +204,6 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
208
204
|
},
|
209
205
|
|
210
206
|
replaceContainerChildren(container: Container, newChildren: ChildSet) {
|
211
|
-
debug("replaceContainerChildren");
|
212
207
|
container.root = newChildren;
|
213
208
|
},
|
214
209
|
|
@@ -229,7 +224,7 @@ export const sksgHostConfig: SkiaHostConfig = {
|
|
229
224
|
getCurrentEventPriority: () => DefaultEventPriority,
|
230
225
|
beforeActiveInstanceBlur: () => {},
|
231
226
|
afterActiveInstanceBlur: () => {},
|
232
|
-
detachDeletedInstance: () => {},
|
227
|
+
detachDeletedInstance: (_node: Instance) => {},
|
233
228
|
getInstanceFromNode: function (_node): Fiber | null | undefined {
|
234
229
|
throw new Error("Function not implemented.");
|
235
230
|
},
|
package/src/sksg/Reconciler.ts
CHANGED
@@ -6,7 +6,8 @@ import type { SkCanvas, Skia } from "../skia/types";
|
|
6
6
|
import { NodeType } from "../dom/types";
|
7
7
|
|
8
8
|
import { debug, sksgHostConfig } from "./HostConfig";
|
9
|
-
import { Container } from "./Container";
|
9
|
+
import type { Container } from "./Container";
|
10
|
+
import { createContainer } from "./Container";
|
10
11
|
|
11
12
|
const skiaReconciler = ReactReconciler(sksgHostConfig);
|
12
13
|
|
@@ -21,7 +22,7 @@ export class SkiaSGRoot {
|
|
21
22
|
private container: Container;
|
22
23
|
|
23
24
|
constructor(public Skia: Skia, nativeId = -1) {
|
24
|
-
this.container =
|
25
|
+
this.container = createContainer(Skia, nativeId);
|
25
26
|
this.root = skiaReconciler.createContainer(
|
26
27
|
this.container,
|
27
28
|
0,
|
@@ -58,7 +59,6 @@ export class SkiaSGRoot {
|
|
58
59
|
}
|
59
60
|
|
60
61
|
unmount() {
|
61
|
-
this.container.unmounted = true;
|
62
62
|
skiaReconciler.updateContainer(null, this.root, null, () => {
|
63
63
|
debug("unmountContainer");
|
64
64
|
});
|
@@ -30,12 +30,31 @@ import type {
|
|
30
30
|
import type { AnimatedProps } from "../../renderer";
|
31
31
|
import { isSharedValue } from "../utils";
|
32
32
|
import { isColorFilter, isImageFilter, isPathEffect, isShader } from "../Node";
|
33
|
+
import type { SkPaint } from "../../skia/types";
|
33
34
|
|
34
35
|
import { CommandType } from "./Core";
|
35
36
|
import type { Command } from "./Core";
|
36
37
|
|
38
|
+
export interface Recording {
|
39
|
+
commands: Command[];
|
40
|
+
paintPool: SkPaint[];
|
41
|
+
}
|
42
|
+
|
43
|
+
interface AnimationValues {
|
44
|
+
animationValues: Set<SharedValue<unknown>>;
|
45
|
+
}
|
46
|
+
|
37
47
|
export class Recorder {
|
38
48
|
commands: Command[] = [];
|
49
|
+
animationValues: Set<SharedValue<unknown>> = new Set();
|
50
|
+
|
51
|
+
getRecording(): Recording & AnimationValues {
|
52
|
+
return {
|
53
|
+
commands: this.commands,
|
54
|
+
paintPool: [],
|
55
|
+
animationValues: this.animationValues,
|
56
|
+
};
|
57
|
+
}
|
39
58
|
|
40
59
|
private processProps(props: Record<string, unknown>) {
|
41
60
|
const animatedProps: Record<string, SharedValue<unknown>> = {};
|
@@ -44,6 +63,7 @@ export class Recorder {
|
|
44
63
|
for (const key in props) {
|
45
64
|
const prop = props[key];
|
46
65
|
if (isSharedValue(prop)) {
|
66
|
+
this.animationValues.add(prop);
|
47
67
|
props[key] = prop.value;
|
48
68
|
animatedProps[key] = prop;
|
49
69
|
hasAnimatedProps = true;
|
@@ -40,7 +40,10 @@ import {
|
|
40
40
|
BlurStyle,
|
41
41
|
ClipOp,
|
42
42
|
FillType,
|
43
|
+
FilterMode,
|
44
|
+
isCubicSampling,
|
43
45
|
isRRect,
|
46
|
+
MipmapMode,
|
44
47
|
PointMode,
|
45
48
|
VertexMode,
|
46
49
|
} from "../../../skia/types";
|
@@ -117,7 +120,7 @@ export const drawBox = (
|
|
117
120
|
|
118
121
|
export const drawImage = (ctx: DrawingContext, props: ImageProps) => {
|
119
122
|
"worklet";
|
120
|
-
const { image } = props;
|
123
|
+
const { image, sampling } = props;
|
121
124
|
if (image) {
|
122
125
|
const fit = props.fit ?? "contain";
|
123
126
|
const rect = processRect(ctx.Skia, props);
|
@@ -131,7 +134,25 @@ export const drawImage = (ctx: DrawingContext, props: ImageProps) => {
|
|
131
134
|
},
|
132
135
|
rect
|
133
136
|
);
|
134
|
-
|
137
|
+
if (sampling && isCubicSampling(sampling)) {
|
138
|
+
ctx.canvas.drawImageRectCubic(
|
139
|
+
image,
|
140
|
+
src,
|
141
|
+
dst,
|
142
|
+
sampling.B,
|
143
|
+
sampling.C,
|
144
|
+
ctx.paint
|
145
|
+
);
|
146
|
+
} else {
|
147
|
+
ctx.canvas.drawImageRectOptions(
|
148
|
+
image,
|
149
|
+
src,
|
150
|
+
dst,
|
151
|
+
sampling?.filter ?? FilterMode.Linear,
|
152
|
+
sampling?.mipmap ?? MipmapMode.None,
|
153
|
+
ctx.paint
|
154
|
+
);
|
155
|
+
}
|
135
156
|
}
|
136
157
|
};
|
137
158
|
|
@@ -349,10 +370,18 @@ export const drawPicture = (ctx: DrawingContext, props: PictureProps) => {
|
|
349
370
|
|
350
371
|
export const drawAtlas = (ctx: DrawingContext, props: AtlasProps) => {
|
351
372
|
"worklet";
|
352
|
-
const { image, sprites, transforms, colors, blendMode } = props;
|
373
|
+
const { image, sprites, transforms, colors, blendMode, sampling } = props;
|
353
374
|
const blend = blendMode ? BlendMode[enumKey(blendMode)] : undefined;
|
354
375
|
if (image) {
|
355
|
-
ctx.canvas.drawAtlas(
|
376
|
+
ctx.canvas.drawAtlas(
|
377
|
+
image,
|
378
|
+
sprites,
|
379
|
+
transforms,
|
380
|
+
ctx.paint,
|
381
|
+
blend,
|
382
|
+
colors,
|
383
|
+
sampling
|
384
|
+
);
|
356
385
|
}
|
357
386
|
};
|
358
387
|
|
@@ -19,9 +19,11 @@ import type {
|
|
19
19
|
TurbulenceProps,
|
20
20
|
TwoPointConicalGradientProps,
|
21
21
|
} from "../../../dom/types";
|
22
|
+
import type { SkShader } from "../../../skia/types";
|
22
23
|
import {
|
23
24
|
BlendMode,
|
24
25
|
FilterMode,
|
26
|
+
isCubicSampling,
|
25
27
|
MipmapMode,
|
26
28
|
processUniforms,
|
27
29
|
TileMode,
|
@@ -179,7 +181,7 @@ const declareTurbulenceShader = (
|
|
179
181
|
|
180
182
|
const declareImageShader = (ctx: DrawingContext, props: ImageShaderProps) => {
|
181
183
|
"worklet";
|
182
|
-
const { fit, image, tx, ty,
|
184
|
+
const { fit, image, tx, ty, sampling, ...imageShaderProps } = props;
|
183
185
|
if (!image) {
|
184
186
|
return;
|
185
187
|
}
|
@@ -199,13 +201,24 @@ const declareImageShader = (ctx: DrawingContext, props: ImageShaderProps) => {
|
|
199
201
|
const lm = ctx.Skia.Matrix();
|
200
202
|
lm.concat(m3);
|
201
203
|
processTransformProps(lm, imageShaderProps);
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
204
|
+
let shader: SkShader;
|
205
|
+
if (sampling && isCubicSampling(sampling)) {
|
206
|
+
shader = image.makeShaderCubic(
|
207
|
+
TileMode[enumKey(tx)],
|
208
|
+
TileMode[enumKey(ty)],
|
209
|
+
sampling.B,
|
210
|
+
sampling.C,
|
211
|
+
lm
|
212
|
+
);
|
213
|
+
} else {
|
214
|
+
shader = image.makeShaderCubic(
|
215
|
+
TileMode[enumKey(tx)],
|
216
|
+
TileMode[enumKey(ty)],
|
217
|
+
sampling?.filter ?? FilterMode.Linear,
|
218
|
+
sampling?.mipmap ?? MipmapMode.None,
|
219
|
+
lm
|
220
|
+
);
|
221
|
+
}
|
209
222
|
ctx.shaders.push(shader);
|
210
223
|
};
|
211
224
|
|