Coder Social home page Coder Social logo

wobsoriano / v-perfect-signature Goto Github PK

View Code? Open in Web Editor NEW
229.0 5.0 22.0 810 KB

Pressure-sensitive signature drawing for Vue 2 and 3

Home Page: https://wobsoriano.github.io/v-perfect-signature/

License: MIT License

HTML 1.05% Vue 7.28% TypeScript 90.57% JavaScript 0.82% CSS 0.28%
canvas drawing signature html-canvas

v-perfect-signature's Introduction

v-perfect-signature

Pressure-sensitive signature drawing for Vue 2 and 3 built on top of perfect-freehand.

Demo: https://wobsoriano.github.io/v-perfect-signature

Install

pnpm add v-perfect-signature

Usage

<script setup>
import { ref } from 'vue'
import { VPerfectSignature } from 'v-perfect-signature'

const signaturePad = ref()
const strokeOptions = {
  size: 16,
  thinning: 0.75,
  smoothing: 0.5,
  streamline: 0.5,
}

function toDataURL() {
  const dataURL = signaturePad.value.toDataURL()
  console.log(dataURL)
}
</script>

<template>
  <VPerfectSignature ref="signaturePad" :stroke-options="strokeOptions" />
</template>

Props

Name Type Default Description
width String 100% Set canvas width
height String 100% Set canvas height
backgroundColor String rgba(0,0,0,0) Canvas background color
penColor String #000 Canvas pen color
strokeOptions Object Reference Perfect freehand options

Methods

Name Argument Type Description
toDataURL(type) String Returns signature image as data URL
fromDataURL(dataUri) String Draws signature image from data URL
toData - Returns signature image as an array of array of input points
fromData(data) Array Draws signature image from array of array of input points
clear() - Clears the canvas
isEmpty() - Returns true if canvas is empty
resizeCanvas(shouldClear) Boolean Resizes and recalculate dimensions

Note: Like signature_pad, fromDataURL does not populate internal data structure. Thus, after using fromDataURL, toData won't work properly.

Events

Name Type Default Description
onBegin Function - Fired when stroke begin
onEnd Function - Fired when stroke end

Nuxt

export default defineNuxtConfig({
  build: {
    transpile: ['v-perfect-signature']
  }
})

License

MIT

v-perfect-signature's People

Contributors

ibrahimbeladi avatar josedabm avatar trijpstra-fourlights avatar wobsoriano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

v-perfect-signature's Issues

fromDataURL does not scale properly on HiDPI screens

Thanks for this component. I noticed that the current implementation for fromDataURL does not work properly on HiDPI screens (i.e. window.devicePixelRatio > 1).

When using drawImage on a canvas, you need to reset the scale before drawing the image, and then set the scale again.

I've created a repo:

Url:
https://jake.stackblitz.com/edit/vue3-vite-typescript-starter-sharha?file=src/App.vue

To reproduce:
Go to inspector in chrome, toggle device toolbar. Set on 'responsiveness' device. Three dots menu on the top right -> add device pixel ratio. Now you can set the DPR to 1, 2 or 3.

Reload the page after changing the DPR and press "load image". You'll see that the image does not scale properly on the canvas.
You need to reload the page to see the effect.

I've created a fix for which I'll open a PR.

perfect-freehand throws an error when using in vitest

Hello! Recently I've added v-perfect-signature to the project I'm writing and it's working great. I wanted to write some tests though, and got the following error.

FAIL src/tests/components/VComponent.spec.ts [ src/tests/components/VComponent.spec.ts ]
SyntaxError: Unexpected token 'export'
Module /project/node_modules/perfect-freehand/dist/esm/index.js:1 seems to be an ES Module but shipped in a CommonJS package. You might want to create an issue to the package "perfect-freehand" asking them to ship the file in .mjs extension or add "type": "module" in their package.json.

As a temporary workaround you can try to inline the package by updating your config:

// vitest.config.js
export default {
  test: {
    server: {
      deps: {
        inline: [
          "perfect-freehand"
        ]
      }
    }
  }
}

I'm using vue 3 and vitest 0.34.4.

I've made some research and found out this issue with perfect-freehand. As you can see, it has been resolved and pushed, although there wasn't any official release since the push. I've tested changing manually package.json in my node_modules to check, if this solution resolves my issue, and it does, so I assume it's just a matter of updating the dependency and potentially releasing new version for perfect-signature. I'm going to write about that in the mentioned issue too and hopefully they will do a release, so that it will just be matter of updating the version.

getStroke not found

image
I have a problem here, I am using nuxt 3 and trying to use v-perfect-signature

Changing penColor changes existing paths

I implemented a very simple color-picker and paired it with v-perfect-signature. Looking at Perfect Freehand's example page, it is possible to draw paths with different colors onto the canvas. Is it possible to do this with v-perfect-signature as well? Currently, when modifying the penColor-prop, it affects all existing paths.

Example:

Oct-12-2021 02-49-38

Thanks!

References to access methods in a v-for fail (vue 2)

 <v-col
    cols="12"
    v-for="(signature, index) in formData.signatures"
    :key="index"
  >
        <VPerfectSignature
          width="100%"
          height="300px"
          :stroke-options="strokeOptions"
          :ref="`signatures${index}`"
        />
       <v-btn  @click="$refs[`signatures${index}`].clear()">Clear</v-btn>
 </v-col>

ERROR:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in v-on handler: "TypeError: _vm.$refs[("signatures" + index)].clear is not a function"

vue.runtime.esm.js?2b0e:1897 TypeError: _vm.$refs[("signatures" + index)].clear is not a function

Clear function doesn't work as expected

when emitting the clear function it clears the top left section and keeps a weird border
image

html:

<div class="container">
    <VPerfectSignature
	    background="transparent"
	    :stroke-options="strokeOptions"
	    ref="signaturePad"
	    class="canvas" width="30em"
	    @onEnd="updateDataURL"
    />
    <div class="settings">
	    <button @click="clearCanvas">Clear Signature</button>
    </div>
</div>

script:

import { ref } from 'vue';
import { VPerfectSignature } from 'v-perfect-signature';

const emit = defineEmits('update:modelValue')

const signaturePad = ref();
const strokeOptions = {
	size: 10,
	thinning: 0.75,
	smoothing: .5,
	streamline: 0.5,
};

const updateDataURL = () => {
	emit('update:modelValue', signaturePad.value.toDataURL())
}

const clearCanvas = () => {
	signaturePad.value.clear();
};

Vue2 errors with vue-demi

When adding the library in Vue2 I get the following errors:

ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(7,34):
7:34 '"./frontend/node_modules/vue-demi/lib/index"' has no exported member named 'DefineComponent'. Did you mean 'defineComponent'?
     5 | 
     6 | declare type InputPoints = number[];
  >  7 | declare const _default: vue_demi.DefineComponent<{
       |                                  ^
     8 |     width: {
     9 |         type: StringConstructor;
    10 |         required: false;
ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(54,13):
54:13 Namespace '"./frontend/node_modules/vue-demi/lib/index"' has no exported member 'ComponentOptionsMixin'.
    52 |     resizeCanvas(clearCanvas?: boolean): void;
    53 |     inputPointsHandler(): void;
  > 54 | }, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("onBegin" | "onEnd")[], "onBegin" | "onEnd", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<{
       |             ^
    55 |     width?: unknown;
    56 |     height?: unknown;
    57 |     backgroundColor?: unknown;
ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(54,45):
54:45 Namespace '"./frontend/node_modules/vue-demi/lib/index"' has no exported member 'ComponentOptionsMixin'.
    52 |     resizeCanvas(clearCanvas?: boolean): void;
    53 |     inputPointsHandler(): void;
  > 54 | }, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("onBegin" | "onEnd")[], "onBegin" | "onEnd", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<{
       |                                             ^
    55 |     width?: unknown;
    56 |     height?: unknown;
    57 |     backgroundColor?: unknown;
ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(54,123):
54:123 Namespace '"./frontend/node_modules/vue-demi/lib/index"' has no exported member 'VNodeProps'.
    52 |     resizeCanvas(clearCanvas?: boolean): void;
    53 |     inputPointsHandler(): void;
  > 54 | }, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("onBegin" | "onEnd")[], "onBegin" | "onEnd", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<{
       |                                                                                                                           ^
    55 |     width?: unknown;
    56 |     height?: unknown;
    57 |     backgroundColor?: unknown;
ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(54,145):
54:145 Namespace '"./frontend/node_modules/vue-demi/lib/index"' has no exported member 'AllowedComponentProps'.
    52 |     resizeCanvas(clearCanvas?: boolean): void;
    53 |     inputPointsHandler(): void;
  > 54 | }, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("onBegin" | "onEnd")[], "onBegin" | "onEnd", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<{
       |                                                                                                                                                 ^
    55 |     width?: unknown;
    56 |     height?: unknown;
    57 |     backgroundColor?: unknown;
ERROR in ./frontend/node_modules/v-perfect-signature/dist/index.d.ts(54,178):
54:178 Namespace '"./frontend/node_modules/vue-demi/lib/index"' has no exported member 'ComponentCustomProps'.
    52 |     resizeCanvas(clearCanvas?: boolean): void;
    53 |     inputPointsHandler(): void;
  > 54 | }, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("onBegin" | "onEnd")[], "onBegin" | "onEnd", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<{
       |                                                                                                                                                                                  ^
    55 |     width?: unknown;
    56 |     height?: unknown;
    57 |     backgroundColor?: unknown;

v-perfect-signature: 1.0.0
vue: 2.6.14

When I set "skipLibCheck": true in tsconfig.ts everything works fine.

integration with laravel nova

Hello,

I've made a custom field component for laravel noval to integrate v-perfect-signature.
I've got error "Uncaught TypeError: window.Vue.use is not a function"

<script>
import { FormField, HandlesValidationErrors } from 'laravel-nova'
import { VPerfectSignature } from 'v-perfect-signature';

export default {
  components: [ VPerfectSignature ],  

package.json

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "prod": "npm run production",
    "production": "mix --production",
    "nova:install": "npm --prefix='../../vendor/laravel/nova' ci"
  },
  "devDependencies": {
    "@vue/compiler-sfc": "^3.2.22",
    "form-backend-validation": "^2.3.3",
    "laravel-mix": "^6.0.41",
    "lodash": "^4.17.21",
    "postcss": "^8.3.11",
    "vue-loader": "^16.8.3"
  },
  "dependencies": {
    "@vue/composition-api": "^1.7.2",
    "v-perfect-signature": "^1.2.1"
  }
}

Any idea what occurs?

Regards

Ios 12 BUG

Hi,
Thanks for your work
Many peoples still using safari 12, our project draws only one point before crashing
Please consider compatibilty for using in production project

regards

Using v-perfect-signature with an initially hidden parent element (modals/dialogs/tabs)

I'm trying to use this in a modal/dialog context (specifically I'm using Quasar's Dialog). This means that, when the component is drawn, the parent element is hidden. This appears to be causing the canvas to end up with zero height and width. I would have thought that I could just call resizeCanvas() once my modal has been rendered (with a show()-callback), but that doesn't seem to work either. I guess a similar use case could be when using the signature pad in a tab that's initially hidden on page render.

Do you have any suggestions on how to handle such a use case?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.