@shopify/react-native-skia 0.1.189 → 0.1.190
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.
- package/jestSetup.js +17 -3
- package/lib/commonjs/Platform/IPlatform.d.ts +12 -0
- package/lib/commonjs/Platform/IPlatform.js +6 -0
- package/lib/commonjs/Platform/IPlatform.js.map +1 -0
- package/lib/commonjs/Platform/Platform.d.ts +2 -0
- package/lib/commonjs/Platform/Platform.js +24 -0
- package/lib/commonjs/Platform/Platform.js.map +1 -0
- package/lib/commonjs/Platform/Platform.web.d.ts +2 -0
- package/lib/commonjs/Platform/Platform.web.js +157 -0
- package/lib/commonjs/Platform/Platform.web.js.map +1 -0
- package/lib/commonjs/Platform/index.d.ts +1 -0
- package/lib/commonjs/Platform/index.js +19 -0
- package/lib/commonjs/Platform/index.js.map +1 -0
- package/lib/commonjs/skia/NativeSetup.js +3 -3
- package/lib/commonjs/skia/NativeSetup.js.map +1 -1
- package/lib/commonjs/skia/core/Data.js +2 -8
- package/lib/commonjs/skia/core/Data.js.map +1 -1
- package/lib/commonjs/skia/core/Image.js +3 -3
- package/lib/commonjs/skia/core/Image.js.map +1 -1
- package/lib/commonjs/views/SkiaBaseWebView.d.ts +6 -1
- package/lib/commonjs/views/SkiaBaseWebView.js +32 -25
- package/lib/commonjs/views/SkiaBaseWebView.js.map +1 -1
- package/lib/commonjs/views/SkiaDomView.js +2 -2
- package/lib/commonjs/views/SkiaDomView.js.map +1 -1
- package/lib/commonjs/views/SkiaPictureView.js +2 -2
- package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
- package/lib/commonjs/views/SkiaView.js +3 -2
- package/lib/commonjs/views/SkiaView.js.map +1 -1
- package/lib/commonjs/views/useTouchHandler.js +3 -3
- package/lib/commonjs/views/useTouchHandler.js.map +1 -1
- package/lib/commonjs/web/WithSkiaWeb.js +2 -2
- package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
- package/lib/module/Platform/IPlatform.d.ts +12 -0
- package/lib/module/Platform/IPlatform.js +2 -0
- package/lib/module/Platform/IPlatform.js.map +1 -0
- package/lib/module/Platform/Platform.d.ts +2 -0
- package/lib/module/Platform/Platform.js +14 -0
- package/lib/module/Platform/Platform.js.map +1 -0
- package/lib/module/Platform/Platform.web.d.ts +2 -0
- package/lib/module/Platform/Platform.web.js +143 -0
- package/lib/module/Platform/Platform.web.js.map +1 -0
- package/lib/module/Platform/index.d.ts +1 -0
- package/lib/module/Platform/index.js +2 -0
- package/lib/module/Platform/index.js.map +1 -0
- package/lib/module/skia/NativeSetup.js +2 -2
- package/lib/module/skia/NativeSetup.js.map +1 -1
- package/lib/module/skia/core/Data.js +2 -7
- package/lib/module/skia/core/Data.js.map +1 -1
- package/lib/module/skia/core/Image.js +2 -2
- package/lib/module/skia/core/Image.js.map +1 -1
- package/lib/module/views/SkiaBaseWebView.d.ts +6 -1
- package/lib/module/views/SkiaBaseWebView.js +31 -24
- package/lib/module/views/SkiaBaseWebView.js.map +1 -1
- package/lib/module/views/SkiaDomView.js +2 -2
- package/lib/module/views/SkiaDomView.js.map +1 -1
- package/lib/module/views/SkiaPictureView.js +2 -2
- package/lib/module/views/SkiaPictureView.js.map +1 -1
- package/lib/module/views/SkiaView.js +2 -2
- package/lib/module/views/SkiaView.js.map +1 -1
- package/lib/module/views/useTouchHandler.js +3 -3
- package/lib/module/views/useTouchHandler.js.map +1 -1
- package/lib/module/web/WithSkiaWeb.js +1 -1
- package/lib/module/web/WithSkiaWeb.js.map +1 -1
- package/lib/typescript/src/Platform/IPlatform.d.ts +12 -0
- package/lib/typescript/src/Platform/Platform.d.ts +2 -0
- package/lib/typescript/src/Platform/Platform.web.d.ts +2 -0
- package/lib/typescript/src/Platform/index.d.ts +1 -0
- package/lib/typescript/src/views/SkiaBaseWebView.d.ts +6 -1
- package/package.json +9 -9
- package/src/Platform/IPlatform.ts +20 -0
- package/src/Platform/Platform.ts +28 -0
- package/src/Platform/Platform.web.tsx +136 -0
- package/src/Platform/index.ts +1 -0
- package/src/skia/NativeSetup.ts +2 -2
- package/src/skia/core/Data.ts +4 -15
- package/src/skia/core/Image.ts +2 -3
- package/src/views/SkiaBaseWebView.tsx +24 -19
- package/src/views/SkiaDomView.tsx +2 -2
- package/src/views/SkiaPictureView.tsx +2 -2
- package/src/views/SkiaView.tsx +2 -2
- package/src/views/useTouchHandler.ts +3 -3
- package/src/web/WithSkiaWeb.tsx +2 -1
@@ -0,0 +1,136 @@
|
|
1
|
+
import type { RefObject, CSSProperties } from "react";
|
2
|
+
import React, { useLayoutEffect, useMemo, useRef } from "react";
|
3
|
+
import type { LayoutChangeEvent, ViewComponent, ViewProps } from "react-native";
|
4
|
+
|
5
|
+
import type { DataModule } from "../skia/types";
|
6
|
+
import { isRNModule } from "../skia/types";
|
7
|
+
|
8
|
+
import type { IPlatform } from "./IPlatform";
|
9
|
+
|
10
|
+
// eslint-disable-next-line max-len
|
11
|
+
// https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/modules/useElementLayout/index.js
|
12
|
+
const DOM_LAYOUT_HANDLER_NAME = "__reactLayoutHandler";
|
13
|
+
type OnLayout = ((event: LayoutChangeEvent) => void) | undefined;
|
14
|
+
type Div = HTMLDivElement & {
|
15
|
+
__reactLayoutHandler: OnLayout;
|
16
|
+
};
|
17
|
+
|
18
|
+
let resizeObserver: ResizeObserver | null = null;
|
19
|
+
|
20
|
+
const getObserver = () => {
|
21
|
+
if (resizeObserver == null) {
|
22
|
+
resizeObserver = new window.ResizeObserver(function (entries) {
|
23
|
+
entries.forEach((entry) => {
|
24
|
+
const node = entry.target as Div;
|
25
|
+
const { left, top, width, height } = entry.contentRect;
|
26
|
+
const onLayout = node[DOM_LAYOUT_HANDLER_NAME];
|
27
|
+
if (typeof onLayout === "function") {
|
28
|
+
// setTimeout 0 is taken from react-native-web (UIManager)
|
29
|
+
setTimeout(
|
30
|
+
() =>
|
31
|
+
onLayout({
|
32
|
+
timeStamp: Date.now(),
|
33
|
+
nativeEvent: { layout: { x: left, y: top, width, height } },
|
34
|
+
currentTarget: 0,
|
35
|
+
target: 0,
|
36
|
+
bubbles: false,
|
37
|
+
cancelable: false,
|
38
|
+
defaultPrevented: false,
|
39
|
+
eventPhase: 0,
|
40
|
+
isDefaultPrevented() {
|
41
|
+
throw new Error("Method not supported on web.");
|
42
|
+
},
|
43
|
+
isPropagationStopped() {
|
44
|
+
throw new Error("Method not supported on web.");
|
45
|
+
},
|
46
|
+
persist() {
|
47
|
+
throw new Error("Method not supported on web.");
|
48
|
+
},
|
49
|
+
preventDefault() {
|
50
|
+
throw new Error("Method not supported on web.");
|
51
|
+
},
|
52
|
+
stopPropagation() {
|
53
|
+
throw new Error("Method not supported on web.");
|
54
|
+
},
|
55
|
+
isTrusted: true,
|
56
|
+
type: "",
|
57
|
+
}),
|
58
|
+
0
|
59
|
+
);
|
60
|
+
}
|
61
|
+
});
|
62
|
+
});
|
63
|
+
}
|
64
|
+
return resizeObserver;
|
65
|
+
};
|
66
|
+
|
67
|
+
const useElementLayout = (ref: RefObject<Div>, onLayout: OnLayout) => {
|
68
|
+
const observer = getObserver();
|
69
|
+
|
70
|
+
useLayoutEffect(() => {
|
71
|
+
const node = ref.current;
|
72
|
+
if (node !== null) {
|
73
|
+
node[DOM_LAYOUT_HANDLER_NAME] = onLayout;
|
74
|
+
}
|
75
|
+
}, [ref, onLayout]);
|
76
|
+
|
77
|
+
useLayoutEffect(() => {
|
78
|
+
const node = ref.current;
|
79
|
+
if (node != null && observer != null) {
|
80
|
+
if (typeof node[DOM_LAYOUT_HANDLER_NAME] === "function") {
|
81
|
+
observer.observe(node);
|
82
|
+
} else {
|
83
|
+
observer.unobserve(node);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
return () => {
|
87
|
+
if (node != null && observer != null) {
|
88
|
+
observer.unobserve(node);
|
89
|
+
}
|
90
|
+
};
|
91
|
+
}, [observer, ref]);
|
92
|
+
};
|
93
|
+
|
94
|
+
const View = (({ children, onLayout, style: rawStyle }: ViewProps) => {
|
95
|
+
const style = useMemo(() => (rawStyle ?? {}) as CSSProperties, [rawStyle]);
|
96
|
+
const ref = useRef<Div>(null);
|
97
|
+
useElementLayout(ref, onLayout);
|
98
|
+
const cssStyles = useMemo(() => {
|
99
|
+
return {
|
100
|
+
...style,
|
101
|
+
display: "flex",
|
102
|
+
flexDirection: style.flexDirection || "column",
|
103
|
+
flexWrap: style.flexWrap || "nowrap",
|
104
|
+
justifyContent: style.justifyContent || "flex-start",
|
105
|
+
alignItems: style.alignItems || "stretch",
|
106
|
+
alignContent: style.alignContent || "stretch",
|
107
|
+
};
|
108
|
+
}, [style]);
|
109
|
+
|
110
|
+
return (
|
111
|
+
<div ref={ref} style={cssStyles}>
|
112
|
+
{children}
|
113
|
+
</div>
|
114
|
+
);
|
115
|
+
}) as unknown as typeof ViewComponent;
|
116
|
+
|
117
|
+
export const Platform: IPlatform = {
|
118
|
+
OS: "web",
|
119
|
+
PixelRatio: window.devicePixelRatio,
|
120
|
+
requireNativeComponent: () => {
|
121
|
+
throw new Error("requireNativeComponent is not supported on the web");
|
122
|
+
},
|
123
|
+
resolveAsset: (source: DataModule) => {
|
124
|
+
if (isRNModule(source)) {
|
125
|
+
throw new Error(
|
126
|
+
"Image source is a number - this is not supported on the web"
|
127
|
+
);
|
128
|
+
}
|
129
|
+
return source.default;
|
130
|
+
},
|
131
|
+
findNodeHandle: () => {
|
132
|
+
throw new Error("findNodeHandle is not supported on the web");
|
133
|
+
},
|
134
|
+
NativeModules: {},
|
135
|
+
View,
|
136
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./Platform";
|
package/src/skia/NativeSetup.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
import {
|
1
|
+
import { Platform } from "../Platform";
|
2
2
|
|
3
3
|
if (Platform.OS !== "web" && global.SkiaApi == null) {
|
4
4
|
// Initialize RN Skia
|
5
|
-
const SkiaModule = NativeModules.RNSkia;
|
5
|
+
const SkiaModule = Platform.NativeModules.RNSkia;
|
6
6
|
if (SkiaModule == null || typeof SkiaModule.install !== "function") {
|
7
7
|
throw new Error(
|
8
8
|
"Native RNSkia Module cannot be found! Make sure you correctly " +
|
package/src/skia/core/Data.ts
CHANGED
@@ -1,20 +1,8 @@
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
2
|
-
import { Image } from "react-native";
|
3
2
|
|
4
3
|
import { Skia } from "../Skia";
|
5
|
-
import {
|
6
|
-
import
|
7
|
-
SkData,
|
8
|
-
DataModule,
|
9
|
-
DataSourceParam,
|
10
|
-
JsiDisposable,
|
11
|
-
} from "../types";
|
12
|
-
|
13
|
-
const resolveAsset = (source: DataModule) => {
|
14
|
-
return isRNModule(source)
|
15
|
-
? Image.resolveAssetSource(source).uri
|
16
|
-
: source.default;
|
17
|
-
};
|
4
|
+
import type { SkData, DataSourceParam, JsiDisposable } from "../types";
|
5
|
+
import { Platform } from "../../Platform";
|
18
6
|
|
19
7
|
const factoryWrapper = <T>(
|
20
8
|
data2: SkData,
|
@@ -42,7 +30,8 @@ const loadData = <T>(
|
|
42
30
|
resolve(factoryWrapper(Skia.Data.fromBytes(source), factory, onError))
|
43
31
|
);
|
44
32
|
} else {
|
45
|
-
const uri =
|
33
|
+
const uri =
|
34
|
+
typeof source === "string" ? source : Platform.resolveAsset(source);
|
46
35
|
return Skia.Data.fromURI(uri).then((d) =>
|
47
36
|
factoryWrapper(d, factory, onError)
|
48
37
|
);
|
package/src/skia/core/Image.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { Platform } from "../../Platform";
|
3
2
|
import { Skia } from "../Skia";
|
4
3
|
import type { DataSourceParam, SkImage } from "../types";
|
5
4
|
|
@@ -48,7 +47,7 @@ export const makeImageFromView = <
|
|
48
47
|
);
|
49
48
|
}
|
50
49
|
}
|
51
|
-
const viewTag = findNodeHandle(viewRef.current);
|
50
|
+
const viewTag = Platform.findNodeHandle(viewRef.current);
|
52
51
|
if (viewTag !== null && viewTag !== 0) {
|
53
52
|
return Skia.Image.MakeImageFromViewTag(viewTag);
|
54
53
|
}
|
@@ -2,16 +2,16 @@
|
|
2
2
|
import React from "react";
|
3
3
|
import type { PointerEvent } from "react";
|
4
4
|
import type { LayoutChangeEvent } from "react-native";
|
5
|
-
import { PixelRatio, View } from "react-native";
|
6
5
|
|
7
6
|
import type { SkRect, SkCanvas } from "../skia/types";
|
8
7
|
import type { SkiaValue } from "../values";
|
9
8
|
import { JsiSkSurface } from "../skia/web/JsiSkSurface";
|
9
|
+
import { Platform } from "../Platform";
|
10
10
|
|
11
11
|
import type { DrawMode, SkiaBaseViewProps, TouchInfo } from "./types";
|
12
12
|
import { TouchType } from "./types";
|
13
13
|
|
14
|
-
const pd = PixelRatio
|
14
|
+
const pd = Platform.PixelRatio;
|
15
15
|
|
16
16
|
export abstract class SkiaBaseWebView<
|
17
17
|
TProps extends SkiaBaseViewProps
|
@@ -38,17 +38,16 @@ export abstract class SkiaBaseWebView<
|
|
38
38
|
this._unsubscriptions = [];
|
39
39
|
}
|
40
40
|
|
41
|
-
private
|
41
|
+
private onLayoutEvent(evt: LayoutChangeEvent) {
|
42
42
|
const { CanvasKit } = global;
|
43
|
-
const { width, height } = evt.nativeEvent.layout;
|
44
|
-
this.width = width;
|
45
|
-
this.height = height;
|
46
43
|
// Reset canvas / surface on layout change
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
const canvas = this._canvasRef.current;
|
45
|
+
if (canvas) {
|
46
|
+
this.width = canvas.clientWidth;
|
47
|
+
this.height = canvas.clientHeight;
|
48
|
+
canvas.width = this.width * pd;
|
49
|
+
canvas.height = this.height * pd;
|
50
|
+
const surface = CanvasKit.MakeWebGLCanvasSurface(canvas);
|
52
51
|
if (!surface) {
|
53
52
|
throw new Error("Could not create surface");
|
54
53
|
}
|
@@ -178,21 +177,27 @@ export abstract class SkiaBaseWebView<
|
|
178
177
|
return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);
|
179
178
|
}
|
180
179
|
|
180
|
+
private onStart = this.createTouchHandler(TouchType.Start);
|
181
|
+
private onActive = this.createTouchHandler(TouchType.Active);
|
182
|
+
private onCancel = this.createTouchHandler(TouchType.Cancelled);
|
183
|
+
private onEnd = this.createTouchHandler(TouchType.End);
|
184
|
+
private onLayout = this.onLayoutEvent.bind(this);
|
185
|
+
|
181
186
|
render() {
|
182
187
|
const { mode, debug = false, ...viewProps } = this.props;
|
183
188
|
return (
|
184
|
-
<View {...viewProps} onLayout={this.onLayout
|
189
|
+
<Platform.View {...viewProps} onLayout={this.onLayout}>
|
185
190
|
<canvas
|
186
191
|
ref={this._canvasRef}
|
187
192
|
style={{ display: "flex", flex: 1 }}
|
188
|
-
onPointerDown={this.
|
189
|
-
onPointerMove={this.
|
190
|
-
onPointerUp={this.
|
191
|
-
onPointerCancel={this.
|
192
|
-
onPointerLeave={this.
|
193
|
-
onPointerOut={this.
|
193
|
+
onPointerDown={this.onStart}
|
194
|
+
onPointerMove={this.onActive}
|
195
|
+
onPointerUp={this.onEnd}
|
196
|
+
onPointerCancel={this.onCancel}
|
197
|
+
onPointerLeave={this.onEnd}
|
198
|
+
onPointerOut={this.onEnd}
|
194
199
|
/>
|
195
|
-
</View>
|
200
|
+
</Platform.View>
|
196
201
|
);
|
197
202
|
}
|
198
203
|
}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import React from "react";
|
2
|
-
import { requireNativeComponent, Platform } from "react-native";
|
3
2
|
import type { HostComponent } from "react-native";
|
4
3
|
|
5
4
|
import type { SkRect } from "../skia/types";
|
6
5
|
import type { SkiaValue } from "../values";
|
6
|
+
import { Platform } from "../Platform";
|
7
7
|
|
8
8
|
import { SkiaViewApi } from "./api";
|
9
9
|
import { SkiaViewNativeId } from "./SkiaView";
|
@@ -11,7 +11,7 @@ import type { NativeSkiaViewProps, SkiaDomViewProps } from "./types";
|
|
11
11
|
|
12
12
|
const NativeSkiaDomView: HostComponent<SkiaDomViewProps> =
|
13
13
|
Platform.OS !== "web"
|
14
|
-
? requireNativeComponent<NativeSkiaViewProps>("SkiaDomView")
|
14
|
+
? Platform.requireNativeComponent<NativeSkiaViewProps>("SkiaDomView")
|
15
15
|
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
16
16
|
(null as any);
|
17
17
|
|
@@ -1,15 +1,15 @@
|
|
1
1
|
import React from "react";
|
2
|
-
import { requireNativeComponent } from "react-native";
|
3
2
|
|
4
3
|
import type { SkRect } from "../skia/types";
|
5
4
|
import type { SkiaValue } from "../values";
|
5
|
+
import { Platform } from "../Platform";
|
6
6
|
|
7
7
|
import { SkiaViewApi } from "./api";
|
8
8
|
import { SkiaViewNativeId } from "./SkiaView";
|
9
9
|
import type { NativeSkiaViewProps, SkiaPictureViewProps } from "./types";
|
10
10
|
|
11
11
|
const NativeSkiaPictureView =
|
12
|
-
requireNativeComponent<NativeSkiaViewProps>("SkiaPictureView");
|
12
|
+
Platform.requireNativeComponent<NativeSkiaViewProps>("SkiaPictureView");
|
13
13
|
|
14
14
|
export class SkiaPictureView extends React.Component<SkiaPictureViewProps> {
|
15
15
|
constructor(props: SkiaPictureViewProps) {
|
package/src/views/SkiaView.tsx
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
import React from "react";
|
2
|
-
import { requireNativeComponent } from "react-native";
|
3
2
|
|
4
3
|
import type { SkRect } from "../skia/types";
|
5
4
|
import type { SkiaValue } from "../values";
|
5
|
+
import { Platform } from "../Platform";
|
6
6
|
|
7
7
|
import { SkiaViewApi } from "./api";
|
8
8
|
import type { NativeSkiaViewProps, SkiaDrawViewProps } from "./types";
|
@@ -10,7 +10,7 @@ import type { NativeSkiaViewProps, SkiaDrawViewProps } from "./types";
|
|
10
10
|
export const SkiaViewNativeId = { current: 1000 };
|
11
11
|
|
12
12
|
const NativeSkiaView =
|
13
|
-
requireNativeComponent<NativeSkiaViewProps>("SkiaDrawView");
|
13
|
+
Platform.requireNativeComponent<NativeSkiaViewProps>("SkiaDrawView");
|
14
14
|
|
15
15
|
export class SkiaView extends React.Component<SkiaDrawViewProps> {
|
16
16
|
constructor(props: SkiaDrawViewProps) {
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import type { DependencyList } from "react";
|
2
2
|
import { useCallback, useRef } from "react";
|
3
|
-
import { PixelRatio } from "react-native";
|
4
3
|
|
5
4
|
import type { Vector } from "../skia/types";
|
5
|
+
import { Platform } from "../Platform";
|
6
6
|
|
7
7
|
import type {
|
8
8
|
ExtendedTouchInfo,
|
@@ -46,8 +46,8 @@ const useInternalTouchHandler = (
|
|
46
46
|
timeDiffseconds > 0
|
47
47
|
) {
|
48
48
|
prevVelocityRef.current[touch.id] = {
|
49
|
-
x: distX / timeDiffseconds / PixelRatio
|
50
|
-
y: distY / timeDiffseconds / PixelRatio
|
49
|
+
x: distX / timeDiffseconds / Platform.PixelRatio,
|
50
|
+
y: distY / timeDiffseconds / Platform.PixelRatio,
|
51
51
|
};
|
52
52
|
}
|
53
53
|
|
package/src/web/WithSkiaWeb.tsx
CHANGED