@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.
Files changed (82) hide show
  1. package/jestSetup.js +17 -3
  2. package/lib/commonjs/Platform/IPlatform.d.ts +12 -0
  3. package/lib/commonjs/Platform/IPlatform.js +6 -0
  4. package/lib/commonjs/Platform/IPlatform.js.map +1 -0
  5. package/lib/commonjs/Platform/Platform.d.ts +2 -0
  6. package/lib/commonjs/Platform/Platform.js +24 -0
  7. package/lib/commonjs/Platform/Platform.js.map +1 -0
  8. package/lib/commonjs/Platform/Platform.web.d.ts +2 -0
  9. package/lib/commonjs/Platform/Platform.web.js +157 -0
  10. package/lib/commonjs/Platform/Platform.web.js.map +1 -0
  11. package/lib/commonjs/Platform/index.d.ts +1 -0
  12. package/lib/commonjs/Platform/index.js +19 -0
  13. package/lib/commonjs/Platform/index.js.map +1 -0
  14. package/lib/commonjs/skia/NativeSetup.js +3 -3
  15. package/lib/commonjs/skia/NativeSetup.js.map +1 -1
  16. package/lib/commonjs/skia/core/Data.js +2 -8
  17. package/lib/commonjs/skia/core/Data.js.map +1 -1
  18. package/lib/commonjs/skia/core/Image.js +3 -3
  19. package/lib/commonjs/skia/core/Image.js.map +1 -1
  20. package/lib/commonjs/views/SkiaBaseWebView.d.ts +6 -1
  21. package/lib/commonjs/views/SkiaBaseWebView.js +32 -25
  22. package/lib/commonjs/views/SkiaBaseWebView.js.map +1 -1
  23. package/lib/commonjs/views/SkiaDomView.js +2 -2
  24. package/lib/commonjs/views/SkiaDomView.js.map +1 -1
  25. package/lib/commonjs/views/SkiaPictureView.js +2 -2
  26. package/lib/commonjs/views/SkiaPictureView.js.map +1 -1
  27. package/lib/commonjs/views/SkiaView.js +3 -2
  28. package/lib/commonjs/views/SkiaView.js.map +1 -1
  29. package/lib/commonjs/views/useTouchHandler.js +3 -3
  30. package/lib/commonjs/views/useTouchHandler.js.map +1 -1
  31. package/lib/commonjs/web/WithSkiaWeb.js +2 -2
  32. package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
  33. package/lib/module/Platform/IPlatform.d.ts +12 -0
  34. package/lib/module/Platform/IPlatform.js +2 -0
  35. package/lib/module/Platform/IPlatform.js.map +1 -0
  36. package/lib/module/Platform/Platform.d.ts +2 -0
  37. package/lib/module/Platform/Platform.js +14 -0
  38. package/lib/module/Platform/Platform.js.map +1 -0
  39. package/lib/module/Platform/Platform.web.d.ts +2 -0
  40. package/lib/module/Platform/Platform.web.js +143 -0
  41. package/lib/module/Platform/Platform.web.js.map +1 -0
  42. package/lib/module/Platform/index.d.ts +1 -0
  43. package/lib/module/Platform/index.js +2 -0
  44. package/lib/module/Platform/index.js.map +1 -0
  45. package/lib/module/skia/NativeSetup.js +2 -2
  46. package/lib/module/skia/NativeSetup.js.map +1 -1
  47. package/lib/module/skia/core/Data.js +2 -7
  48. package/lib/module/skia/core/Data.js.map +1 -1
  49. package/lib/module/skia/core/Image.js +2 -2
  50. package/lib/module/skia/core/Image.js.map +1 -1
  51. package/lib/module/views/SkiaBaseWebView.d.ts +6 -1
  52. package/lib/module/views/SkiaBaseWebView.js +31 -24
  53. package/lib/module/views/SkiaBaseWebView.js.map +1 -1
  54. package/lib/module/views/SkiaDomView.js +2 -2
  55. package/lib/module/views/SkiaDomView.js.map +1 -1
  56. package/lib/module/views/SkiaPictureView.js +2 -2
  57. package/lib/module/views/SkiaPictureView.js.map +1 -1
  58. package/lib/module/views/SkiaView.js +2 -2
  59. package/lib/module/views/SkiaView.js.map +1 -1
  60. package/lib/module/views/useTouchHandler.js +3 -3
  61. package/lib/module/views/useTouchHandler.js.map +1 -1
  62. package/lib/module/web/WithSkiaWeb.js +1 -1
  63. package/lib/module/web/WithSkiaWeb.js.map +1 -1
  64. package/lib/typescript/src/Platform/IPlatform.d.ts +12 -0
  65. package/lib/typescript/src/Platform/Platform.d.ts +2 -0
  66. package/lib/typescript/src/Platform/Platform.web.d.ts +2 -0
  67. package/lib/typescript/src/Platform/index.d.ts +1 -0
  68. package/lib/typescript/src/views/SkiaBaseWebView.d.ts +6 -1
  69. package/package.json +9 -9
  70. package/src/Platform/IPlatform.ts +20 -0
  71. package/src/Platform/Platform.ts +28 -0
  72. package/src/Platform/Platform.web.tsx +136 -0
  73. package/src/Platform/index.ts +1 -0
  74. package/src/skia/NativeSetup.ts +2 -2
  75. package/src/skia/core/Data.ts +4 -15
  76. package/src/skia/core/Image.ts +2 -3
  77. package/src/views/SkiaBaseWebView.tsx +24 -19
  78. package/src/views/SkiaDomView.tsx +2 -2
  79. package/src/views/SkiaPictureView.tsx +2 -2
  80. package/src/views/SkiaView.tsx +2 -2
  81. package/src/views/useTouchHandler.ts +3 -3
  82. 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";
@@ -1,8 +1,8 @@
1
- import { NativeModules, Platform } from "react-native";
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 " +
@@ -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 { isRNModule } from "../types";
6
- import type {
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 = typeof source === "string" ? source : resolveAsset(source);
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
  );
@@ -1,5 +1,4 @@
1
- import { findNodeHandle, Platform } from "react-native";
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.get();
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 onLayout(evt: LayoutChangeEvent) {
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
- if (this._canvasRef.current) {
48
- const canvas = this._canvasRef.current;
49
- canvas.width = width * pd;
50
- canvas.height = height * pd;
51
- const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);
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.bind(this)}>
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.createTouchHandler(TouchType.Start)}
189
- onPointerMove={this.createTouchHandler(TouchType.Active)}
190
- onPointerUp={this.createTouchHandler(TouchType.End)}
191
- onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}
192
- onPointerLeave={this.createTouchHandler(TouchType.End)}
193
- onPointerOut={this.createTouchHandler(TouchType.End)}
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) {
@@ -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.get(),
50
- y: distY / timeDiffseconds / PixelRatio.get(),
49
+ x: distX / timeDiffseconds / Platform.PixelRatio,
50
+ y: distY / timeDiffseconds / Platform.PixelRatio,
51
51
  };
52
52
  }
53
53
 
@@ -1,6 +1,7 @@
1
1
  import type { ComponentProps, ComponentType } from "react";
2
2
  import React, { useMemo, lazy, Suspense } from "react";
3
- import { Platform } from "react-native";
3
+
4
+ import { Platform } from "../Platform";
4
5
 
5
6
  import { LoadSkiaWeb } from "./LoadSkiaWeb";
6
7