@shopify/react-native-skia 0.1.189 → 0.1.190

Sign up to get free protection for your applications and to get access to all the features.
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