import { SIGNATURE_MIN_COVERAGE_THRESHOLD } from '@documenso/lib/constants/signatures'; import type { RefObject } from 'react'; /** * Checks whether the signature covers enough of the canvas to be considered * valid, by measuring the percentage of non-transparent pixels against * SIGNATURE_MIN_COVERAGE_THRESHOLD. */ export const checkSignatureValidity = (element: RefObject) => { if (!element.current) { return false; } const ctx = element.current.getContext('2d'); if (!ctx) { return false; } const imageData = ctx.getImageData(0, 0, element.current.width, element.current.height); const data = imageData.data; let filledPixels = 0; const totalPixels = data.length / 4; for (let i = 0; i < data.length; i += 4) { if (data[i + 3] > 0) { filledPixels++; } } const filledPercentage = filledPixels / totalPixels; const isValid = filledPercentage > SIGNATURE_MIN_COVERAGE_THRESHOLD; return isValid; }; export const average = (a: number, b: number) => (a + b) / 2; export const getSvgPathFromStroke = (points: number[][], closed = true) => { const len = points.length; if (len < 4) { return ``; } let a = points[0]; let b = points[1]; const c = points[2]; let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed( 2, )} ${average(b[0], c[0]).toFixed(2)},${average(b[1], c[1]).toFixed(2)} T`; for (let i = 2, max = len - 1; i < max; i++) { a = points[i]; b = points[i + 1]; result += `${average(a[0], b[0]).toFixed(2)},${average(a[1], b[1]).toFixed(2)} `; } if (closed) { result += 'Z'; } return result; };