UNPKG

@shopify/react-native-skia

Version:

High-performance React Native Graphics using Skia

156 lines (151 loc) 5.02 kB
var _global; function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react"; import Rea from "../external/reanimated/ReanimatedProxy"; import { SkiaViewNativeId } from "../views/SkiaViewNativeId"; import SkiaPictureViewNativeComponent from "../specs/SkiaPictureViewNativeComponent"; import { SkiaSGRoot } from "../sksg/Reconciler"; import { Skia } from "../skia"; import { Platform } from "../Platform"; import { HAS_REANIMATED_3 } from "../external"; export const useCanvasRef = () => useRef(null); const useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback; const measure = !HAS_REANIMATED_3 ? null : Rea.measure; const useCanvasRefPriv = !HAS_REANIMATED_3 ? useRef : Rea.useAnimatedRef; export const useCanvasSize = userRef => { const ourRef = useCanvasRef(); const ref = userRef !== null && userRef !== void 0 ? userRef : ourRef; const [size, setSize] = useState({ width: 0, height: 0 }); useLayoutEffect(() => { if (ref.current) { ref.current.measure((_x, _y, width, height) => { setSize({ width, height }); }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ref, size }; }; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const isFabric = Boolean((_global = global) === null || _global === void 0 ? void 0 : _global.nativeFabricUIManager); export const Canvas = ({ debug, opaque, children, onSize, colorSpace = "p3", androidWarmup = false, ref, onLayout, ...viewProps }) => { if (onLayout && isFabric) { console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size"); } const viewRef = useCanvasRefPriv(null); // Native ID const nativeId = useMemo(() => { return SkiaViewNativeId.current++; }, []); // Root const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]); useReanimatedFrame(() => { "worklet"; if (onSize && measure) { var _viewRef$current; const result = // eslint-disable-next-line no-nested-ternary Platform.OS === "web" ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error (_viewRef$current = viewRef.current) !== null && _viewRef$current !== void 0 && _viewRef$current.canvasRef ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error measure(viewRef.current.canvasRef) : { width: 0, height: 0 } : // eslint-disable-next-line @typescript-eslint/no-explicit-any measure(viewRef); if (result) { const { width, height } = result; if (onSize.value.width !== width || onSize.value.height !== height) { onSize.value = { width, height }; } } } }, !!onSize); // Render effects useLayoutEffect(() => { root.render(children); }, [children, root, nativeId]); useEffect(() => { return () => { root.unmount(); }; }, [root]); // Component methods useImperativeHandle(ref, () => ({ makeImageSnapshot: rect => { return SkiaViewApi.makeImageSnapshot(nativeId, rect); }, makeImageSnapshotAsync: rect => { return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect); }, redraw: () => { SkiaViewApi.requestRedraw(nativeId); }, getNativeId: () => { return nativeId; }, measure: callback => { var _viewRef$current2; (_viewRef$current2 = viewRef.current) === null || _viewRef$current2 === void 0 || _viewRef$current2.measure(callback); }, measureInWindow: callback => { var _viewRef$current3; (_viewRef$current3 = viewRef.current) === null || _viewRef$current3 === void 0 || _viewRef$current3.measureInWindow(callback); } })); const onLayoutWeb = useCallback(e => { if (onLayout) { onLayout(e); } if (Platform.OS === "web" && onSize) { const { width, height } = e.nativeEvent.layout; onSize.value = { width, height }; } }, [onLayout, onSize]); return /*#__PURE__*/React.createElement(SkiaPictureViewNativeComponent, _extends({ ref: viewRef, collapsable: false, nativeID: `${nativeId}`, debug: debug, opaque: opaque, colorSpace: colorSpace, androidWarmup: androidWarmup, onLayout: Platform.OS === "web" && (onSize || onLayout) ? onLayoutWeb : onLayout }, viewProps)); }; //# sourceMappingURL=Canvas.js.map