Skip to content

Commit 9c2f039

Browse files
authored
Merge pull request #2041 from Shopify/deprecation
Deprecation of `SkiaView` and `<Drawing />`
2 parents 522bd31 + 8152d60 commit 9c2f039

File tree

9 files changed

+140
-5
lines changed

9 files changed

+140
-5
lines changed

docs/docs/shapes/pictures.md

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,54 @@ A Picture renders a previously recorded list of drawing operations on the canvas
1111
| :------ | :---------- | :---------------- |
1212
| picture | `SkPicture` | Picture to render |
1313

14-
### Example
14+
15+
## Hello World
16+
17+
```tsx twoslash
18+
import React, { useMemo } from "react";
19+
import {
20+
createPicture,
21+
Canvas,
22+
Picture,
23+
Skia,
24+
Group,
25+
BlendMode
26+
} from "@shopify/react-native-skia";
27+
28+
const size = 256;
29+
30+
export const HelloWorld = () => {
31+
// Create a picture
32+
const picture = useMemo(() => createPicture(
33+
{ width: size, height: size },
34+
(canvas) => {
35+
const r = 0.33 * size;
36+
const paint = Skia.Paint();
37+
paint.setBlendMode(BlendMode.Multiply);
38+
39+
paint.setColor(Skia.Color("cyan"));
40+
canvas.drawCircle(r, r, r, paint);
41+
42+
paint.setColor(Skia.Color("magenta"));
43+
canvas.drawCircle(size - r, r, r, paint);
44+
45+
paint.setColor(Skia.Color("yellow"));
46+
canvas.drawCircle(size / 2, size - r, r, paint);
47+
}
48+
), []);
49+
return (
50+
<Canvas style={{ flex: 1 }}>
51+
<Picture picture={picture} />
52+
</Canvas>
53+
);
54+
};
55+
```
56+
57+
## Serialization
58+
59+
You can serialize a picture to a byte array.
60+
Serialized pictures are only compatible with the version of Skia it was created with.
61+
You can use serialized pictures with the [Skia debugger](https://skia.org/docs/dev/tools/debugger/).
1562

1663
```tsx twoslash
1764
import React, { useMemo } from "react";
@@ -26,7 +73,7 @@ import {
2673
export const PictureExample = () => {
2774
// Create picture
2875
const picture = useMemo(() => createPicture(
29-
{ x: 0, y: 0, width: 100, height: 100 },
76+
{ width: 100, height: 100 },
3077
(canvas) => {
3178
const paint = Skia.Paint();
3279
paint.setColor(Skia.Color("pink"));
7.64 KB
Loading
883 Bytes
Loading

package/src/dom/nodes/JsiSkDOM.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ export class JsiSkDOM implements SkDOM {
173173
}
174174

175175
CustomDrawing(props: CustomDrawingNodeProps) {
176+
console.warn(
177+
// eslint-disable-next-line max-len
178+
"The <Drawing /> component is deprecated and will be removed in the next release. For custom drawings, please sure the <Picture /> component: https://shopify.github.io/react-native-skia/docs/shapes/pictures/"
179+
);
176180
return NATIVE_DOM
177181
? global.SkiaDomApi.CustomDrawingNode(props ?? {})
178182
: new CustomDrawingNode(this.ctx, props);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { importSkia, surface } from "../setup";
2+
import { checkImage } from "../../../__tests__/setup";
3+
import { BlendMode } from "../../../skia/types";
4+
5+
describe("Pictures", () => {
6+
it("Should draw a simple picture", async () => {
7+
const { Skia } = importSkia();
8+
const str = await surface.eval((Sk) => {
9+
const size = 256;
10+
const surf = Sk.Surface.MakeOffscreen(size, size)!;
11+
const canvas = surf.getCanvas();
12+
const recorder = Sk.PictureRecorder();
13+
const canvas2 = recorder.beginRecording(Sk.XYWHRect(0, 0, size, size));
14+
canvas2.drawColor(Sk.Color("cyan"));
15+
const picture = recorder.finishRecordingAsPicture();
16+
canvas.drawPicture(picture);
17+
return surf.makeImageSnapshot().encodeToBase64();
18+
});
19+
const image = Skia.Image.MakeImageFromEncoded(Skia.Data.fromBase64(str))!;
20+
checkImage(image, "snapshots/pictures/simple-picture.png");
21+
});
22+
it("Should draw the hello world example as picture", async () => {
23+
const { Skia } = importSkia();
24+
const str = await surface.eval(
25+
(Sk, ctx) => {
26+
const { size } = ctx;
27+
const r = size * 0.33;
28+
const surf = Sk.Surface.MakeOffscreen(size, size)!;
29+
const canvas = surf.getCanvas();
30+
const recorder = Sk.PictureRecorder();
31+
const canvas2 = recorder.beginRecording(Sk.XYWHRect(0, 0, size, size));
32+
const paint = Sk.Paint();
33+
paint.setBlendMode(ctx.BlendMode);
34+
paint.setColor(Sk.Color("cyan"));
35+
canvas2.drawCircle(r, r, r, paint);
36+
paint.setColor(Sk.Color("magenta"));
37+
canvas2.drawCircle(size - r, r, r, paint);
38+
paint.setColor(Sk.Color("yellow"));
39+
canvas2.drawCircle(size / 2, size - r, r, paint);
40+
const picture = recorder.finishRecordingAsPicture();
41+
canvas.drawPicture(picture);
42+
surf.flush();
43+
return surf.makeImageSnapshot().encodeToBase64();
44+
},
45+
{ BlendMode: BlendMode.Multiply, size: surface.width }
46+
);
47+
const image = Skia.Image.MakeImageFromEncoded(Skia.Data.fromBase64(str))!;
48+
checkImage(image, "snapshots/pictures/hello-world.png");
49+
});
50+
});

package/src/renderer/components/Drawing.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import React from "react";
22

33
import type { CustomDrawingNodeProps } from "../../dom/types";
44

5+
/**
6+
* @deprecated If you are looking to use the Skia imperative API, you can use:
7+
* The picture API: https://shopify.github.io/react-native-skia/docs/shapes/pictures/
8+
* The offscreen API: https://shopify.github.io/react-native-skia/docs/animations/textures
9+
*/
510
export const Drawing = (props: CustomDrawingNodeProps) => {
611
return <skDrawing {...props} />;
712
};

package/src/skia/core/Picture.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import { Skia } from "../Skia";
2-
import type { SkCanvas, SkRect } from "../types";
2+
import { isRect, type SkCanvas, type SkRect, type SkSize } from "../types";
33

44
/**
55
* Memoizes and returns an SkPicture that can be drawn to another canvas.
66
* @param rect Picture bounds
77
* @param cb Callback for drawing to the canvas
88
* @returns SkPicture
99
*/
10-
export const createPicture = (rect: SkRect, cb: (canvas: SkCanvas) => void) => {
10+
export const createPicture = (
11+
rect: SkRect | SkSize,
12+
cb: (canvas: SkCanvas) => void
13+
) => {
1114
const recorder = Skia.PictureRecorder();
12-
const canvas = recorder.beginRecording(rect);
15+
const canvas = recorder.beginRecording(
16+
isRect(rect) ? rect : Skia.XYWHRect(0, 0, rect.width, rect.height)
17+
);
1318
cb(canvas);
1419
return recorder.finishRecordingAsPicture();
1520
};

package/src/skia/types/Rect.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,16 @@ export interface SkRect {
44
readonly width: number;
55
readonly height: number;
66
}
7+
8+
export const isRect = (def: unknown): def is SkRect => {
9+
if (typeof def === "object" && def !== null) {
10+
const rect = def as SkRect;
11+
return (
12+
typeof rect.x === "number" &&
13+
typeof rect.y === "number" &&
14+
typeof rect.width === "number" &&
15+
typeof rect.height === "number"
16+
);
17+
}
18+
return false;
19+
};

package/src/views/SkiaView.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,20 @@ export const SkiaViewNativeId = { current: 1000 };
1111

1212
const NativeSkiaView = SkiaDrawViewNativeComponent;
1313

14+
/**
15+
* @deprecated If you are looking to use the Skia imperative API, you can use:
16+
* The picture API: https://shopify.github.io/react-native-skia/docs/shapes/pictures/
17+
* The offscreen API: https://shopify.github.io/react-native-skia/docs/animations/textures
18+
*/
1419
export class SkiaView extends React.Component<SkiaDrawViewProps> {
1520
constructor(props: SkiaDrawViewProps) {
1621
super(props);
22+
console.warn(
23+
`The SkiaView component is deprecated and will be removed in the next release.
24+
If you are looking to use the Skia imperative API, you can use:
25+
* The picture API: https://shopify.github.io/react-native-skia/docs/shapes/pictures/
26+
* The offscreen API: https://shopify.github.io/react-native-skia/docs/animations/textures`
27+
);
1728
this._nativeId = SkiaViewNativeId.current++;
1829
const { onDraw, onSize } = props;
1930
if (onDraw) {

0 commit comments

Comments
 (0)