Skip to content

Commit 121ebd4

Browse files
authoredFeb 8, 2025
fix(🌍): Fix RN Web support (#2954)
1 parent 55de322 commit 121ebd4

File tree

6 files changed

+239
-264
lines changed

6 files changed

+239
-264
lines changed
 

‎packages/skia/src/renderer/Canvas.web.tsx

-134
This file was deleted.

‎packages/skia/src/sksg/Container.ts

+7-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import Rea from "../external/reanimated/ReanimatedProxy";
22
import type { Skia, SkCanvas } from "../skia/types";
33
import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers";
44
import type { JsiRecorder } from "../skia/types/Recorder";
5-
import type { ISkiaViewApi } from "../views/types";
65

76
import type { Node } from "./Node";
87
import type { Recording } from "./Recorder/Recorder";
@@ -12,9 +11,7 @@ import { replay } from "./Recorder/Player";
1211
import { createDrawingContext } from "./Recorder/DrawingContext";
1312
import { ReanimatedRecorder } from "./Recorder/ReanimatedRecorder";
1413

15-
declare global {
16-
var SkiaViewApi: ISkiaViewApi;
17-
}
14+
import "../views/api";
1815

1916
const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
2017
"worklet";
@@ -29,8 +26,6 @@ const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
2926
//const end = performance.now();
3027
//console.log("Recording time: ", end - start);
3128
SkiaViewApi.setJsiProperty(nativeId, "picture", picture);
32-
rec.dispose();
33-
picture.dispose();
3429
};
3530

3631
const nativeDrawOnscreen = (nativeId: number, recorder: JsiRecorder) => {
@@ -145,24 +140,24 @@ class NativeReanimatedContainer extends Container {
145140
visit(recorder, this.root);
146141
const sharedValues = recorder.getSharedValues();
147142
const sharedRecorder = recorder.getRecorder();
143+
Rea.runOnUI(() => {
144+
"worklet";
145+
nativeDrawOnscreen(nativeId, sharedRecorder);
146+
})();
148147
if (sharedValues.length > 0) {
149148
this.mapperId = Rea.startMapper(() => {
150149
"worklet";
151150
sharedRecorder.applyUpdates(sharedValues);
152151
nativeDrawOnscreen(nativeId, sharedRecorder);
153152
}, sharedValues);
154153
}
155-
Rea.runOnUI(() => {
156-
"worklet";
157-
nativeDrawOnscreen(nativeId, sharedRecorder);
158-
})();
159154
}
160155
}
161156

162157
export const createContainer = (Skia: Skia, nativeId: number) => {
163-
const native = global.SkiaViewApi !== undefined;
158+
const web = global.SkiaViewApi && global.SkiaViewApi.web;
164159
if (HAS_REANIMATED_3 && nativeId !== -1) {
165-
if (native) {
160+
if (!web) {
166161
return new NativeReanimatedContainer(Skia, nativeId);
167162
} else {
168163
return new ReanimatedContainer(Skia, nativeId);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { SkRect } from "../skia/types";
2+
import type { ISkiaViewApi } from "../views/types";
3+
import type { SkiaPictureView } from "../views/SkiaPictureView.web";
4+
5+
export type ISkiaViewApiWeb = ISkiaViewApi & {
6+
views: Record<string, SkiaPictureView>;
7+
registerView(nativeId: string, view: SkiaPictureView): void;
8+
};
9+
10+
global.SkiaViewApi = {
11+
views: {},
12+
web: true,
13+
registerView(nativeId: string, view: SkiaPictureView) {
14+
this.views[nativeId] = view;
15+
},
16+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17+
setJsiProperty(nativeId: number, name: string, value: any) {
18+
if (name === "picture") {
19+
this.views[`${nativeId}`].setPicture(value);
20+
}
21+
},
22+
requestRedraw(nativeId: number) {
23+
this.views[`${nativeId}`].redraw();
24+
},
25+
makeImageSnapshot(nativeId: number, rect?: SkRect) {
26+
return this.views[`${nativeId}`].makeImageSnapshot(rect);
27+
},
28+
makeImageSnapshotAsync(nativeId: number, rect?: SkRect) {
29+
return new Promise((resolve, reject) => {
30+
const result = this.views[`${nativeId}`].makeImageSnapshot(rect);
31+
if (result) {
32+
resolve(result);
33+
} else {
34+
reject(new Error("Failed to make image snapshot"));
35+
}
36+
});
37+
},
38+
} as ISkiaViewApiWeb;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import type { ViewProps } from "react-native";
2+
import { createElement, useEffect, useRef } from "react";
3+
4+
import { SkiaPictureView } from "../views/SkiaPictureView.web";
5+
6+
import type { ISkiaViewApiWeb } from "./NativeSkiaModule.web";
7+
8+
export interface NativeProps extends ViewProps {
9+
debug?: boolean;
10+
opaque?: boolean;
11+
nativeID: string;
12+
}
13+
14+
const SkiaPictureViewNativeComponent = ({
15+
nativeID,
16+
debug,
17+
opaque,
18+
onLayout,
19+
...viewProps
20+
}: NativeProps) => {
21+
const ref = useRef(null);
22+
useEffect(() => {
23+
if (ref.current) {
24+
(global.SkiaViewApi as ISkiaViewApiWeb).registerView(
25+
nativeID,
26+
ref.current
27+
);
28+
}
29+
}, [nativeID]);
30+
return createElement(SkiaPictureView, {
31+
ref,
32+
debug,
33+
opaque,
34+
onLayout,
35+
...viewProps,
36+
});
37+
};
38+
// eslint-disable-next-line import/no-default-export
39+
export default SkiaPictureViewNativeComponent;

‎packages/skia/src/views/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type NativeSkiaViewProps = ViewProps & {
1010
};
1111

1212
export interface ISkiaViewApi {
13+
web?: boolean;
1314
setJsiProperty: <T>(nativeId: number, name: string, value: T) => void;
1415
requestRedraw: (nativeId: number) => void;
1516
makeImageSnapshot: (nativeId: number, rect?: SkRect) => SkImage;

0 commit comments

Comments
 (0)
Failed to load comments.