@shopify/react-native-skia 1.3.3 → 1.3.4
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/android/cpp/jni/JniPlatformContext.cpp +4 -3
- package/lib/commonjs/external/reanimated/useVideo.js +22 -9
- package/lib/commonjs/external/reanimated/useVideo.js.map +1 -1
- package/lib/commonjs/external/reanimated/useVideoLoading.d.ts +4 -0
- package/lib/commonjs/external/reanimated/useVideoLoading.js +27 -0
- package/lib/commonjs/external/reanimated/useVideoLoading.js.map +1 -0
- package/lib/commonjs/external/reanimated/useVideoLoading.web.d.ts +4 -0
- package/lib/commonjs/external/reanimated/useVideoLoading.web.js +20 -0
- package/lib/commonjs/external/reanimated/useVideoLoading.web.js.map +1 -0
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.d.ts +3 -1
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js +4 -2
- package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -1
- package/lib/commonjs/skia/types/Skia.d.ts +1 -1
- package/lib/commonjs/skia/types/Skia.js.map +1 -1
- package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.d.ts +9 -0
- package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.js +30 -0
- package/lib/commonjs/skia/web/CanvasKitWebGLBufferImpl.js.map +1 -0
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +8 -2
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkia.js +2 -3
- package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
- package/lib/commonjs/skia/web/JsiVideo.d.ts +24 -0
- package/lib/commonjs/skia/web/JsiVideo.js +83 -0
- package/lib/commonjs/skia/web/JsiVideo.js.map +1 -0
- package/lib/commonjs/views/SkiaDomView.js +2 -0
- package/lib/commonjs/views/SkiaDomView.js.map +1 -1
- package/lib/commonjs/views/SkiaDomView.web.js +2 -0
- package/lib/commonjs/views/SkiaDomView.web.js.map +1 -1
- package/lib/commonjs/views/SkiaJSDomView.js +2 -0
- package/lib/commonjs/views/SkiaJSDomView.js.map +1 -1
- package/lib/module/external/reanimated/useVideo.js +22 -9
- package/lib/module/external/reanimated/useVideo.js.map +1 -1
- package/lib/module/external/reanimated/useVideoLoading.d.ts +4 -0
- package/lib/module/external/reanimated/useVideoLoading.js +20 -0
- package/lib/module/external/reanimated/useVideoLoading.js.map +1 -0
- package/lib/module/external/reanimated/useVideoLoading.web.d.ts +4 -0
- package/lib/module/external/reanimated/useVideoLoading.web.js +13 -0
- package/lib/module/external/reanimated/useVideoLoading.web.js.map +1 -0
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.d.ts +3 -1
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js +2 -1
- package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -1
- package/lib/module/skia/types/Skia.d.ts +1 -1
- package/lib/module/skia/types/Skia.js.map +1 -1
- package/lib/module/skia/web/CanvasKitWebGLBufferImpl.d.ts +9 -0
- package/lib/module/skia/web/CanvasKitWebGLBufferImpl.js +23 -0
- package/lib/module/skia/web/CanvasKitWebGLBufferImpl.js.map +1 -0
- package/lib/module/skia/web/JsiSkImageFactory.js +9 -3
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/skia/web/JsiSkia.js +2 -3
- package/lib/module/skia/web/JsiSkia.js.map +1 -1
- package/lib/module/skia/web/JsiVideo.d.ts +24 -0
- package/lib/module/skia/web/JsiVideo.js +75 -0
- package/lib/module/skia/web/JsiVideo.js.map +1 -0
- package/lib/module/views/SkiaDomView.js +2 -0
- package/lib/module/views/SkiaDomView.js.map +1 -1
- package/lib/module/views/SkiaDomView.web.js +2 -0
- package/lib/module/views/SkiaDomView.web.js.map +1 -1
- package/lib/module/views/SkiaJSDomView.js +2 -0
- package/lib/module/views/SkiaJSDomView.js.map +1 -1
- package/lib/typescript/src/external/reanimated/useVideoLoading.d.ts +4 -0
- package/lib/typescript/src/external/reanimated/useVideoLoading.web.d.ts +4 -0
- package/lib/typescript/src/skia/types/NativeBuffer/NativeBufferFactory.d.ts +3 -1
- package/lib/typescript/src/skia/types/Skia.d.ts +1 -1
- package/lib/typescript/src/skia/web/CanvasKitWebGLBufferImpl.d.ts +9 -0
- package/lib/typescript/src/skia/web/JsiVideo.d.ts +24 -0
- package/package.json +1 -1
- package/src/external/reanimated/useVideo.ts +25 -9
- package/src/external/reanimated/useVideoLoading.ts +28 -0
- package/src/external/reanimated/useVideoLoading.web.ts +17 -0
- package/src/skia/types/NativeBuffer/NativeBufferFactory.ts +10 -2
- package/src/skia/types/Skia.ts +1 -1
- package/src/skia/web/CanvasKitWebGLBufferImpl.ts +22 -0
- package/src/skia/web/JsiSkImageFactory.ts +16 -3
- package/src/skia/web/JsiSkia.ts +2 -3
- package/src/skia/web/JsiVideo.ts +96 -0
- package/src/views/SkiaDomView.tsx +4 -0
- package/src/views/SkiaDomView.web.tsx +4 -0
- package/src/views/SkiaJSDomView.tsx +4 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
|
3
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
4
|
+
import { CanvasKitWebGLBufferImpl } from "./CanvasKitWebGLBufferImpl";
|
|
5
|
+
import { JsiSkImageFactory } from "./JsiSkImageFactory";
|
|
6
|
+
export const createVideo = async (CanvasKit, url) => {
|
|
7
|
+
const video = document.createElement("video");
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
video.src = url;
|
|
10
|
+
video.style.display = "none";
|
|
11
|
+
video.crossOrigin = "anonymous";
|
|
12
|
+
video.volume = 0;
|
|
13
|
+
video.addEventListener("loadedmetadata", () => {
|
|
14
|
+
document.body.appendChild(video);
|
|
15
|
+
resolve(new JsiVideo(new JsiSkImageFactory(CanvasKit), video));
|
|
16
|
+
});
|
|
17
|
+
video.addEventListener("error", () => {
|
|
18
|
+
reject(new Error(`Failed to load video from URL: ${url}`));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export class JsiVideo {
|
|
23
|
+
constructor(ImageFactory, videoElement) {
|
|
24
|
+
this.ImageFactory = ImageFactory;
|
|
25
|
+
this.videoElement = videoElement;
|
|
26
|
+
_defineProperty(this, "__typename__", "Video");
|
|
27
|
+
_defineProperty(this, "webglBuffer", null);
|
|
28
|
+
document.body.appendChild(this.videoElement);
|
|
29
|
+
}
|
|
30
|
+
duration() {
|
|
31
|
+
return this.videoElement.duration * 1000;
|
|
32
|
+
}
|
|
33
|
+
framerate() {
|
|
34
|
+
throw new Error("Video.frame is not available on React Native Web");
|
|
35
|
+
}
|
|
36
|
+
setSurface(surface) {
|
|
37
|
+
// If we have the surface, we can use the WebGL buffer which is slightly faster
|
|
38
|
+
// This is because WebGL cannot be shared across contextes.
|
|
39
|
+
// This can be removed with WebGPU
|
|
40
|
+
this.webglBuffer = new CanvasKitWebGLBufferImpl(surface, this.videoElement);
|
|
41
|
+
}
|
|
42
|
+
nextImage() {
|
|
43
|
+
return this.ImageFactory.MakeImageFromNativeBuffer(this.webglBuffer ? this.webglBuffer : this.videoElement);
|
|
44
|
+
}
|
|
45
|
+
seek(time) {
|
|
46
|
+
if (isNaN(time)) {
|
|
47
|
+
throw new Error(`Invalid time: ${time}`);
|
|
48
|
+
}
|
|
49
|
+
this.videoElement.currentTime = time / 1000;
|
|
50
|
+
}
|
|
51
|
+
rotation() {
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
size() {
|
|
55
|
+
return {
|
|
56
|
+
width: this.videoElement.videoWidth,
|
|
57
|
+
height: this.videoElement.videoHeight
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
pause() {
|
|
61
|
+
this.videoElement.pause();
|
|
62
|
+
}
|
|
63
|
+
play() {
|
|
64
|
+
this.videoElement.play();
|
|
65
|
+
}
|
|
66
|
+
setVolume(volume) {
|
|
67
|
+
this.videoElement.volume = volume;
|
|
68
|
+
}
|
|
69
|
+
dispose() {
|
|
70
|
+
if (this.videoElement.parentNode) {
|
|
71
|
+
this.videoElement.parentNode.removeChild(this.videoElement);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=JsiVideo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["CanvasKitWebGLBufferImpl","JsiSkImageFactory","createVideo","CanvasKit","url","video","document","createElement","Promise","resolve","reject","src","style","display","crossOrigin","volume","addEventListener","body","appendChild","JsiVideo","Error","constructor","ImageFactory","videoElement","_defineProperty","duration","framerate","setSurface","surface","webglBuffer","nextImage","MakeImageFromNativeBuffer","seek","time","isNaN","currentTime","rotation","size","width","videoWidth","height","videoHeight","pause","play","setVolume","dispose","parentNode","removeChild"],"sources":["JsiVideo.ts"],"sourcesContent":["import type { CanvasKit, Surface } from \"canvaskit-wasm\";\n\nimport type { CanvasKitWebGLBuffer, Video, ImageFactory } from \"../types\";\n\nimport { CanvasKitWebGLBufferImpl } from \"./CanvasKitWebGLBufferImpl\";\nimport { JsiSkImageFactory } from \"./JsiSkImageFactory\";\n\nexport const createVideo = async (\n CanvasKit: CanvasKit,\n url: string\n): Promise<Video> => {\n const video = document.createElement(\"video\");\n return new Promise((resolve, reject) => {\n video.src = url;\n video.style.display = \"none\";\n video.crossOrigin = \"anonymous\";\n video.volume = 0;\n video.addEventListener(\"loadedmetadata\", () => {\n document.body.appendChild(video);\n resolve(new JsiVideo(new JsiSkImageFactory(CanvasKit), video));\n });\n video.addEventListener(\"error\", () => {\n reject(new Error(`Failed to load video from URL: ${url}`));\n });\n });\n};\n\nexport class JsiVideo implements Video {\n __typename__ = \"Video\" as const;\n\n private webglBuffer: CanvasKitWebGLBuffer | null = null;\n\n constructor(\n private ImageFactory: ImageFactory,\n private videoElement: HTMLVideoElement\n ) {\n document.body.appendChild(this.videoElement);\n }\n\n duration() {\n return this.videoElement.duration * 1000;\n }\n\n framerate(): number {\n throw new Error(\"Video.frame is not available on React Native Web\");\n }\n\n setSurface(surface: Surface) {\n // If we have the surface, we can use the WebGL buffer which is slightly faster\n // This is because WebGL cannot be shared across contextes.\n // This can be removed with WebGPU\n this.webglBuffer = new CanvasKitWebGLBufferImpl(surface, this.videoElement);\n }\n\n nextImage() {\n return this.ImageFactory.MakeImageFromNativeBuffer(\n this.webglBuffer ? this.webglBuffer : this.videoElement\n );\n }\n\n seek(time: number) {\n if (isNaN(time)) {\n throw new Error(`Invalid time: ${time}`);\n }\n this.videoElement.currentTime = time / 1000;\n }\n\n rotation() {\n return 0 as const;\n }\n\n size() {\n return {\n width: this.videoElement.videoWidth,\n height: this.videoElement.videoHeight,\n };\n }\n\n pause() {\n this.videoElement.pause();\n }\n\n play() {\n this.videoElement.play();\n }\n\n setVolume(volume: number) {\n this.videoElement.volume = volume;\n }\n\n dispose() {\n if (this.videoElement.parentNode) {\n this.videoElement.parentNode.removeChild(this.videoElement);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -26,6 +26,8 @@ export class SkiaDomView extends React.Component {
|
|
|
26
26
|
}
|
|
27
27
|
if (onTouch) {
|
|
28
28
|
assertSkiaViewApi();
|
|
29
|
+
console.warn(`The onTouch property is deprecated and will be removed in the next Skia release.
|
|
30
|
+
See: https://shopify.github.io/react-native-skia/docs/animations/gestures`);
|
|
29
31
|
SkiaViewApi.setJsiProperty(this._nativeId, "onTouch", onTouch);
|
|
30
32
|
}
|
|
31
33
|
if (onSize) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Platform","SkiaDomViewNativeComponent","SkiaViewApi","SkiaViewNativeId","NativeSkiaDomView","OS","SkiaDomView","Component","constructor","props","_defineProperty","_nativeId","current","root","onTouch","onSize","assertSkiaViewApi","setJsiProperty","nativeId","componentDidUpdate","prevProps","makeImageSnapshot","rect","makeImageSnapshotAsync","redraw","requestRedraw","componentWillUnmount","render","mode","debug","viewProps","createElement","_extends","collapsable","nativeID","callJsiMethod","Error"],"sources":["SkiaDomView.tsx"],"sourcesContent":["import React from \"react\";\nimport type { HostComponent } from \"react-native\";\n\nimport type { SkRect } from \"../skia/types\";\nimport { Platform } from \"../Platform\";\nimport SkiaDomViewNativeComponent from \"../specs/SkiaDomViewNativeComponent\";\n\nimport { SkiaViewApi } from \"./api\";\nimport type { SkiaDomViewProps } from \"./types\";\nimport { SkiaViewNativeId } from \"./SkiaViewNativeId\";\n\nconst NativeSkiaDomView: HostComponent<SkiaDomViewProps> =\n Platform.OS !== \"web\"\n ? SkiaDomViewNativeComponent\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (null as any);\n\nexport class SkiaDomView extends React.Component<SkiaDomViewProps> {\n constructor(props: SkiaDomViewProps) {\n super(props);\n this._nativeId = SkiaViewNativeId.current++;\n const { root, onTouch, onSize } = props;\n if (root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n private _nativeId: number;\n\n public get nativeId() {\n return this._nativeId;\n }\n\n componentDidUpdate(prevProps: SkiaDomViewProps) {\n const { root, onTouch, onSize } = this.props;\n if (root !== prevProps.root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch !== prevProps.onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize !== prevProps.onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshot(this._nativeId, rect);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshotAsync(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshotAsync(this._nativeId, rect);\n }\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n public redraw() {\n assertSkiaViewApi();\n SkiaViewApi.requestRedraw(this._nativeId);\n }\n\n /**\n * Clear up the dom node when unmounting to release resources.\n */\n componentWillUnmount(): void {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", null);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <NativeSkiaDomView\n collapsable={false}\n nativeID={`${this._nativeId}`}\n mode={mode}\n debug={debug}\n {...viewProps}\n />\n );\n }\n}\n\nconst assertSkiaViewApi = () => {\n if (\n SkiaViewApi === null ||\n SkiaViewApi.setJsiProperty === null ||\n SkiaViewApi.callJsiMethod === null ||\n SkiaViewApi.requestRedraw === null ||\n SkiaViewApi.makeImageSnapshot === null\n ) {\n throw Error(\"Skia View Api was not found.\");\n }\n};\n"],"mappings":";;;;AAAA,OAAOA,KAAK,MAAM,OAAO;AAIzB,SAASC,QAAQ,QAAQ,aAAa;AACtC,OAAOC,0BAA0B,MAAM,qCAAqC;AAE5E,SAASC,WAAW,QAAQ,OAAO;AAEnC,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,MAAMC,iBAAkD,GACtDJ,QAAQ,CAACK,EAAE,KAAK,KAAK,GACjBJ,0BAA0B;AAC1B;AACC,IAAY;AAEnB,OAAO,MAAMK,WAAW,SAASP,KAAK,CAACQ,SAAS,CAAmB;EACjEC,WAAWA,CAACC,KAAuB,EAAE;IACnC,KAAK,CAACA,KAAK,CAAC;IAACC,eAAA;IACb,IAAI,CAACC,SAAS,GAAGR,gBAAgB,CAACS,OAAO,EAAE;IAC3C,MAAM;MAAEC,IAAI;MAAEC,OAAO;MAAEC;IAAO,CAAC,GAAGN,KAAK;IACvC,IAAII,IAAI,EAAE;MACRG,iBAAiB,CAAC,CAAC;MACnBd,WAAW,CAACe,cAAc,CAAC,IAAI,CAACN,SAAS,EAAE,MAAM,EAAEE,IAAI,CAAC;IAC1D;IACA,IAAIC,OAAO,EAAE;MACXE,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["React","Platform","SkiaDomViewNativeComponent","SkiaViewApi","SkiaViewNativeId","NativeSkiaDomView","OS","SkiaDomView","Component","constructor","props","_defineProperty","_nativeId","current","root","onTouch","onSize","assertSkiaViewApi","setJsiProperty","console","warn","nativeId","componentDidUpdate","prevProps","makeImageSnapshot","rect","makeImageSnapshotAsync","redraw","requestRedraw","componentWillUnmount","render","mode","debug","viewProps","createElement","_extends","collapsable","nativeID","callJsiMethod","Error"],"sources":["SkiaDomView.tsx"],"sourcesContent":["import React from \"react\";\nimport type { HostComponent } from \"react-native\";\n\nimport type { SkRect } from \"../skia/types\";\nimport { Platform } from \"../Platform\";\nimport SkiaDomViewNativeComponent from \"../specs/SkiaDomViewNativeComponent\";\n\nimport { SkiaViewApi } from \"./api\";\nimport type { SkiaDomViewProps } from \"./types\";\nimport { SkiaViewNativeId } from \"./SkiaViewNativeId\";\n\nconst NativeSkiaDomView: HostComponent<SkiaDomViewProps> =\n Platform.OS !== \"web\"\n ? SkiaDomViewNativeComponent\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (null as any);\n\nexport class SkiaDomView extends React.Component<SkiaDomViewProps> {\n constructor(props: SkiaDomViewProps) {\n super(props);\n this._nativeId = SkiaViewNativeId.current++;\n const { root, onTouch, onSize } = props;\n if (root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch) {\n assertSkiaViewApi();\n console.warn(\n `The onTouch property is deprecated and will be removed in the next Skia release.\nSee: https://shopify.github.io/react-native-skia/docs/animations/gestures`\n );\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n private _nativeId: number;\n\n public get nativeId() {\n return this._nativeId;\n }\n\n componentDidUpdate(prevProps: SkiaDomViewProps) {\n const { root, onTouch, onSize } = this.props;\n if (root !== prevProps.root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch !== prevProps.onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize !== prevProps.onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshot(this._nativeId, rect);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshotAsync(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshotAsync(this._nativeId, rect);\n }\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n public redraw() {\n assertSkiaViewApi();\n SkiaViewApi.requestRedraw(this._nativeId);\n }\n\n /**\n * Clear up the dom node when unmounting to release resources.\n */\n componentWillUnmount(): void {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", null);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <NativeSkiaDomView\n collapsable={false}\n nativeID={`${this._nativeId}`}\n mode={mode}\n debug={debug}\n {...viewProps}\n />\n );\n }\n}\n\nconst assertSkiaViewApi = () => {\n if (\n SkiaViewApi === null ||\n SkiaViewApi.setJsiProperty === null ||\n SkiaViewApi.callJsiMethod === null ||\n SkiaViewApi.requestRedraw === null ||\n SkiaViewApi.makeImageSnapshot === null\n ) {\n throw Error(\"Skia View Api was not found.\");\n }\n};\n"],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export class SkiaDomView extends SkiaBaseWebView {
|
|
|
7
7
|
}
|
|
8
8
|
renderInCanvas(canvas, touches) {
|
|
9
9
|
if (this.props.onTouch) {
|
|
10
|
+
console.warn(`The onTouch property is deprecated and will be removed in the next Skia release.
|
|
11
|
+
See: https://shopify.github.io/react-native-skia/docs/animations/gestures`);
|
|
10
12
|
this.props.onTouch([touches]);
|
|
11
13
|
}
|
|
12
14
|
if (this.props.onSize) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Skia","JsiDrawingContext","SkiaBaseWebView","SkiaDomView","constructor","props","renderInCanvas","canvas","touches","onTouch","onSize","width","height","getSize","value","root","ctx","render"],"sources":["SkiaDomView.web.tsx"],"sourcesContent":["import { Skia } from \"../skia\";\nimport type { SkCanvas } from \"../skia/types\";\nimport { JsiDrawingContext } from \"../dom/types/DrawingContext\";\n\nimport { SkiaBaseWebView } from \"./SkiaBaseWebView\";\nimport type { SkiaDomViewProps, TouchInfo } from \"./types\";\n\nexport class SkiaDomView extends SkiaBaseWebView<SkiaDomViewProps> {\n constructor(props: SkiaDomViewProps) {\n super(props);\n }\n\n protected renderInCanvas(canvas: SkCanvas, touches: TouchInfo[]): void {\n if (this.props.onTouch) {\n this.props.onTouch([touches]);\n }\n if (this.props.onSize) {\n const { width, height } = this.getSize();\n this.props.onSize.value = { width, height };\n }\n if (this.props.root) {\n const ctx = new JsiDrawingContext(Skia, canvas);\n this.props.root.render(ctx);\n }\n }\n}\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,SAAS;AAE9B,SAASC,iBAAiB,QAAQ,6BAA6B;AAE/D,SAASC,eAAe,QAAQ,mBAAmB;AAGnD,OAAO,MAAMC,WAAW,SAASD,eAAe,CAAmB;EACjEE,WAAWA,CAACC,KAAuB,EAAE;IACnC,KAAK,CAACA,KAAK,CAAC;EACd;EAEUC,cAAcA,CAACC,MAAgB,EAAEC,OAAoB,EAAQ;IACrE,IAAI,IAAI,CAACH,KAAK,CAACI,OAAO,EAAE;
|
|
1
|
+
{"version":3,"names":["Skia","JsiDrawingContext","SkiaBaseWebView","SkiaDomView","constructor","props","renderInCanvas","canvas","touches","onTouch","console","warn","onSize","width","height","getSize","value","root","ctx","render"],"sources":["SkiaDomView.web.tsx"],"sourcesContent":["import { Skia } from \"../skia\";\nimport type { SkCanvas } from \"../skia/types\";\nimport { JsiDrawingContext } from \"../dom/types/DrawingContext\";\n\nimport { SkiaBaseWebView } from \"./SkiaBaseWebView\";\nimport type { SkiaDomViewProps, TouchInfo } from \"./types\";\n\nexport class SkiaDomView extends SkiaBaseWebView<SkiaDomViewProps> {\n constructor(props: SkiaDomViewProps) {\n super(props);\n }\n\n protected renderInCanvas(canvas: SkCanvas, touches: TouchInfo[]): void {\n if (this.props.onTouch) {\n console.warn(\n `The onTouch property is deprecated and will be removed in the next Skia release.\nSee: https://shopify.github.io/react-native-skia/docs/animations/gestures`\n );\n this.props.onTouch([touches]);\n }\n if (this.props.onSize) {\n const { width, height } = this.getSize();\n this.props.onSize.value = { width, height };\n }\n if (this.props.root) {\n const ctx = new JsiDrawingContext(Skia, canvas);\n this.props.root.render(ctx);\n }\n }\n}\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,SAAS;AAE9B,SAASC,iBAAiB,QAAQ,6BAA6B;AAE/D,SAASC,eAAe,QAAQ,mBAAmB;AAGnD,OAAO,MAAMC,WAAW,SAASD,eAAe,CAAmB;EACjEE,WAAWA,CAACC,KAAuB,EAAE;IACnC,KAAK,CAACA,KAAK,CAAC;EACd;EAEUC,cAAcA,CAACC,MAAgB,EAAEC,OAAoB,EAAQ;IACrE,IAAI,IAAI,CAACH,KAAK,CAACI,OAAO,EAAE;MACtBC,OAAO,CAACC,IAAI,CACT;AACT,0EACM,CAAC;MACD,IAAI,CAACN,KAAK,CAACI,OAAO,CAAC,CAACD,OAAO,CAAC,CAAC;IAC/B;IACA,IAAI,IAAI,CAACH,KAAK,CAACO,MAAM,EAAE;MACrB,MAAM;QAAEC,KAAK;QAAEC;MAAO,CAAC,GAAG,IAAI,CAACC,OAAO,CAAC,CAAC;MACxC,IAAI,CAACV,KAAK,CAACO,MAAM,CAACI,KAAK,GAAG;QAAEH,KAAK;QAAEC;MAAO,CAAC;IAC7C;IACA,IAAI,IAAI,CAACT,KAAK,CAACY,IAAI,EAAE;MACnB,MAAMC,GAAG,GAAG,IAAIjB,iBAAiB,CAACD,IAAI,EAAEO,MAAM,CAAC;MAC/C,IAAI,CAACF,KAAK,CAACY,IAAI,CAACE,MAAM,CAACD,GAAG,CAAC;IAC7B;EACF;AACF"}
|
|
@@ -27,6 +27,8 @@ export class SkiaJSDomView extends React.Component {
|
|
|
27
27
|
}
|
|
28
28
|
if (onTouch) {
|
|
29
29
|
assertSkiaViewApi();
|
|
30
|
+
console.warn(`The onTouch property is deprecated and will be removed in the next Skia release.
|
|
31
|
+
See: https://shopify.github.io/react-native-skia/docs/animations/gestures`);
|
|
30
32
|
SkiaViewApi.setJsiProperty(this._nativeId, "onTouch", onTouch);
|
|
31
33
|
}
|
|
32
34
|
if (onSize) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Platform","SkiaPictureViewNativeComponent","JsiDrawingContext","SkiaViewApi","SkiaViewNativeId","NativeSkiaPictureView","OS","SkiaJSDomView","Component","constructor","props","_defineProperty","_nativeId","current","root","onTouch","onSize","assertSkiaViewApi","setJsiProperty","nativeId","componentDidUpdate","prevProps","undefined","draw","makeImageSnapshot","rect","redraw","Skia","rec","PictureRecorder","canvas","beginRecording","ctx","render","picture","finishRecordingAsPicture","componentWillUnmount","mode","debug","viewProps","createElement","_extends","collapsable","nativeID","callJsiMethod","requestRedraw","Error"],"sources":["SkiaJSDomView.tsx"],"sourcesContent":["import React from \"react\";\nimport type { HostComponent } from \"react-native\";\n\nimport type { Skia, SkRect } from \"../skia/types\";\nimport { Platform } from \"../Platform\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport { JsiDrawingContext } from \"../dom/types\";\n\nimport { SkiaViewApi } from \"./api\";\nimport type { SkiaPictureViewProps, SkiaDomViewProps } from \"./types\";\nimport { SkiaViewNativeId } from \"./SkiaViewNativeId\";\n\nconst NativeSkiaPictureView: HostComponent<SkiaPictureViewProps> =\n Platform.OS !== \"web\"\n ? SkiaPictureViewNativeComponent\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (null as any);\n\nexport class SkiaJSDomView extends React.Component<\n SkiaDomViewProps & { Skia: Skia }\n> {\n constructor(props: SkiaDomViewProps & { Skia: Skia }) {\n super(props);\n this._nativeId = SkiaViewNativeId.current++;\n const { root, onTouch, onSize } = props;\n if (root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n private _nativeId: number;\n\n public get nativeId() {\n return this._nativeId;\n }\n\n componentDidUpdate(prevProps: SkiaDomViewProps & { Skia: Skia }) {\n const { root, onTouch, onSize } = this.props;\n if (root !== prevProps.root && root !== undefined) {\n assertSkiaViewApi();\n this.draw();\n }\n if (onTouch !== prevProps.onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize !== prevProps.onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshot(this._nativeId, rect);\n }\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n public redraw() {\n assertSkiaViewApi();\n this.draw();\n //SkiaViewApi.requestRedraw(this._nativeId);\n }\n\n private draw() {\n const { root, Skia } = this.props;\n if (root !== undefined) {\n assertSkiaViewApi();\n const rec = Skia.PictureRecorder();\n const canvas = rec.beginRecording();\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.render(ctx);\n const picture = rec.finishRecordingAsPicture();\n SkiaViewApi.setJsiProperty(this._nativeId, \"picture\", picture);\n }\n }\n\n /**\n * Clear up the dom node when unmounting to release resources.\n */\n componentWillUnmount(): void {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"picture\", null);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <NativeSkiaPictureView\n collapsable={false}\n nativeID={`${this._nativeId}`}\n mode={mode}\n debug={debug}\n {...viewProps}\n />\n );\n }\n}\n\nconst assertSkiaViewApi = () => {\n if (\n SkiaViewApi === null ||\n SkiaViewApi.setJsiProperty === null ||\n SkiaViewApi.callJsiMethod === null ||\n SkiaViewApi.requestRedraw === null ||\n SkiaViewApi.makeImageSnapshot === null\n ) {\n throw Error(\"Skia View Api was not found.\");\n }\n};\n"],"mappings":";;;;AAAA,OAAOA,KAAK,MAAM,OAAO;AAIzB,SAASC,QAAQ,QAAQ,aAAa;AACtC,OAAOC,8BAA8B,MAAM,yCAAyC;AACpF,SAASC,iBAAiB,QAAQ,cAAc;AAEhD,SAASC,WAAW,QAAQ,OAAO;AAEnC,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,MAAMC,qBAA0D,GAC9DL,QAAQ,CAACM,EAAE,KAAK,KAAK,GACjBL,8BAA8B;AAC9B;AACC,IAAY;AAEnB,OAAO,MAAMM,aAAa,SAASR,KAAK,CAACS,SAAS,CAEhD;EACAC,WAAWA,CAACC,KAAwC,EAAE;IACpD,KAAK,CAACA,KAAK,CAAC;IAACC,eAAA;IACb,IAAI,CAACC,SAAS,GAAGR,gBAAgB,CAACS,OAAO,EAAE;IAC3C,MAAM;MAAEC,IAAI;MAAEC,OAAO;MAAEC;IAAO,CAAC,GAAGN,KAAK;IACvC,IAAII,IAAI,EAAE;MACRG,iBAAiB,CAAC,CAAC;MACnBd,WAAW,CAACe,cAAc,CAAC,IAAI,CAACN,SAAS,EAAE,MAAM,EAAEE,IAAI,CAAC;IAC1D;IACA,IAAIC,OAAO,EAAE;MACXE,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"names":["React","Platform","SkiaPictureViewNativeComponent","JsiDrawingContext","SkiaViewApi","SkiaViewNativeId","NativeSkiaPictureView","OS","SkiaJSDomView","Component","constructor","props","_defineProperty","_nativeId","current","root","onTouch","onSize","assertSkiaViewApi","setJsiProperty","console","warn","nativeId","componentDidUpdate","prevProps","undefined","draw","makeImageSnapshot","rect","redraw","Skia","rec","PictureRecorder","canvas","beginRecording","ctx","render","picture","finishRecordingAsPicture","componentWillUnmount","mode","debug","viewProps","createElement","_extends","collapsable","nativeID","callJsiMethod","requestRedraw","Error"],"sources":["SkiaJSDomView.tsx"],"sourcesContent":["import React from \"react\";\nimport type { HostComponent } from \"react-native\";\n\nimport type { Skia, SkRect } from \"../skia/types\";\nimport { Platform } from \"../Platform\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport { JsiDrawingContext } from \"../dom/types\";\n\nimport { SkiaViewApi } from \"./api\";\nimport type { SkiaPictureViewProps, SkiaDomViewProps } from \"./types\";\nimport { SkiaViewNativeId } from \"./SkiaViewNativeId\";\n\nconst NativeSkiaPictureView: HostComponent<SkiaPictureViewProps> =\n Platform.OS !== \"web\"\n ? SkiaPictureViewNativeComponent\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (null as any);\n\nexport class SkiaJSDomView extends React.Component<\n SkiaDomViewProps & { Skia: Skia }\n> {\n constructor(props: SkiaDomViewProps & { Skia: Skia }) {\n super(props);\n this._nativeId = SkiaViewNativeId.current++;\n const { root, onTouch, onSize } = props;\n if (root) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"root\", root);\n }\n if (onTouch) {\n assertSkiaViewApi();\n console.warn(\n `The onTouch property is deprecated and will be removed in the next Skia release.\nSee: https://shopify.github.io/react-native-skia/docs/animations/gestures`\n );\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n private _nativeId: number;\n\n public get nativeId() {\n return this._nativeId;\n }\n\n componentDidUpdate(prevProps: SkiaDomViewProps & { Skia: Skia }) {\n const { root, onTouch, onSize } = this.props;\n if (root !== prevProps.root && root !== undefined) {\n assertSkiaViewApi();\n this.draw();\n }\n if (onTouch !== prevProps.onTouch) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onTouch\", onTouch);\n }\n if (onSize !== prevProps.onSize) {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"onSize\", onSize);\n }\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n assertSkiaViewApi();\n return SkiaViewApi.makeImageSnapshot(this._nativeId, rect);\n }\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n public redraw() {\n assertSkiaViewApi();\n this.draw();\n //SkiaViewApi.requestRedraw(this._nativeId);\n }\n\n private draw() {\n const { root, Skia } = this.props;\n if (root !== undefined) {\n assertSkiaViewApi();\n const rec = Skia.PictureRecorder();\n const canvas = rec.beginRecording();\n const ctx = new JsiDrawingContext(Skia, canvas);\n root.render(ctx);\n const picture = rec.finishRecordingAsPicture();\n SkiaViewApi.setJsiProperty(this._nativeId, \"picture\", picture);\n }\n }\n\n /**\n * Clear up the dom node when unmounting to release resources.\n */\n componentWillUnmount(): void {\n assertSkiaViewApi();\n SkiaViewApi.setJsiProperty(this._nativeId, \"picture\", null);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <NativeSkiaPictureView\n collapsable={false}\n nativeID={`${this._nativeId}`}\n mode={mode}\n debug={debug}\n {...viewProps}\n />\n );\n }\n}\n\nconst assertSkiaViewApi = () => {\n if (\n SkiaViewApi === null ||\n SkiaViewApi.setJsiProperty === null ||\n SkiaViewApi.callJsiMethod === null ||\n SkiaViewApi.requestRedraw === null ||\n SkiaViewApi.makeImageSnapshot === null\n ) {\n throw Error(\"Skia View Api was not found.\");\n }\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { SkImage } from "../Image";
|
|
2
|
-
export
|
|
2
|
+
export declare abstract class CanvasKitWebGLBuffer {
|
|
3
|
+
}
|
|
4
|
+
export type NativeBuffer<T extends bigint | ArrayBuffer | CanvasImageSource | CanvasKitWebGLBuffer | unknown = unknown> = T;
|
|
3
5
|
export type NativeBufferAddr = NativeBuffer<bigint>;
|
|
4
6
|
export type NativeBufferWeb = NativeBuffer<CanvasImageSource>;
|
|
5
7
|
export type NativeBufferNode = NativeBuffer<ArrayBuffer>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Surface, TextureSource, Image } from "canvaskit-wasm";
|
|
2
|
+
import { CanvasKitWebGLBuffer } from "../types";
|
|
3
|
+
export declare class CanvasKitWebGLBufferImpl extends CanvasKitWebGLBuffer {
|
|
4
|
+
surface: Surface;
|
|
5
|
+
private source;
|
|
6
|
+
image: Image | null;
|
|
7
|
+
constructor(surface: Surface, source: TextureSource);
|
|
8
|
+
toImage(): Image;
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CanvasKit, Surface } from "canvaskit-wasm";
|
|
2
|
+
import type { Video, ImageFactory } from "../types";
|
|
3
|
+
export declare const createVideo: (CanvasKit: CanvasKit, url: string) => Promise<Video>;
|
|
4
|
+
export declare class JsiVideo implements Video {
|
|
5
|
+
private ImageFactory;
|
|
6
|
+
private videoElement;
|
|
7
|
+
__typename__: "Video";
|
|
8
|
+
private webglBuffer;
|
|
9
|
+
constructor(ImageFactory: ImageFactory, videoElement: HTMLVideoElement);
|
|
10
|
+
duration(): number;
|
|
11
|
+
framerate(): number;
|
|
12
|
+
setSurface(surface: Surface): void;
|
|
13
|
+
nextImage(): import("../types").SkImage;
|
|
14
|
+
seek(time: number): void;
|
|
15
|
+
rotation(): 0;
|
|
16
|
+
size(): {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
pause(): void;
|
|
21
|
+
play(): void;
|
|
22
|
+
setVolume(volume: number): void;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"setup-skia-web": "./scripts/setup-canvaskit.js"
|
|
8
8
|
},
|
|
9
9
|
"title": "React Native Skia",
|
|
10
|
-
"version": "1.3.
|
|
10
|
+
"version": "1.3.4",
|
|
11
11
|
"description": "High-performance React Native Graphics using Skia",
|
|
12
12
|
"main": "lib/module/index.js",
|
|
13
13
|
"react-native": "src/index.ts",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { SharedValue, FrameInfo } from "react-native-reanimated";
|
|
2
2
|
import { useEffect, useMemo } from "react";
|
|
3
3
|
|
|
4
|
-
import { Skia } from "../../skia/Skia";
|
|
5
4
|
import type { SkImage, Video } from "../../skia/types";
|
|
6
5
|
import { Platform } from "../../Platform";
|
|
7
6
|
|
|
8
7
|
import Rea from "./ReanimatedProxy";
|
|
8
|
+
import { useVideoLoading } from "./useVideoLoading";
|
|
9
9
|
|
|
10
10
|
type Animated<T> = SharedValue<T> | T;
|
|
11
11
|
|
|
@@ -16,6 +16,18 @@ interface PlaybackOptions {
|
|
|
16
16
|
volume: Animated<number>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
const copyFrameOnAndroid = (currentFrame: SharedValue<SkImage | null>) => {
|
|
20
|
+
"worklet";
|
|
21
|
+
// on android we need to copy the texture before it's invalidated
|
|
22
|
+
if (Platform.OS === "android") {
|
|
23
|
+
const tex = currentFrame.value;
|
|
24
|
+
if (tex) {
|
|
25
|
+
currentFrame.value = tex.makeNonTextureImage();
|
|
26
|
+
tex.dispose();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
19
31
|
const setFrame = (video: Video, currentFrame: SharedValue<SkImage | null>) => {
|
|
20
32
|
"worklet";
|
|
21
33
|
const img = video.nextImage();
|
|
@@ -23,11 +35,9 @@ const setFrame = (video: Video, currentFrame: SharedValue<SkImage | null>) => {
|
|
|
23
35
|
if (currentFrame.value) {
|
|
24
36
|
currentFrame.value.dispose();
|
|
25
37
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
currentFrame.value = img;
|
|
30
|
-
}
|
|
38
|
+
currentFrame.value = img;
|
|
39
|
+
} else {
|
|
40
|
+
copyFrameOnAndroid(currentFrame);
|
|
31
41
|
}
|
|
32
42
|
};
|
|
33
43
|
|
|
@@ -57,7 +67,7 @@ export const useVideo = (
|
|
|
57
67
|
source: string | null,
|
|
58
68
|
userOptions?: Partial<PlaybackOptions>
|
|
59
69
|
) => {
|
|
60
|
-
const video =
|
|
70
|
+
const video = useVideoLoading(source);
|
|
61
71
|
const isPaused = useOption(userOptions?.paused ?? defaultOptions.paused);
|
|
62
72
|
const looping = useOption(userOptions?.looping ?? defaultOptions.looping);
|
|
63
73
|
const seek = useOption(userOptions?.seek ?? defaultOptions.seek);
|
|
@@ -66,7 +76,10 @@ export const useVideo = (
|
|
|
66
76
|
const currentTime = Rea.useSharedValue(0);
|
|
67
77
|
const lastTimestamp = Rea.useSharedValue(-1);
|
|
68
78
|
const duration = useMemo(() => video?.duration() ?? 0, [video]);
|
|
69
|
-
const framerate = useMemo(
|
|
79
|
+
const framerate = useMemo(
|
|
80
|
+
() => (Platform.OS === "web" ? -1 : video?.framerate() ?? 0),
|
|
81
|
+
[video]
|
|
82
|
+
);
|
|
70
83
|
const size = useMemo(() => video?.size() ?? { width: 0, height: 0 }, [video]);
|
|
71
84
|
const rotation = useMemo(() => video?.rotation() ?? 0, [video]);
|
|
72
85
|
const frameDuration = 1000 / framerate;
|
|
@@ -86,6 +99,7 @@ export const useVideo = (
|
|
|
86
99
|
() => seek.value,
|
|
87
100
|
(value) => {
|
|
88
101
|
if (value !== null) {
|
|
102
|
+
copyFrameOnAndroid(currentFrame);
|
|
89
103
|
video?.seek(value);
|
|
90
104
|
currentTime.value = value;
|
|
91
105
|
seek.value = null;
|
|
@@ -118,7 +132,9 @@ export const useVideo = (
|
|
|
118
132
|
currentTime.value = seek.value;
|
|
119
133
|
lastTimestamp.value = currentTimestamp;
|
|
120
134
|
}
|
|
121
|
-
|
|
135
|
+
// On Web the framerate is uknown.
|
|
136
|
+
// This could be optimized by using requestVideoFrameCallback (Chrome only)
|
|
137
|
+
if ((delta >= currentFrameDuration && !isOver) || Platform.OS === "web") {
|
|
122
138
|
setFrame(video, currentFrame);
|
|
123
139
|
currentTime.value += delta;
|
|
124
140
|
lastTimestamp.value = currentTimestamp;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
createWorkletRuntime,
|
|
4
|
+
runOnJS,
|
|
5
|
+
runOnRuntime,
|
|
6
|
+
} from "react-native-reanimated";
|
|
7
|
+
|
|
8
|
+
import type { Video } from "../../skia/types";
|
|
9
|
+
import { Skia } from "../../skia";
|
|
10
|
+
|
|
11
|
+
const runtime = createWorkletRuntime("video-metadata-runtime");
|
|
12
|
+
|
|
13
|
+
type VideoSource = string | null;
|
|
14
|
+
|
|
15
|
+
export const useVideoLoading = (source: VideoSource) => {
|
|
16
|
+
const [video, setVideo] = useState<Video | null>(null);
|
|
17
|
+
const cb = (src: string) => {
|
|
18
|
+
"worklet";
|
|
19
|
+
const vid = Skia.Video(src) as Video;
|
|
20
|
+
runOnJS(setVideo)(vid);
|
|
21
|
+
};
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (source) {
|
|
24
|
+
runOnRuntime(runtime, cb)(source);
|
|
25
|
+
}
|
|
26
|
+
}, [source]);
|
|
27
|
+
return video;
|
|
28
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import type { Video } from "../../skia/types";
|
|
4
|
+
import { Skia } from "../../skia";
|
|
5
|
+
|
|
6
|
+
type VideoSource = string | null;
|
|
7
|
+
|
|
8
|
+
export const useVideoLoading = (source: VideoSource) => {
|
|
9
|
+
const [video, setVideo] = useState<Video | null>(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (source) {
|
|
12
|
+
const vid = Skia.Video(source) as Promise<Video>;
|
|
13
|
+
vid.then((v) => setVideo(v));
|
|
14
|
+
}
|
|
15
|
+
}, [source]);
|
|
16
|
+
return video;
|
|
17
|
+
};
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { SkImage } from "../Image";
|
|
2
2
|
|
|
3
|
+
export abstract class CanvasKitWebGLBuffer {}
|
|
4
|
+
|
|
3
5
|
export type NativeBuffer<
|
|
4
|
-
T extends
|
|
6
|
+
T extends
|
|
7
|
+
| bigint
|
|
8
|
+
| ArrayBuffer
|
|
9
|
+
| CanvasImageSource
|
|
10
|
+
| CanvasKitWebGLBuffer
|
|
11
|
+
| unknown = unknown
|
|
5
12
|
> = T;
|
|
6
13
|
|
|
7
14
|
export type NativeBufferAddr = NativeBuffer<bigint>;
|
|
@@ -20,7 +27,8 @@ export const isNativeBufferWeb = (
|
|
|
20
27
|
buffer instanceof OffscreenCanvas ||
|
|
21
28
|
buffer instanceof VideoFrame ||
|
|
22
29
|
buffer instanceof HTMLImageElement ||
|
|
23
|
-
buffer instanceof SVGImageElement
|
|
30
|
+
buffer instanceof SVGImageElement ||
|
|
31
|
+
buffer instanceof CanvasKitWebGLBuffer;
|
|
24
32
|
|
|
25
33
|
export const isNativeBufferNode = (
|
|
26
34
|
buffer: NativeBuffer
|
package/src/skia/types/Skia.ts
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Surface, TextureSource, Image } from "canvaskit-wasm";
|
|
2
|
+
|
|
3
|
+
import { CanvasKitWebGLBuffer } from "../types";
|
|
4
|
+
|
|
5
|
+
export class CanvasKitWebGLBufferImpl extends CanvasKitWebGLBuffer {
|
|
6
|
+
public image: Image | null = null;
|
|
7
|
+
|
|
8
|
+
constructor(public surface: Surface, private source: TextureSource) {
|
|
9
|
+
super();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
toImage() {
|
|
13
|
+
if (this.image === null) {
|
|
14
|
+
this.image = this.surface.makeImageFromTextureSource(this.source);
|
|
15
|
+
}
|
|
16
|
+
if (this.image === null) {
|
|
17
|
+
throw new Error("Failed to create image from texture source");
|
|
18
|
+
}
|
|
19
|
+
this.surface.updateTextureFromSource(this.image, this.source);
|
|
20
|
+
return this.image;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanvasKit, Image } from "canvaskit-wasm";
|
|
2
2
|
|
|
3
|
-
import { isNativeBufferWeb } from "../types";
|
|
3
|
+
import { CanvasKitWebGLBuffer, isNativeBufferWeb } from "../types";
|
|
4
4
|
import type {
|
|
5
5
|
SkData,
|
|
6
6
|
ImageInfo,
|
|
@@ -13,6 +13,7 @@ import { Host, getEnum } from "./Host";
|
|
|
13
13
|
import { JsiSkImage } from "./JsiSkImage";
|
|
14
14
|
import { JsiSkData } from "./JsiSkData";
|
|
15
15
|
import type { JsiSkSurface } from "./JsiSkSurface";
|
|
16
|
+
import type { CanvasKitWebGLBufferImpl } from "./CanvasKitWebGLBufferImpl";
|
|
16
17
|
|
|
17
18
|
export class JsiSkImageFactory extends Host implements ImageFactory {
|
|
18
19
|
constructor(CanvasKit: CanvasKit) {
|
|
@@ -35,8 +36,20 @@ export class JsiSkImageFactory extends Host implements ImageFactory {
|
|
|
35
36
|
throw new Error("Invalid NativeBuffer");
|
|
36
37
|
}
|
|
37
38
|
if (!surface) {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
let img: Image;
|
|
40
|
+
if (
|
|
41
|
+
buffer instanceof HTMLImageElement ||
|
|
42
|
+
buffer instanceof HTMLVideoElement ||
|
|
43
|
+
buffer instanceof ImageBitmap
|
|
44
|
+
) {
|
|
45
|
+
img = this.CanvasKit.MakeLazyImageFromTextureSource(buffer);
|
|
46
|
+
} else if (buffer instanceof CanvasKitWebGLBuffer) {
|
|
47
|
+
img = (
|
|
48
|
+
buffer as CanvasKitWebGLBuffer as CanvasKitWebGLBufferImpl
|
|
49
|
+
).toImage();
|
|
50
|
+
} else {
|
|
51
|
+
img = this.CanvasKit.MakeImageFromCanvasImageSource(buffer);
|
|
52
|
+
}
|
|
40
53
|
return new JsiSkImage(this.CanvasKit, img);
|
|
41
54
|
} else if (!image) {
|
|
42
55
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/src/skia/web/JsiSkia.ts
CHANGED
|
@@ -42,6 +42,7 @@ import { JsiSkFontMgrFactory } from "./JsiSkFontMgrFactory";
|
|
|
42
42
|
import { JsiSkAnimatedImageFactory } from "./JsiSkAnimatedImageFactory";
|
|
43
43
|
import { JsiSkParagraphBuilderFactory } from "./JsiSkParagraphBuilderFactory";
|
|
44
44
|
import { JsiSkNativeBufferFactory } from "./JsiSkNativeBufferFactory";
|
|
45
|
+
import { createVideo } from "./JsiVideo";
|
|
45
46
|
|
|
46
47
|
export const JsiSkApi = (CanvasKit: CanvasKit): Skia => ({
|
|
47
48
|
Point: (x: number, y: number) =>
|
|
@@ -127,7 +128,5 @@ export const JsiSkApi = (CanvasKit: CanvasKit): Skia => ({
|
|
|
127
128
|
FontMgr: new JsiSkFontMgrFactory(CanvasKit),
|
|
128
129
|
ParagraphBuilder: new JsiSkParagraphBuilderFactory(CanvasKit),
|
|
129
130
|
NativeBuffer: new JsiSkNativeBufferFactory(CanvasKit),
|
|
130
|
-
Video: (
|
|
131
|
-
throw new Error("Not implemented on React Native Web");
|
|
132
|
-
},
|
|
131
|
+
Video: createVideo.bind(null, CanvasKit),
|
|
133
132
|
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { CanvasKit, Surface } from "canvaskit-wasm";
|
|
2
|
+
|
|
3
|
+
import type { CanvasKitWebGLBuffer, Video, ImageFactory } from "../types";
|
|
4
|
+
|
|
5
|
+
import { CanvasKitWebGLBufferImpl } from "./CanvasKitWebGLBufferImpl";
|
|
6
|
+
import { JsiSkImageFactory } from "./JsiSkImageFactory";
|
|
7
|
+
|
|
8
|
+
export const createVideo = async (
|
|
9
|
+
CanvasKit: CanvasKit,
|
|
10
|
+
url: string
|
|
11
|
+
): Promise<Video> => {
|
|
12
|
+
const video = document.createElement("video");
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
video.src = url;
|
|
15
|
+
video.style.display = "none";
|
|
16
|
+
video.crossOrigin = "anonymous";
|
|
17
|
+
video.volume = 0;
|
|
18
|
+
video.addEventListener("loadedmetadata", () => {
|
|
19
|
+
document.body.appendChild(video);
|
|
20
|
+
resolve(new JsiVideo(new JsiSkImageFactory(CanvasKit), video));
|
|
21
|
+
});
|
|
22
|
+
video.addEventListener("error", () => {
|
|
23
|
+
reject(new Error(`Failed to load video from URL: ${url}`));
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export class JsiVideo implements Video {
|
|
29
|
+
__typename__ = "Video" as const;
|
|
30
|
+
|
|
31
|
+
private webglBuffer: CanvasKitWebGLBuffer | null = null;
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
private ImageFactory: ImageFactory,
|
|
35
|
+
private videoElement: HTMLVideoElement
|
|
36
|
+
) {
|
|
37
|
+
document.body.appendChild(this.videoElement);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
duration() {
|
|
41
|
+
return this.videoElement.duration * 1000;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
framerate(): number {
|
|
45
|
+
throw new Error("Video.frame is not available on React Native Web");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setSurface(surface: Surface) {
|
|
49
|
+
// If we have the surface, we can use the WebGL buffer which is slightly faster
|
|
50
|
+
// This is because WebGL cannot be shared across contextes.
|
|
51
|
+
// This can be removed with WebGPU
|
|
52
|
+
this.webglBuffer = new CanvasKitWebGLBufferImpl(surface, this.videoElement);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
nextImage() {
|
|
56
|
+
return this.ImageFactory.MakeImageFromNativeBuffer(
|
|
57
|
+
this.webglBuffer ? this.webglBuffer : this.videoElement
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
seek(time: number) {
|
|
62
|
+
if (isNaN(time)) {
|
|
63
|
+
throw new Error(`Invalid time: ${time}`);
|
|
64
|
+
}
|
|
65
|
+
this.videoElement.currentTime = time / 1000;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
rotation() {
|
|
69
|
+
return 0 as const;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
size() {
|
|
73
|
+
return {
|
|
74
|
+
width: this.videoElement.videoWidth,
|
|
75
|
+
height: this.videoElement.videoHeight,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
pause() {
|
|
80
|
+
this.videoElement.pause();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
play() {
|
|
84
|
+
this.videoElement.play();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
setVolume(volume: number) {
|
|
88
|
+
this.videoElement.volume = volume;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dispose() {
|
|
92
|
+
if (this.videoElement.parentNode) {
|
|
93
|
+
this.videoElement.parentNode.removeChild(this.videoElement);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -26,6 +26,10 @@ export class SkiaDomView extends React.Component<SkiaDomViewProps> {
|
|
|
26
26
|
}
|
|
27
27
|
if (onTouch) {
|
|
28
28
|
assertSkiaViewApi();
|
|
29
|
+
console.warn(
|
|
30
|
+
`The onTouch property is deprecated and will be removed in the next Skia release.
|
|
31
|
+
See: https://shopify.github.io/react-native-skia/docs/animations/gestures`
|
|
32
|
+
);
|
|
29
33
|
SkiaViewApi.setJsiProperty(this._nativeId, "onTouch", onTouch);
|
|
30
34
|
}
|
|
31
35
|
if (onSize) {
|