Signature_pad: Bug in fromDataURL for high DPI screen devices

Created on 10 Mar 2016  ·  3Comments  ·  Source: szimek/signature_pad

Description

I've found that the method fromDataURL behaves oddly on devices that don't have the pixel ratio 1, e.g. on mobile devices with high DPI.
I'm aware of the clause in the README where handling of high DPI screens is discussed.
However, I'm still able to reproduce an issue using fromDataURL in cases where the canvas is of a fixed size. I believe that this scaling of the image is the reason for this issue.
You can reproduce this issue using this JSFiddle.

Steps to reproduce

  1. Open the JSFiddled linked in the description above on a device that does not have a pixel ratio of 1 and write something on the signature pad.
  2. Click Save.
    1_after_save
  3. Click Edit.
  4. Write some more on the pad.
    2_before_cancel
  5. Click Cancel

    Expected outcome

The signature pad should look exactly like it did after step 2.

Actual outcome

The changes on the signature pad are reverted, but the image has been scaled so it looks different from what was on the pad after step 2.
3_after_cancel

Most helpful comment

Hi,

I also stumbled upon this issue. This is unexpected behavior. I think we should have a choice whether we want such modifications (so second argument defaulting to previous behavior should be fine). Mainly because something like that is not done automatically anywhere else.

Thanks a lot @siggifv for your investigation, you saved me some time.

Manually populating canvas is the way for now:

var image = new Image();
signaturePad.clear();
image.src = dataURL;
image.onload = function () {
    signatureCanvas = document.querySelector("#signature-pad");
    signatureCanvas.getContext("2d").drawImage(image, 0, 0, width, height);
};
this.signaturePad._isEmpty = false;

All 3 comments

Hi,

I also stumbled upon this issue. This is unexpected behavior. I think we should have a choice whether we want such modifications (so second argument defaulting to previous behavior should be fine). Mainly because something like that is not done automatically anywhere else.

Thanks a lot @siggifv for your investigation, you saved me some time.

Manually populating canvas is the way for now:

var image = new Image();
signaturePad.clear();
image.src = dataURL;
image.onload = function () {
    signatureCanvas = document.querySelector("#signature-pad");
    signatureCanvas.getContext("2d").drawImage(image, 0, 0, width, height);
};
this.signaturePad._isEmpty = false;

Hi Durasj,
thanks a lot... have been struggling and used your solution in my angular directive.

Hi @durasj Thanks a lot, works perfectly

my example with accessor's writeValue

  writeValue(value: string): void {
    if (!value) {
      this.signaturePad.clear();
      return;
    }
   this.value = value;
   this._drawValueToCanvas();
   this.cdr.markForCheck();
  }

  /** Draw from image according to retina or some devices  */
  _drawValueToCanvas() {
    if (this.canvas != null) {
      const image = new Image();
      this.signaturePad.clear();
      image.src = this.value;
      image.onload = () =>
        this.canvas
          .getContext('2d')
          .drawImage(image, 0, 0, 300, 120);
      this.signaturePad._isEmpty = false;
    }
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jsruok picture jsruok  ·  11Comments

derUli picture derUli  ·  3Comments

MarcGodard picture MarcGodard  ·  8Comments

khawye picture khawye  ·  4Comments

50l3r picture 50l3r  ·  3Comments