1 | import { Platform } from '@unimodules/core';
|
2 | import * as React from 'react';
|
3 | import { findDOMNode } from 'react-dom';
|
4 | import { PixelRatio, StyleSheet, View } from 'react-native';
|
5 | import createElement from 'react-native-web/dist/exports/createElement';
|
6 | function getElement(component) {
|
7 | try {
|
8 | return findDOMNode(component);
|
9 | }
|
10 | catch (e) {
|
11 | return component;
|
12 | }
|
13 | }
|
14 | function setRef(refProp, ref) {
|
15 | if (!refProp)
|
16 | return;
|
17 | if (typeof refProp === 'function') {
|
18 | refProp(ref);
|
19 | }
|
20 | else if ('current' in refProp) {
|
21 |
|
22 | refProp.current = ref;
|
23 | }
|
24 | }
|
25 | const Canvas = React.forwardRef((props, ref) => createElement('canvas', { ...props, ref }));
|
26 | const CanvasWrapper = ({ pointerEvents, children, ...props }) => {
|
27 | const [size, setSize] = React.useState(null);
|
28 | const ref = React.useRef(null);
|
29 | const _canvasRef = React.useRef(null);
|
30 | function updateCanvasSize() {
|
31 | const canvas = _canvasRef.current;
|
32 |
|
33 | if (typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement) {
|
34 | const size = getSize();
|
35 | const scale = PixelRatio.get();
|
36 | canvas.style.width = `${size.width}px`;
|
37 | canvas.style.height = `${size.height}px`;
|
38 | canvas.width = size.width * scale;
|
39 | canvas.height = size.height * scale;
|
40 | }
|
41 | }
|
42 | function getSize() {
|
43 | if (size) {
|
44 | return size;
|
45 | }
|
46 | else if (!ref.current || !Platform.isDOMAvailable) {
|
47 | return { width: 0, height: 0 };
|
48 | }
|
49 | const element = getElement(ref.current);
|
50 | const { offsetWidth: width = 0, offsetHeight: height = 0 } = element;
|
51 | return { width, height };
|
52 | }
|
53 | function onLayout(event) {
|
54 | const { nativeEvent: { layout: { width, height }, }, } = event;
|
55 | if (width !== size?.width || height !== size.height) {
|
56 | setSize({ width, height });
|
57 | if (props.onLayout) {
|
58 | props.onLayout(event);
|
59 | }
|
60 | }
|
61 | }
|
62 | React.useEffect(() => {
|
63 | if (ref.current != null) {
|
64 | setSize(getSize());
|
65 | }
|
66 | }, [ref]);
|
67 | React.useEffect(() => {
|
68 | updateCanvasSize();
|
69 | }, [size]);
|
70 | React.useEffect(() => {
|
71 | const canvas = _canvasRef.current;
|
72 | if (canvas) {
|
73 | updateCanvasSize();
|
74 | }
|
75 | setRef(props.canvasRef, canvas);
|
76 | }, [_canvasRef]);
|
77 | return (React.createElement(View, Object.assign({}, props, { pointerEvents: "box-none", ref: ref, onLayout: onLayout }),
|
78 | React.createElement(Canvas, { ref: _canvasRef, pointerEvents: pointerEvents, style: StyleSheet.absoluteFill }),
|
79 | children));
|
80 | };
|
81 | export default CanvasWrapper;
|
82 |
|
\ | No newline at end of file |