From 84fc866cfb38a179fa06814a7a58dcc0ec123317 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Thu, 30 Apr 2026 15:21:09 +1000 Subject: [PATCH] fix: improve signature rendering quality with high-resolution caching (#2745) --- .../field-renderer/render-signature-field.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/lib/universal/field-renderer/render-signature-field.ts b/packages/lib/universal/field-renderer/render-signature-field.ts index d13602b63..bd7daa6c1 100644 --- a/packages/lib/universal/field-renderer/render-signature-field.ts +++ b/packages/lib/universal/field-renderer/render-signature-field.ts @@ -40,6 +40,18 @@ const getImageDimensions = (img: HTMLImageElement, fieldWidth: number, fieldHeig }; }; +/** + * The pixel ratio used when caching the signature image as an offscreen bitmap. + * + * Konva's default redraw composites the source image with low-quality scaling + * which makes signatures look blurry, especially when the source PNG is much + * larger than the field. Caching at a high pixel ratio rasterises the shape + * once into a sharp bitmap that is then reused on every redraw. + * + * Multiplied by `devicePixelRatio` to keep the cache crisp on retina displays. + */ +const SIGNATURE_IMAGE_CACHE_PIXEL_RATIO = 2; + /** * Build a Konva.Image for a base64 signature, sized to fit within the given * field dimensions. Works in both browser and Node.js (via skia-canvas). @@ -65,6 +77,13 @@ const createSignatureImage = ( image: img, ...getImageDimensions(img, fieldWidth, fieldHeight), }); + + // Cache the image as a high-resolution bitmap so it stays sharp on + // redraws and zoom changes instead of being re-scaled from the source PNG + // every time. + image.cache({ + pixelRatio: SIGNATURE_IMAGE_CACHE_PIXEL_RATIO * (window.devicePixelRatio || 1), + }); }; img.src = signatureImageAsBase64;