forked from blackjk3/react-signature-pad
-
-
Notifications
You must be signed in to change notification settings - Fork 120
/
index.js
141 lines (118 loc) · 3.39 KB
/
index.js
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
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import SignaturePad from 'signature_pad'
import trimCanvas from 'trim-canvas'
export default class SignatureCanvas extends Component {
static propTypes = {
// signature_pad's props
velocityFilterWeight: PropTypes.number,
minWidth: PropTypes.number,
maxWidth: PropTypes.number,
minDistance: PropTypes.number,
dotSize: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
penColor: PropTypes.string,
throttle: PropTypes.number,
onEnd: PropTypes.func,
onBegin: PropTypes.func,
// props specific to the React wrapper
canvasProps: PropTypes.object,
clearOnResize: PropTypes.bool
}
static defaultProps = {
clearOnResize: true
}
_sigPad = null
_excludeOurProps = () => {
let {canvasProps, clearOnResize, ...sigPadProps} = this.props
return sigPadProps
}
componentDidMount () {
this._sigPad = new SignaturePad(this._canvas, this._excludeOurProps())
this._resizeCanvas()
this.on()
}
componentWillUnmount () {
this.off()
}
// propagate prop updates to SignaturePad
componentDidUpdate () {
Object.assign(this._sigPad, this._excludeOurProps())
}
// return the canvas ref for operations like toDataURL
getCanvas = () => {
return this._canvas
}
// return a trimmed copy of the canvas
getTrimmedCanvas = () => {
// copy the canvas
let copy = document.createElement('canvas')
copy.width = this._canvas.width
copy.height = this._canvas.height
copy.getContext('2d').drawImage(this._canvas, 0, 0)
// then trim it
return trimCanvas(copy)
}
// return the internal SignaturePad reference
getSignaturePad = () => {
return this._sigPad
}
_checkClearOnResize = () => {
if (!this.props.clearOnResize) {
return
}
this._resizeCanvas()
}
_resizeCanvas = () => {
let canvasProps = this.props.canvasProps || {}
let {width, height} = canvasProps
// don't resize if the canvas has fixed width and height
if (width && height) {
return
}
let canvas = this._canvas
/* 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. */
let ratio = Math.max(window.devicePixelRatio || 1, 1)
if (!width) {
canvas.width = canvas.offsetWidth * ratio
}
if (!height) {
canvas.height = canvas.offsetHeight * ratio
}
canvas.getContext('2d').scale(ratio, ratio)
this.clear()
}
render () {
let {canvasProps} = this.props
return <canvas ref={(ref) => { this._canvas = ref }} {...canvasProps} />
}
// all wrapper functions below render
//
on = () => {
window.addEventListener('resize', this._checkClearOnResize)
return this._sigPad.on()
}
off = () => {
window.removeEventListener('resize', this._checkClearOnResize)
return this._sigPad.off()
}
clear = () => {
return this._sigPad.clear()
}
isEmpty = () => {
return this._sigPad.isEmpty()
}
fromDataURL = (dataURL, options) => {
return this._sigPad.fromDataURL(dataURL, options)
}
toDataURL = (type, encoderOptions) => {
return this._sigPad.toDataURL(type, encoderOptions)
}
fromData = (pointGroups) => {
return this._sigPad.fromData(pointGroups)
}
toData = () => {
return this._sigPad.toData()
}
}