vue.jsvuejs2signaturepad

Why doesn't vue-signature-pad work in a modal?


I am currently using the following library: https://www.npmjs.com/package/vue-signature-pad which has the following example: https://codesandbox.io/s/n5qjp3oqv4

I am applying it as the example, but I have it in a modal:

<v-dialog v-model="canvasVehiculo" fullscreen hide-overlay transition="dialog-bottom-transition">
         <v-card>
         <v-toolbar dark color="primary">
         <v-btn icon dark @click="canvasVehiculo = false">
          <v-icon>close</v-icon>
         </v-btn>
         <v-toolbar-title>Seleccionar partes del vehiculo:</v-toolbar-title>
            <v-spacer></v-spacer>
            <v-toolbar-items>
            <v-btn dark flat @click="undo">Deshacer</v-btn>
          </v-toolbar-items>
        </v-toolbar>
        <v-list three-line subheader>
        <v-subheader></v-subheader>            
        <VueSignaturePad
         id="signature"
         width="100%"
         height="450px"
         ref="signaturePad"
        />
   </v-list>
 </v-card>

<script>
import VueSignature from 'vue-signature-pad'; //Unicamente lo importo
</script>
<style scoped>
#signature {
  border: double 3px transparent;
  border-radius: 5px;
  background-image: url('imagen.png');
  background-size: 900px 456px; 
  background-position: center;
  background-origin: border-box;
  background-clip: content-box, border-box;
}
</style>

If I use it outside of the modal, it works correctly; but in the modal, to make it work, I must modify the size of the screen (for example, by using the DevTools' Toggle device toolbar to see the responsive form).

enter image description here


Solution

  • Open DevTools and look at the canvas element. At first you will see its width and height (not width and height styles) is set to 0 then resize the window you will see width and height are change to some values and it works.

    At VueSignaturePad.js. look at resizeCanvas methods

    canvas.width = canvas.offsetWidth * ratio;
    canvas.height = canvas.offsetHeight * ratio;
    

    When v-dialog is mounted and then VueSignaturePad is mounted. The resizeCanvas is call once at mounted and at that moment somehow the canvas has no width and height (due to its parent) so it sets those values to 0. After you resize the window it will call again and update those values.

    One way to solve this is just call resizeCanvas after its parent finish render.

    this.$nextTick(() => {
      this.$refs.signaturePad.resizeCanvas();
    })
    

    See codesandbox.

    Note: The resizeCanvas is not the official method.