@magnetman103/react-native-sketch-canvas
Version:
A fork of react native sketch canvas from sourcetoad for modification.
182 lines (169 loc) • 5.79 kB
JavaScript
;
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