mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-17 13:52:14 +01:00
Show signature preview on hover Place signature smaller (mkatch preview size) Retain signature in modal on close/open Clean up ui generally Small bug fixes
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import { SignParameters } from '@app/hooks/tools/sign/useSignParameters';
|
|
import { HORIZONTAL_PADDING_RATIO, VERTICAL_PADDING_RATIO } from '@app/constants/signConstants';
|
|
|
|
export interface SignaturePreview {
|
|
dataUrl: string;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
const loadImage = (src: string): Promise<HTMLImageElement> =>
|
|
new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
img.onload = () => resolve(img);
|
|
img.onerror = reject;
|
|
img.src = src;
|
|
});
|
|
|
|
export const buildSignaturePreview = async (config: SignParameters | null): Promise<SignaturePreview | null> => {
|
|
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
return null;
|
|
}
|
|
|
|
if (!config) {
|
|
return null;
|
|
}
|
|
|
|
if (config.signatureType === 'text') {
|
|
const text = config.signerName?.trim();
|
|
if (!text) {
|
|
return null;
|
|
}
|
|
|
|
const fontSize = config.fontSize ?? 16;
|
|
const fontFamily = config.fontFamily ?? 'Helvetica';
|
|
const textColor = config.textColor ?? '#000000';
|
|
|
|
const paddingX = Math.round(fontSize * HORIZONTAL_PADDING_RATIO);
|
|
const paddingY = Math.round(fontSize * VERTICAL_PADDING_RATIO);
|
|
|
|
const measureCanvas = document.createElement('canvas');
|
|
const measureCtx = measureCanvas.getContext('2d');
|
|
|
|
if (!measureCtx) {
|
|
return null;
|
|
}
|
|
|
|
measureCtx.font = `${fontSize}px ${fontFamily}`;
|
|
const metrics = measureCtx.measureText(text);
|
|
const textWidth = Math.ceil(metrics.width);
|
|
|
|
const width = Math.max(1, textWidth + paddingX * 2);
|
|
const height = Math.max(1, Math.ceil(fontSize + paddingY * 2));
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) {
|
|
return null;
|
|
}
|
|
|
|
ctx.fillStyle = textColor;
|
|
ctx.font = `${fontSize}px ${fontFamily}`;
|
|
ctx.textBaseline = 'middle';
|
|
ctx.textAlign = 'left';
|
|
ctx.fillText(text, paddingX, height / 2);
|
|
|
|
const dataUrl = canvas.toDataURL('image/png');
|
|
return { dataUrl, width, height };
|
|
}
|
|
|
|
const dataUrl = config.signatureData;
|
|
if (!dataUrl) {
|
|
return null;
|
|
}
|
|
|
|
const image = await loadImage(dataUrl);
|
|
return {
|
|
dataUrl,
|
|
width: image.naturalWidth || image.width,
|
|
height: image.naturalHeight || image.height,
|
|
};
|
|
};
|