@kubit-ui-web/react-components
Version:
Kubit React Components is a customizable, accessible library of React web components, designed to enhance your application's user experience
131 lines • 5.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useDraw = void 0;
const react_1 = require("react");
function isImageDataEqual(a, b) {
if (a.width !== b.width || a.height !== b.height) {
return false;
}
for (let i = 0; i < a.data.length; i++) {
if (a.data[i] !== b.data[i]) {
return false;
}
}
return true;
}
const useDraw = (onChange) => {
const canvasRef = (0, react_1.useRef)(null);
const context = (0, react_1.useRef)();
const isDrawing = (0, react_1.useRef)(false);
const isFilled = (0, react_1.useRef)(false);
const signatureStylesRef = (0, react_1.useRef)({ color: 'black', lineWidth: 2 });
const canvasInnerData = (0, react_1.useRef)(null); // reference to the canvas data before drawing
const resetCanvas = () => {
if (!canvasRef.current) {
return;
}
isFilled.current = false;
context.current.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
};
const setSignatureStyles = (signatureStyles) => {
if (!signatureStyles) {
return;
}
signatureStylesRef.current.color = signatureStyles.color;
signatureStylesRef.current.lineWidth = signatureStyles.lineWidth;
};
const startDrawing = event => {
let offsetX, offsetY;
if (event.type === 'touchstart' && canvasRef.current) {
const { touches } = event;
const { clientX, clientY } = touches[0];
const { left, top } = canvasRef.current.getBoundingClientRect();
offsetX = clientX - left;
offsetY = clientY - top;
}
else {
offsetX = event.offsetX;
offsetY = event.offsetY;
}
canvasInnerData.current = context.current.getImageData(0, 0, canvasRef.current?.width, canvasRef.current?.height);
context.current.beginPath();
context.current.moveTo(offsetX, offsetY);
isDrawing.current = true;
};
const draw = event => {
if (!isDrawing.current)
return;
let offsetX, offsetY;
event.preventDefault();
if (event.type === 'touchmove' && canvasRef.current) {
const { touches } = event;
const { clientX, clientY } = touches[0];
const { left, top } = canvasRef.current.getBoundingClientRect();
offsetX = clientX - left;
offsetY = clientY - top;
}
else {
offsetX = event.offsetX;
offsetY = event.offsetY;
}
context.current.lineTo(offsetX, offsetY);
context.current.stroke();
};
const stopDrawing = () => {
const currentLayout = context.current.getImageData(0, 0, canvasRef.current?.width, canvasRef.current?.height);
context.current.closePath();
isDrawing.current = false;
if (!canvasInnerData.current) {
return;
}
const isEqual = isImageDataEqual(currentLayout, canvasInnerData.current);
if (!isEqual) {
const dataUrl = canvasRef.current?.toDataURL();
onChange?.(dataUrl);
isFilled.current = true;
}
};
(0, react_1.useEffect)(() => {
if (canvasRef.current === null) {
return;
}
const canvas = canvasRef.current;
context.current = canvas?.getContext('2d', {
willReadFrequently: true,
});
if (!context.current) {
return;
}
// Configuración del estilo del trazo
context.current.strokeStyle = signatureStylesRef.current.color;
context.current.lineWidth = signatureStylesRef.current.lineWidth;
context.current.lineCap = 'round';
context.current.lineJoin = 'round';
// Añadir event listeners al canvas
canvas?.addEventListener('mousedown', startDrawing);
canvas?.addEventListener('mousemove', draw);
canvas?.addEventListener('mouseup', stopDrawing);
canvas?.addEventListener('mouseleave', stopDrawing);
canvas?.addEventListener('touchstart', startDrawing);
canvas?.addEventListener('touchmove', draw, { passive: false });
canvas?.addEventListener('touchend', stopDrawing);
return () => {
// Limpiar event listeners al desmontar el componente
canvas?.removeEventListener('mousedown', startDrawing);
canvas?.removeEventListener('mousemove', draw);
canvas?.removeEventListener('mouseup', stopDrawing);
canvas?.removeEventListener('mouseleave', stopDrawing);
canvas?.removeEventListener('touchstart', startDrawing);
canvas?.removeEventListener('touchmove', draw);
canvas?.removeEventListener('touchend', stopDrawing);
};
}, []);
return {
canvasRef,
filled: isFilled.current,
resetCanvas,
setSignatureStyles,
};
};
exports.useDraw = useDraw;
//# sourceMappingURL=useDraw.js.map