UNPKG

@magnetman103/react-native-sketch-canvas

Version:

A fork of react native sketch canvas from sourcetoad for modification.

182 lines (169 loc) 5.79 kB
'use strict'; import memoize from 'memoize-one'; import React, { forwardRef, useImperativeHandle } from 'react'; import { PixelRatio, Platform, processColor } from 'react-native'; import { requestPermissions } from "./handlePermissions.js"; import ReactNativeSketchCanvasView, { Commands } from "./specs/SketchCanvasNativeComponent.js"; // Define types directly in this file import { jsx as _jsx } from "react/jsx-runtime"; export let OnChangeEventType = /*#__PURE__*/function (OnChangeEventType) { OnChangeEventType["PathsUpdate"] = "pathsUpdate"; OnChangeEventType["Save"] = "save"; return OnChangeEventType; }({}); // Define DrawCanvas props interface // Define the ref interface to expose methods const DrawCanvas = /*#__PURE__*/forwardRef((props, ref) => { const canvasRef = React.useRef(null); // Track these values with refs instead of state const screenScale = React.useRef(Platform.OS === 'ios' ? 1 : PixelRatio.get()); const size = React.useRef({ width: 0, height: 0 }); const initialized = React.useRef(false); // Process text for display const processText = text => { text && text.forEach(t => t.fontColor = processColor(t.fontColor)); return text; }; const getProcessedText = memoize(text => { const textCopy = text ? text.map(t => Object.assign({}, t)) : null; return processText(textCopy); }); // Method implementations const clear = () => { if (canvasRef.current) { Commands.clear(canvasRef.current); } }; const addPath = data => { if (initialized.current) { const pathData = data.path.data.map(p => { const coor = p.split(',').map(pp => parseFloat(pp).toFixed(2)); return `${coor[0] * screenScale.current * size.current.width / data.size.width},${coor[1] * screenScale.current * size.current.height / data.size.height}`; }); if (canvasRef.current) { Commands.addPath(canvasRef.current, data.path.id, processColor(data.path.color), data.path.width ? data.path.width * screenScale.current : 0, pathData); } } }; const deletePath = id => { if (canvasRef.current) { Commands.deletePath(canvasRef.current, id); } }; const save = (imageType, transparent, folder, filename, includeImage, includeText, cropToImageSize) => { if (canvasRef.current) { Commands.save(canvasRef.current, imageType, folder, filename, transparent, includeImage, includeText, cropToImageSize); } }; const getBase64 = (imageType, transparent, includeImage, includeText, cropToImageSize) => { if (canvasRef.current) { Commands.transferToBase64(canvasRef.current, imageType, transparent, includeImage, includeText, cropToImageSize); } }; const addPoint = (x, y) => { if (canvasRef.current) { Commands.addPoint(canvasRef.current, parseFloat((x * screenScale.current).toString()), parseFloat((y * screenScale.current).toString())); } }; const newPath = (id, color, width) => { if (canvasRef.current) { Commands.newPath(canvasRef.current, id, processColor(color), width ? width * screenScale.current : 0); } }; const endPath = () => { if (canvasRef.current) { Commands.endPath(canvasRef.current); } }; // Handle permissions on mount React.useEffect(() => { const setupPermissions = async () => { await requestPermissions(props.permissionDialogTitle || '', props.permissionDialogMessage || ''); }; setupPermissions(); }, [props.permissionDialogTitle, props.permissionDialogMessage]); // Process paths when component updates React.useEffect(() => { // Process any initial paths if (initialized.current && props.pathsToProcess.length > 0) { props.pathsToProcess.forEach(p => addPath(p)); } }, [props.pathsToProcess]); // Expose methods via ref useImperativeHandle(ref, () => ({ clear, addPath, deletePath, newPath, addPoint, endPath, save, getBase64 })); // Default props const defaultProps = { style: null, strokeColor: '#000000', strokeWidth: 3, onPathsChange: () => {}, onStrokeStart: (_x, _y) => {}, onStrokeChanged: () => {}, onStrokeEnd: () => {}, onSketchSaved: () => {}, onGenerateBase64: () => {}, user: null, text: null, localSourceImage: null, permissionDialogTitle: '', permissionDialogMessage: '', pathsToProcess: [], paths: [], currentPath: null }; return /*#__PURE__*/_jsx(ReactNativeSketchCanvasView, { ref: canvasRef, style: props.style || defaultProps.style, onLayout: e => { size.current = { width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height }; initialized.current = true; // Process any initial paths after layout if (props.pathsToProcess.length > 0) { props.pathsToProcess.forEach(p => addPath(p)); } }, onChange: e => { const { eventType, pathsUpdate, success, path } = e.nativeEvent || {}; const isSuccess = success !== undefined; const isSave = eventType === OnChangeEventType.Save; const isPathsUpdate = eventType === OnChangeEventType.PathsUpdate; if (!isSave && isPathsUpdate) { props.onPathsChange?.(pathsUpdate); } else if (isSave) { props.onSketchSaved?.(success, path); } else if (isSuccess) { props.onSketchSaved?.(success, ''); } }, onGenerateBase64: e => { props.onGenerateBase64?.(e.nativeEvent || {}); }, onCanvasReady: () => { props.onCanvasReady?.(); }, localSourceImage: props.localSourceImage, text: getProcessedText(props.text) }); }); export default DrawCanvas; //# sourceMappingURL=DrawCanvas.js.map