This repository has been archived by the owner on Apr 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 155
/
signature-pad.ts
151 lines (123 loc) · 4.23 KB
/
signature-pad.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
'use strict';
import {AfterContentInit, Component, ElementRef, EventEmitter, Input, Output, OnDestroy} from '@angular/core';
declare var require: any;
export interface Point {
x: number;
y: number;
time: number;
}
export type PointGroup = Array<Point>;
@Component({
template: '<canvas></canvas>',
selector: 'signature-pad',
})
export class SignaturePad implements AfterContentInit, OnDestroy {
@Input() public options: Object;
@Output() public onBeginEvent: EventEmitter<boolean>;
@Output() public onEndEvent: EventEmitter<boolean>;
private signaturePad: any;
private elementRef: ElementRef;
constructor(elementRef: ElementRef) {
// no op
this.elementRef = elementRef;
this.options = this.options || {};
this.onBeginEvent = new EventEmitter();
this.onEndEvent = new EventEmitter();
}
public ngAfterContentInit(): void {
const sp: any = require('signature_pad').default;
const canvas: any = this.elementRef.nativeElement.querySelector('canvas');
if ((this.options as any).canvasHeight) {
canvas.height = (this.options as any).canvasHeight;
}
if ((this.options as any).canvasWidth) {
canvas.width = (this.options as any).canvasWidth;
}
this.signaturePad = new sp(canvas, this.options);
this.signaturePad.onBegin = this.onBegin.bind(this);
this.signaturePad.onEnd = this.onEnd.bind(this);
}
public ngOnDestroy(): void {
const canvas: any = this.elementRef.nativeElement.querySelector('canvas');
canvas.width = 0;
canvas.height = 0;
}
public resizeCanvas(): void {
// When zoomed out to less than 100%, for some very strange reason,
// some browsers report devicePixelRatio as less than 1
// and only part of the canvas is cleared then.
const ratio: number = Math.max(window.devicePixelRatio || 1, 1);
const canvas: any = this.signaturePad._canvas;
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext('2d').scale(ratio, ratio);
this.signaturePad.clear(); // otherwise isEmpty() might return incorrect value
}
// Returns signature image as an array of point groups
public toData(): Array<PointGroup> {
if (this.signaturePad) {
return this.signaturePad.toData();
} else {
return [];
}
}
// Draws signature image from an array of point groups
public fromData(points: Array<PointGroup>): void {
this.signaturePad.fromData(points);
}
// Returns signature image as data URL (see https://mdn.io/todataurl for the list of possible paramters)
public toDataURL(imageType?: string, quality?: number): string {
return this.signaturePad.toDataURL(imageType, quality); // save image as data URL
}
// Draws signature image from data URL
public fromDataURL(dataURL: string, options: any = {}): void {
// set default height and width on read data from URL
if (!options.hasOwnProperty('height') && (this.options as any).canvasHeight) {
options.height = (this.options as any).canvasHeight;
}
if (!options.hasOwnProperty('width') && (this.options as any).canvasWidth) {
options.width = (this.options as any).canvasWidth;
}
this.signaturePad.fromDataURL(dataURL, options);
}
// Clears the canvas
public clear(): void {
this.signaturePad.clear();
}
// Returns true if canvas is empty, otherwise returns false
public isEmpty(): boolean {
return this.signaturePad.isEmpty();
}
// Unbinds all event handlers
public off(): void {
this.signaturePad.off();
}
// Rebinds all event handlers
public on(): void {
this.signaturePad.on();
}
// set an option on the signaturePad - e.g. set('minWidth', 50);
public set(option: string, value: any): void {
switch (option) {
case 'canvasHeight':
this.signaturePad._canvas.height = value;
break;
case 'canvasWidth':
this.signaturePad._canvas.width = value;
break;
default:
this.signaturePad[option] = value;
}
}
// notify subscribers on signature begin
public onBegin(): void {
this.onBeginEvent.emit(true);
}
// notify subscribers on signature end
public onEnd(): void {
this.onEndEvent.emit(true);
}
public queryPad(): any {
return this.signaturePad;
}
}