UNPKG

@gdn/react-native-simple-canvas

Version:

A simple canvas component for React Native that allows drawing and signature capture.

148 lines 6.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.SimpleCanvas = exports.clearCanvas = void 0; const react_1 = __importStar(require("react")); const react_native_1 = require("react-native"); const react_native_svg_1 = require("react-native-svg"); const canvas_1 = require("./helpers/canvas"); const clearCanvas = (ref) => { var _a; (_a = ref.current) === null || _a === void 0 ? void 0 : _a.resetImage(); }; exports.clearCanvas = clearCanvas; const SimpleCanvas = ({ onDragEvent, onCanvasChange, strokeColor = 'black', strokeWidth = 3, backgroundColor = 'transparent', style, minPoints = 2, ref, }) => { const [paths, setPaths] = (0, react_1.useState)([]); const pointsRef = (0, react_1.useRef)([]); const svgRef = (0, react_1.useRef)(null); const isDrawing = (0, react_1.useRef)(false); const canvasRef = (0, react_1.useRef)(null); const canvasOffset = (0, react_1.useRef)({ x: 0, y: 0 }); const addPoint = (0, react_1.useCallback)((point) => { pointsRef.current.push(point); return true; }, []); const resetImage = (0, react_1.useCallback)(() => { setPaths([]); pointsRef.current = []; onCanvasChange === null || onCanvasChange === void 0 ? void 0 : onCanvasChange(true); }, [onCanvasChange]); const isEmpty = (0, react_1.useCallback)(() => { return paths.length === 0; }, [paths]); const getPoints = (0, react_1.useCallback)(() => { return [...pointsRef.current]; }, []); const setPoints = (0, react_1.useCallback)((newPoints) => { if (newPoints.length < minPoints) return; pointsRef.current = newPoints; const path = (0, canvas_1.spline)(newPoints, 1, false); setPaths([path]); onCanvasChange === null || onCanvasChange === void 0 ? void 0 : onCanvasChange(false); }, [minPoints, onCanvasChange]); const onLayout = (0, react_1.useCallback)(() => { var _a; (_a = canvasRef.current) === null || _a === void 0 ? void 0 : _a.measureInWindow((x, y) => { canvasOffset.current = { x, y }; }); }, []); const panResponder = (0, react_1.useMemo)(() => react_native_1.PanResponder.create({ onStartShouldSetPanResponder: () => true, onMoveShouldSetPanResponder: () => true, onPanResponderGrant: (event) => { const { pageX, pageY } = event.nativeEvent; const point = { x: pageX - canvasOffset.current.x, y: pageY - canvasOffset.current.y }; isDrawing.current = true; pointsRef.current = [point]; setPaths(prevPaths => [...prevPaths, `M ${point.x} ${point.y}`]); onDragEvent === null || onDragEvent === void 0 ? void 0 : onDragEvent(); }, onPanResponderMove: (event) => { if (!isDrawing.current) return; const { pageX, pageY } = event.nativeEvent; const point = { x: pageX - canvasOffset.current.x, y: pageY - canvasOffset.current.y }; if (addPoint(point)) { if (pointsRef.current.length >= minPoints) { const path = (0, canvas_1.spline)(pointsRef.current, 1, false); setPaths(prevPaths => { const newPaths = [...prevPaths]; newPaths[newPaths.length - 1] = path; return newPaths; }); onCanvasChange === null || onCanvasChange === void 0 ? void 0 : onCanvasChange(false); } } }, onPanResponderRelease: () => { isDrawing.current = false; }, }), [onDragEvent, addPoint, minPoints, onCanvasChange]); (0, react_1.useImperativeHandle)(ref, () => ({ getSVG: () => svgRef, resetImage, isEmpty, getPoints, setPoints }), [resetImage, isEmpty, getPoints, setPoints]); const pathElements = (0, react_1.useMemo)(() => paths.map((path, index) => (<react_native_svg_1.Path key={index} d={path} stroke={strokeColor} strokeWidth={strokeWidth} fill="none" strokeLinecap="round" strokeLinejoin="round"/>)), [paths, strokeColor, strokeWidth]); return (<react_native_1.View style={[styles.container, style]}> <react_native_1.View ref={canvasRef} onLayout={onLayout} style={[styles.canvas, { backgroundColor }]} {...panResponder.panHandlers}> <react_native_svg_1.Svg ref={svgRef} height="100%" width="100%"> {pathElements} </react_native_svg_1.Svg> </react_native_1.View> </react_native_1.View>); }; exports.SimpleCanvas = SimpleCanvas; exports.SimpleCanvas.displayName = 'SimpleCanvas'; const styles = react_native_1.StyleSheet.create({ container: { flex: 1, }, canvas: { flex: 1, borderWidth: 1, borderColor: '#ccc', }, }); //# sourceMappingURL=SimpleCanvas.js.map