Skip to content

Commit 6407a4f

Browse files
authored
Merge pull request #2138 from Shopify/sg
Fix regression with shouldUseJSDomOnNative=true
2 parents a9e4b34 + 33a1e71 commit 6407a4f

File tree

2 files changed

+131
-3
lines changed

2 files changed

+131
-3
lines changed

package/src/renderer/Canvas.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import type {
1515
import type { LayoutChangeEvent } from "react-native";
1616

1717
import { SkiaDomView } from "../views";
18-
import { SkiaDomView as SkiaDomViewWeb } from "../views/SkiaDomView.web";
1918
import { Skia } from "../skia/Skia";
2019
import type { TouchHandler, SkiaBaseViewProps } from "../views";
20+
import { SkiaDomView2 } from "../views/SkiaDomView2";
21+
import { Platform } from "../Platform";
2122

2223
import { SkiaRoot } from "./Reconciler";
2324
import { NATIVE_DOM } from "./HostComponents";
@@ -90,7 +91,7 @@ export const Canvas = forwardRef<SkiaDomView, CanvasProps>(
9091
};
9192
}, [root]);
9293

93-
if (NATIVE_DOM) {
94+
if (NATIVE_DOM || Platform.OS === "web") {
9495
return (
9596
<SkiaDomView
9697
ref={ref}
@@ -105,7 +106,8 @@ export const Canvas = forwardRef<SkiaDomView, CanvasProps>(
105106
);
106107
} else {
107108
return (
108-
<SkiaDomViewWeb
109+
<SkiaDomView2
110+
Skia={Skia}
109111
// eslint-disable-next-line @typescript-eslint/no-explicit-any
110112
ref={ref as any}
111113
style={style}

package/src/views/SkiaDomView2.tsx

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import React from "react";
2+
import type { HostComponent } from "react-native";
3+
4+
import type { Skia, SkRect } from "../skia/types";
5+
import { Platform } from "../Platform";
6+
import SkiaPictureViewNativeComponent from "../specs/SkiaPictureViewNativeComponent";
7+
import { JsiDrawingContext } from "../dom/types";
8+
9+
import { SkiaViewApi } from "./api";
10+
import type { SkiaPictureViewProps, SkiaDomViewProps } from "./types";
11+
import { SkiaViewNativeId } from "./SkiaViewNativeId";
12+
13+
const NativeSkiaPictureView: HostComponent<SkiaPictureViewProps> =
14+
Platform.OS !== "web"
15+
? SkiaPictureViewNativeComponent
16+
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
17+
(null as any);
18+
19+
export class SkiaDomView2 extends React.Component<
20+
SkiaDomViewProps & { Skia: Skia }
21+
> {
22+
constructor(props: SkiaDomViewProps & { Skia: Skia }) {
23+
super(props);
24+
this._nativeId = SkiaViewNativeId.current++;
25+
const { root, onTouch, onSize } = props;
26+
if (root) {
27+
assertSkiaViewApi();
28+
SkiaViewApi.setJsiProperty(this._nativeId, "root", root);
29+
}
30+
if (onTouch) {
31+
assertSkiaViewApi();
32+
SkiaViewApi.setJsiProperty(this._nativeId, "onTouch", onTouch);
33+
}
34+
if (onSize) {
35+
assertSkiaViewApi();
36+
SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
37+
}
38+
}
39+
40+
private _nativeId: number;
41+
42+
public get nativeId() {
43+
return this._nativeId;
44+
}
45+
46+
componentDidUpdate(prevProps: SkiaDomViewProps & { Skia: Skia }) {
47+
const { root, onTouch, onSize } = this.props;
48+
if (root !== prevProps.root && root !== undefined) {
49+
assertSkiaViewApi();
50+
this.draw();
51+
}
52+
if (onTouch !== prevProps.onTouch) {
53+
assertSkiaViewApi();
54+
SkiaViewApi.setJsiProperty(this._nativeId, "onTouch", onTouch);
55+
}
56+
if (onSize !== prevProps.onSize) {
57+
assertSkiaViewApi();
58+
SkiaViewApi.setJsiProperty(this._nativeId, "onSize", onSize);
59+
}
60+
}
61+
62+
/**
63+
* Creates a snapshot from the canvas in the surface
64+
* @param rect Rect to use as bounds. Optional.
65+
* @returns An Image object.
66+
*/
67+
public makeImageSnapshot(rect?: SkRect) {
68+
assertSkiaViewApi();
69+
return SkiaViewApi.makeImageSnapshot(this._nativeId, rect);
70+
}
71+
72+
/**
73+
* Sends a redraw request to the native SkiaView.
74+
*/
75+
public redraw() {
76+
assertSkiaViewApi();
77+
this.draw();
78+
//SkiaViewApi.requestRedraw(this._nativeId);
79+
}
80+
81+
private draw() {
82+
const { root, Skia } = this.props;
83+
if (root !== undefined) {
84+
assertSkiaViewApi();
85+
const rec = Skia.PictureRecorder();
86+
const canvas = rec.beginRecording();
87+
const ctx = new JsiDrawingContext(Skia, canvas);
88+
root.render(ctx);
89+
const picture = rec.finishRecordingAsPicture();
90+
SkiaViewApi.setJsiProperty(this._nativeId, "picture", picture);
91+
}
92+
}
93+
94+
/**
95+
* Clear up the dom node when unmounting to release resources.
96+
*/
97+
componentWillUnmount(): void {
98+
assertSkiaViewApi();
99+
SkiaViewApi.setJsiProperty(this._nativeId, "picture", null);
100+
}
101+
102+
render() {
103+
const { mode, debug = false, ...viewProps } = this.props;
104+
return (
105+
<NativeSkiaPictureView
106+
collapsable={false}
107+
nativeID={`${this._nativeId}`}
108+
mode={mode}
109+
debug={debug}
110+
{...viewProps}
111+
/>
112+
);
113+
}
114+
}
115+
116+
const assertSkiaViewApi = () => {
117+
if (
118+
SkiaViewApi === null ||
119+
SkiaViewApi.setJsiProperty === null ||
120+
SkiaViewApi.callJsiMethod === null ||
121+
SkiaViewApi.requestRedraw === null ||
122+
SkiaViewApi.makeImageSnapshot === null
123+
) {
124+
throw Error("Skia View Api was not found.");
125+
}
126+
};

0 commit comments

Comments
 (0)