signature_pad icon indicating copy to clipboard operation
signature_pad copied to clipboard

Drawing Issue

Open darpan-davara opened this issue 2 years ago • 3 comments

Currently I'm having one issue in use of signature_pad while drawing sign. I am attaching video of problem.

https://user-images.githubusercontent.com/52311195/180694937-803d2ce6-6949-43a2-aa62-ac3d9774b241.mp4

Thanks for your help.

darpan-davara avatar Jul 25 '22 03:07 darpan-davara

Line is not drawing exactly where mouse pointer is dragged.

darpan-davara avatar Jul 25 '22 03:07 darpan-davara

Sounds like your canvas size does not match your canvas css size.

UziTech avatar Jul 26 '22 00:07 UziTech

I have same problem.

bakerman avatar Jul 27 '22 13:07 bakerman

I hit the same thing after migrating off of the React wrapper around this library. I can confirm that @UziTech was correct. The fix was to resize the canvas to match the css size.

In React, something like:

/** Resizes a canvas to match the display size. */
const resizeCanvas = (canvas: HTMLCanvasElement, sigPad: SignaturePad) => {
  const ctx = canvas.getContext('2d');
  if (!ctx) return;
  const ratio = Math.max(window.devicePixelRatio ?? 1, 1);
  // eslint-disable-next-line no-param-reassign
  canvas.width = canvas.offsetWidth * ratio;
  // eslint-disable-next-line no-param-reassign
  canvas.height = canvas.offsetHeight * ratio;
  ctx.scale(ratio, ratio);
  sigPad.clear(); // otherwise, isEmpty() might return incorrect value
};

export const Signature = (props: SignatureProps): JSX.Element => {
  const [canvas, setCanvas] = useState<HTMLCanvasElement | null>(null);
  const [sigPad, setSigPad] = useState<SignaturePad | null>(null);

  // When the canvas element mounts, store the signature pad and canvas.
  const canvasCallback = useCallback((canvasNode: HTMLCanvasElement) => {
    if (canvasNode === null) return;
    setCanvas(canvasNode);
    const sp = new SignaturePad(canvasNode);
    setSigPad(sp);
  }, []);


  // Resize canvas immediately and on window resize so the canvas size matches
  // the display size. Otherwise, the cursor position will not match where
  // lines appear on the canvas.
  useEffect(() => {
    if (!canvas || !sigPad) return;
    const resize = () => resizeCanvas(canvas, sigPad);
    resize();
    window.addEventListener('resize', resize);
    return () => window.removeEventListener('resize', resize);
  }, [canvas, sigPad]);

  return (
      <canvas ref={canvasCallback} />
  );
}

jschaf avatar Aug 22 '22 16:08 jschaf

I am confused. I am hitting this issue too and don't understand why this is not handled by the library. In the age of responsive web design (more than 10 years), a fixed canvas width and height is not feasible.

Edit: Awesome library btw, thanks a ton @UziTech 😄

owzim avatar Nov 15 '22 17:11 owzim

@owzim this library tries to focus on the drawing of the signature. It is a library not a component which is why you pass the canvas into it instead of the library creating a canvas for you. There are components that use this library and handle creating the canvas and handling the size for you like react-signature-pad-wrapper.

UziTech avatar Nov 15 '22 21:11 UziTech