react-native-signature-canvas 4.7.1 → 4.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +205 -380
- package/h5/js/app.js +1 -0
- package/index.d.ts +10 -5
- package/index.js +24 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# React Native Signature Canvas
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/react-native-signature-canvas)
|
|
4
4
|
[](https://www.npmjs.com/package/react-native-signature-canvas)
|
|
@@ -6,15 +6,22 @@
|
|
|
6
6
|

|
|
7
7
|
[](https://github.com/expo/expo)
|
|
8
8
|
|
|
9
|
-
React Native
|
|
9
|
+
A React Native component for capturing signatures or drawing on a canvas with a smooth, native feel. Works on iOS, Android, and Expo.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- Tested with RN 0.69
|
|
13
|
-
- Core use [signature_pad.js](https://github.com/szimek/signature_pad)
|
|
14
|
-
- Generates a base64 encoded png image of the signature
|
|
15
|
-
Note: Expo support for React Native Signature Canvas v1.5.0 started with Expo SDK v33.0.0.
|
|
11
|
+
## Features
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
- Cross-platform support (iOS, Android, Expo)
|
|
14
|
+
- Smooth, responsive drawing experience
|
|
15
|
+
- Customizable pen color, size, and background
|
|
16
|
+
- Support for background and overlay images
|
|
17
|
+
- Export signatures as PNG, JPEG, or SVG
|
|
18
|
+
- Undo/redo functionality
|
|
19
|
+
- Drawing and erasing modes
|
|
20
|
+
- TypeScript support
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### For React Native ≥ 0.60.0 or Expo SDK ≥ 35.0.0
|
|
18
25
|
|
|
19
26
|
```bash
|
|
20
27
|
yarn add react-native-signature-canvas
|
|
@@ -26,140 +33,157 @@ or
|
|
|
26
33
|
npm install --save react-native-signature-canvas
|
|
27
34
|
```
|
|
28
35
|
|
|
29
|
-
> This package depends on [react-native-webview](https://github.com/react-native-webview/react-native-webview
|
|
30
|
-
|
|
36
|
+
> This package depends on [react-native-webview](https://github.com/react-native-webview/react-native-webview). If you're using React Native CLI (not Expo), you'll need to install react-native-webview separately:
|
|
37
|
+
>
|
|
38
|
+
> ```bash
|
|
39
|
+
> yarn add react-native-webview
|
|
40
|
+
> cd ios && pod install
|
|
41
|
+
> ```
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
## Installation(for React Native V0.5x.x or Expo SDK < v33)
|
|
43
|
+
### For React Native < 0.60.0 or Expo SDK < 33.0.0
|
|
34
44
|
|
|
35
45
|
```bash
|
|
36
46
|
npm install --save react-native-signature-canvas@1.4.2
|
|
37
47
|
```
|
|
38
48
|
|
|
39
|
-
## Usage
|
|
40
|
-
Basic
|
|
41
|
-
```js
|
|
42
|
-
import Signature from "react-native-signature-canvas";
|
|
43
|
-
```
|
|
44
|
-
Custom
|
|
45
|
-
```js
|
|
46
|
-
import SignatureScreen from 'react-native-signature-canvas';
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Properties
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
| Prop | Type | Description |
|
|
54
|
-
|:------------------------------------|:----------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
55
|
-
| androidHardwareAccelerationDisabled | `boolean` | androidHardwareAccelerationDisabled for react-native-webview. Default is false |
|
|
56
|
-
| autoClear | `boolean` | should auto clear the signature after clicking the Confirm button |
|
|
57
|
-
| backgroundColor | `string` | default is "rgba(255,255,255,0)" (_transparent_), background color of the canvas |
|
|
58
|
-
| bgHeight | `number` | height of the background image |
|
|
59
|
-
| bgWidth | `number` | width of the background image |
|
|
60
|
-
| bgSrc | `string` | background image source uri (_url_) |
|
|
61
|
-
| clearText | `string` | clear button text |
|
|
62
|
-
| confirmText | `string` | save button text |
|
|
63
|
-
| customHtml | `(injectedJavaScript: string) => string` | html string that lets you modify things like the layout or elements |
|
|
64
|
-
| dataURL | `string` | default is "", Base64 string, draws saved signature from dataURL. |
|
|
65
|
-
| descriptionText | `string` | description text for signature |
|
|
66
|
-
| dotSize | `number` | radius of a single dot _(not stroke width)_ |
|
|
67
|
-
| imageType | `string` | "image/png" (_default_), "image/jpeg"、"image/svg+xml", imageType of exported signature |
|
|
68
|
-
| minWidth | `number` | minimum width of a line. Defaults to 0.5 |
|
|
69
|
-
| maxWidth | `number` | maximum width of a line. Defaults to 2.5 |
|
|
70
|
-
| onOK | `function` | callback function after saving non-empty signature |
|
|
71
|
-
| onEmpty | `function` | callback function after trying to save an empty signature |
|
|
72
|
-
| onClear | `function` | callback function after clearing the signature |
|
|
73
|
-
| onGetData | `function` | callback function when getData() is called
|
|
74
|
-
| onBegin | `function` | callback function when a new stroke is started |
|
|
75
|
-
| onEnd | `function` | callback function when the stroke has ended |
|
|
76
|
-
| onLoadEnd | `function` | callback function when the webview canvas load ended |
|
|
77
|
-
| onUndo | `function` | callback function when undo() is called |
|
|
78
|
-
| onRedo | `function` | callback function when redo() is called |
|
|
79
|
-
| onDraw | `function` | callback function when drawing is enabled |
|
|
80
|
-
| onErase | `function` | callback function when erasing is enabled |
|
|
81
|
-
| onChangePenColor | `function` | callback function after changing the pen color |
|
|
82
|
-
| onChangePenSize | `function` | callback function after changing the pen size
|
|
83
|
-
| overlayHeight | `number` | height of the overlay image |
|
|
84
|
-
| overlayWidth | `number` | width of the overlay image |
|
|
85
|
-
| overlaySrc | `string` | overlay image source uri (url) _must be .png with a transparent background_
|
|
86
|
-
| penColor | `string` | default is "black", color of pen |
|
|
87
|
-
| rotated | `boolean` | rotate signature pad 90 degrees |
|
|
88
|
-
| style | `object` | style of wrapper view |
|
|
89
|
-
| trimWhitespace | `boolean` | trim image whitespace |
|
|
90
|
-
| webStyle | `string` | webview style for overwrite default style, all style: https://github.com/YanYuanFE/react-native-signature-canvas/blob/master/h5/css/signature-pad.css |
|
|
91
|
-
| androidLayerType | `none、software、hardware` | Sets the android webview layerType |
|
|
92
|
-
|
|
93
|
-
## Methods
|
|
94
|
-
|
|
95
|
-
---
|
|
49
|
+
## Basic Usage
|
|
96
50
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
| changePenSize(minW, maxW) | Change pen size |
|
|
102
|
-
| draw() | Enable drawing signature |
|
|
103
|
-
| erase() | Enable erasing signature |
|
|
104
|
-
| getData() | Triggers the `onGetData` callback with a single `data` JSON string |
|
|
105
|
-
| readSignature() | Reads the current signature on the canvas and triggers either the `onOK` or `onEmpty` callbacks |
|
|
106
|
-
| undo() | Undo last stroke |
|
|
107
|
-
| redo() | Redo last stroke |
|
|
51
|
+
```jsx
|
|
52
|
+
import React, { useRef, useState } from 'react';
|
|
53
|
+
import { StyleSheet, View, Image } from 'react-native';
|
|
54
|
+
import SignatureCanvas from 'react-native-signature-canvas';
|
|
108
55
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```js
|
|
112
|
-
import SignatureScreen from "react-native-signature-canvas";
|
|
113
|
-
|
|
114
|
-
const Sign = ({ text, onOK }) => {
|
|
56
|
+
const SignatureScreen = () => {
|
|
57
|
+
const [signature, setSignature] = useState(null);
|
|
115
58
|
const ref = useRef();
|
|
116
59
|
|
|
117
|
-
|
|
118
|
-
const handleOK = (signature) => {
|
|
60
|
+
const handleSignature = (signature) => {
|
|
119
61
|
console.log(signature);
|
|
120
|
-
|
|
62
|
+
setSignature(signature);
|
|
121
63
|
};
|
|
122
64
|
|
|
123
|
-
// Called after ref.current.readSignature() reads an empty string
|
|
124
65
|
const handleEmpty = () => {
|
|
125
|
-
console.log(
|
|
66
|
+
console.log('Empty');
|
|
126
67
|
};
|
|
127
68
|
|
|
128
|
-
// Called after ref.current.clearSignature()
|
|
129
69
|
const handleClear = () => {
|
|
130
|
-
console.log(
|
|
70
|
+
console.log('Clear success!');
|
|
131
71
|
};
|
|
132
72
|
|
|
133
|
-
// Called after end of stroke
|
|
134
73
|
const handleEnd = () => {
|
|
135
74
|
ref.current.readSignature();
|
|
136
75
|
};
|
|
137
76
|
|
|
138
|
-
// Called after ref.current.getData()
|
|
139
|
-
const handleData = (data) => {
|
|
140
|
-
console.log(data);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
77
|
return (
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
78
|
+
<View style={styles.container}>
|
|
79
|
+
<View style={styles.preview}>
|
|
80
|
+
{signature && (
|
|
81
|
+
<Image
|
|
82
|
+
resizeMode="contain"
|
|
83
|
+
style={{ width: 335, height: 114 }}
|
|
84
|
+
source={{ uri: signature }}
|
|
85
|
+
/>
|
|
86
|
+
)}
|
|
87
|
+
</View>
|
|
88
|
+
<SignatureCanvas
|
|
89
|
+
ref={ref}
|
|
90
|
+
onEnd={handleEnd}
|
|
91
|
+
onOK={handleSignature}
|
|
92
|
+
onEmpty={handleEmpty}
|
|
93
|
+
onClear={handleClear}
|
|
94
|
+
autoClear={true}
|
|
95
|
+
descriptionText="Sign here"
|
|
96
|
+
clearText="Clear"
|
|
97
|
+
confirmText="Save"
|
|
98
|
+
/>
|
|
99
|
+
</View>
|
|
154
100
|
);
|
|
155
101
|
};
|
|
156
102
|
|
|
157
|
-
|
|
103
|
+
const styles = StyleSheet.create({
|
|
104
|
+
container: {
|
|
105
|
+
flex: 1,
|
|
106
|
+
},
|
|
107
|
+
preview: {
|
|
108
|
+
width: 335,
|
|
109
|
+
height: 114,
|
|
110
|
+
backgroundColor: '#F8F8F8',
|
|
111
|
+
justifyContent: 'center',
|
|
112
|
+
alignItems: 'center',
|
|
113
|
+
marginTop: 15,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
export default SignatureScreen;
|
|
158
118
|
```
|
|
159
|
-
## Using a background image
|
|
160
|
-
You can use a non-erasable background image to draw your signature on using the `bgSrc` prop. Make sure to provide the width and height of the image.
|
|
161
119
|
|
|
162
|
-
|
|
120
|
+
## Props
|
|
121
|
+
|
|
122
|
+
| Prop | Type | Default | Description |
|
|
123
|
+
|------|------|---------|-------------|
|
|
124
|
+
| `androidHardwareAccelerationDisabled` | `boolean` | `false` | Disable hardware acceleration on Android |
|
|
125
|
+
| `autoClear` | `boolean` | `false` | Auto clear signature after clicking the Confirm button |
|
|
126
|
+
| `backgroundColor` | `string` | `rgba(255,255,255,0)` | Background color of the canvas |
|
|
127
|
+
| `bgHeight` | `number` | `0` | Height of the background image |
|
|
128
|
+
| `bgWidth` | `number` | `0` | Width of the background image |
|
|
129
|
+
| `bgSrc` | `string` | `null` | Background image source URI |
|
|
130
|
+
| `clearText` | `string` | `Clear` | Clear button text |
|
|
131
|
+
| `confirmText` | `string` | `Confirm` | Save button text |
|
|
132
|
+
| `customHtml` | `(injectedJavaScript: string) => string` | `null` | Custom HTML template for the canvas |
|
|
133
|
+
| `dataURL` | `string` | `""` | Base64 string to draw saved signature |
|
|
134
|
+
| `descriptionText` | `string` | `Sign above` | Description text for signature |
|
|
135
|
+
| `dotSize` | `number` | `null` | Radius of a single dot |
|
|
136
|
+
| `imageType` | `string` | `image/png` | Image type for export (`image/png`, `image/jpeg`, `image/svg+xml`) |
|
|
137
|
+
| `minWidth` | `number` | `0.5` | Minimum width of a line |
|
|
138
|
+
| `maxWidth` | `number` | `2.5` | Maximum width of a line |
|
|
139
|
+
| `nestedScrollEnabled` | `boolean` | `false` | Enable nested scrolling for use inside a ScrollView |
|
|
140
|
+
| `showsVerticalScrollIndicator` | `boolean` | `true` | Show vertical scroll indicator in WebView |
|
|
141
|
+
| `onOK` | `function` | - | Callback after saving non-empty signature |
|
|
142
|
+
| `onEmpty` | `function` | - | Callback after trying to save an empty signature |
|
|
143
|
+
| `onClear` | `function` | - | Callback after clearing the signature |
|
|
144
|
+
| `onGetData` | `function` | - | Callback when getData() is called |
|
|
145
|
+
| `onBegin` | `function` | - | Callback when a new stroke is started |
|
|
146
|
+
| `onEnd` | `function` | - | Callback when the stroke has ended |
|
|
147
|
+
| `onLoadEnd` | `function` | - | Callback when the WebView canvas load ended |
|
|
148
|
+
| `onUndo` | `function` | - | Callback when undo() is called |
|
|
149
|
+
| `onRedo` | `function` | - | Callback when redo() is called |
|
|
150
|
+
| `onDraw` | `function` | - | Callback when drawing is enabled |
|
|
151
|
+
| `onErase` | `function` | - | Callback when erasing is enabled |
|
|
152
|
+
| `onChangePenColor` | `function` | - | Callback after changing the pen color |
|
|
153
|
+
| `onChangePenSize` | `function` | - | Callback after changing the pen size |
|
|
154
|
+
| `overlayHeight` | `number` | `0` | Height of the overlay image |
|
|
155
|
+
| `overlayWidth` | `number` | `0` | Width of the overlay image |
|
|
156
|
+
| `overlaySrc` | `string` | `null` | Overlay image source URI (must be PNG with transparent background) |
|
|
157
|
+
| `penColor` | `string` | `black` | Color of the pen |
|
|
158
|
+
| `rotated` | `boolean` | `false` | Rotate signature pad 90 degrees |
|
|
159
|
+
| `style` | `object` | - | Style of the wrapper view |
|
|
160
|
+
| `scrollable` | `boolean` | `false` | Enable scrolling in the signature pad |
|
|
161
|
+
| `trimWhitespace` | `boolean` | `false` | Trim image whitespace |
|
|
162
|
+
| `webStyle` | `string` | - | WebView style to override default style |
|
|
163
|
+
| `webviewContainerStyle` | `object` | - | Style for the WebView container |
|
|
164
|
+
| `androidLayerType` | `none\|software\|hardware` | `hardware` | Sets the Android WebView layer type |
|
|
165
|
+
|
|
166
|
+
## Methods
|
|
167
|
+
|
|
168
|
+
Access these methods using a ref to the SignatureCanvas component.
|
|
169
|
+
|
|
170
|
+
| Method | Description |
|
|
171
|
+
|--------|-------------|
|
|
172
|
+
| `clearSignature()` | Clear the current signature |
|
|
173
|
+
| `changePenColor(color)` | Change pen color |
|
|
174
|
+
| `changePenSize(minW, maxW)` | Change pen size |
|
|
175
|
+
| `draw()` | Enable drawing mode |
|
|
176
|
+
| `erase()` | Enable erasing mode |
|
|
177
|
+
| `getData()` | Triggers the `onGetData` callback with signature data |
|
|
178
|
+
| `readSignature()` | Read the current signature and trigger callbacks |
|
|
179
|
+
| `undo()` | Undo last stroke |
|
|
180
|
+
| `redo()` | Redo last stroke |
|
|
181
|
+
|
|
182
|
+
## Advanced Usage
|
|
183
|
+
|
|
184
|
+
### Using a Background Image
|
|
185
|
+
|
|
186
|
+
```jsx
|
|
163
187
|
const imgWidth = 300;
|
|
164
188
|
const imgHeight = 200;
|
|
165
189
|
const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
@@ -167,24 +191,22 @@ const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
|
167
191
|
.m-signature-pad--footer {display: none; margin: 0px;}
|
|
168
192
|
body,html {
|
|
169
193
|
width: ${imgWidth}px; height: ${imgHeight}px;}`;
|
|
170
|
-
|
|
194
|
+
|
|
171
195
|
<View style={{ width: imgWidth, height: imgHeight }}>
|
|
172
|
-
<
|
|
196
|
+
<SignatureCanvas
|
|
173
197
|
ref={ref}
|
|
174
|
-
bgSrc="https://
|
|
198
|
+
bgSrc="https://example.com/background.jpg"
|
|
175
199
|
bgWidth={imgWidth}
|
|
176
200
|
bgHeight={imgHeight}
|
|
177
201
|
webStyle={style}
|
|
178
|
-
onOK={
|
|
202
|
+
onOK={handleSignature}
|
|
179
203
|
/>
|
|
180
204
|
</View>
|
|
181
205
|
```
|
|
182
206
|
|
|
183
|
-
|
|
184
|
-
An overlay is a non-erasable image that can be used as a guideline similar to a colouring book. Make sure the image format is .png and that it has a transparent background. Also, don't forget to provide the width and height of the image.
|
|
185
|
-
Use the `overlaySrc` prop to provide the link.
|
|
207
|
+
### Using an Overlay Image
|
|
186
208
|
|
|
187
|
-
```
|
|
209
|
+
```jsx
|
|
188
210
|
const imgWidth = 256;
|
|
189
211
|
const imgHeight = 256;
|
|
190
212
|
const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
@@ -192,299 +214,102 @@ const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
|
192
214
|
.m-signature-pad--footer {display: none; margin: 0px;}
|
|
193
215
|
body,html {
|
|
194
216
|
width: ${imgWidth}px; height: ${imgHeight}px;}`;
|
|
195
|
-
|
|
217
|
+
|
|
196
218
|
<View style={{ width: imgWidth, height: imgHeight }}>
|
|
197
|
-
<
|
|
219
|
+
<SignatureCanvas
|
|
198
220
|
ref={ref}
|
|
199
|
-
overlaySrc="
|
|
221
|
+
overlaySrc="https://example.com/overlay.png" // Must be PNG with transparent background
|
|
200
222
|
overlayWidth={imgWidth}
|
|
201
223
|
overlayHeight={imgHeight}
|
|
202
224
|
webStyle={style}
|
|
203
|
-
onOK={
|
|
225
|
+
onOK={handleSignature}
|
|
204
226
|
/>
|
|
205
227
|
</View>
|
|
206
228
|
```
|
|
207
229
|
|
|
208
|
-
|
|
230
|
+
### Using in a Modal
|
|
209
231
|
|
|
210
|
-
|
|
232
|
+
```jsx
|
|
233
|
+
import React, { useState, useRef } from 'react';
|
|
234
|
+
import { StyleSheet, View, TouchableOpacity, Modal, Text } from 'react-native';
|
|
235
|
+
import SignatureCanvas from 'react-native-signature-canvas';
|
|
211
236
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const handleOK = (signature) => {
|
|
216
|
-
const path = FileSystem.cacheDirectory + "sign.png";
|
|
217
|
-
FileSystem.writeAsStringAsync(
|
|
218
|
-
path,
|
|
219
|
-
signature.replace("data:image/png;base64,", ""),
|
|
220
|
-
{ encoding: FileSystem.EncodingType.Base64 }
|
|
221
|
-
)
|
|
222
|
-
.then(() => FileSystem.getInfoAsync(path))
|
|
223
|
-
.then(console.log)
|
|
224
|
-
.catch(console.error);
|
|
225
|
-
};
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## Basic parameters
|
|
229
|
-
|
|
230
|
-
```js
|
|
231
|
-
<Signature
|
|
232
|
-
// handle when you click save button
|
|
233
|
-
onOK={(img) => console.log(img)}
|
|
234
|
-
onEmpty={() => console.log("empty")}
|
|
235
|
-
// description text for signature
|
|
236
|
-
descriptionText="Sign"
|
|
237
|
-
// clear button text
|
|
238
|
-
clearText="Clear"
|
|
239
|
-
// save button text
|
|
240
|
-
confirmText="Save"
|
|
241
|
-
// String, webview style for overwrite default style, all style: https://github.com/YanYuanFE/react-native-signature-canvas/blob/master/h5/css/signature-pad.css
|
|
242
|
-
webStyle={`.m-signature-pad--footer
|
|
243
|
-
.button {
|
|
244
|
-
background-color: red;
|
|
245
|
-
color: #FFF;
|
|
246
|
-
}`}
|
|
247
|
-
autoClear={true}
|
|
248
|
-
imageType={"image/svg+xml"}
|
|
249
|
-
/>
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
If you create your own triggers for the readSignature and/or clearSignature you can hide the built in Clear and Save buttons with css styles passed into the **webStyle** property.
|
|
253
|
-
|
|
254
|
-
```js
|
|
255
|
-
const webStyle = `.m-signature-pad--footer
|
|
256
|
-
.save {
|
|
257
|
-
display: none;
|
|
258
|
-
}
|
|
259
|
-
.clear {
|
|
260
|
-
display: none;
|
|
261
|
-
}
|
|
262
|
-
`;
|
|
263
|
-
...
|
|
264
|
-
<Signature
|
|
265
|
-
webStyle={webStyle}
|
|
266
|
-
onOK={handleOK}
|
|
267
|
-
onEmpty={handleEmpty}
|
|
268
|
-
onEnd={handleEnd}
|
|
269
|
-
/>
|
|
270
|
-
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
## Custom Button for Confirm and Clear
|
|
274
|
-
|
|
275
|
-
```js
|
|
276
|
-
import React, { useRef } from "react";
|
|
277
|
-
import { StyleSheet, View, Button } from "react-native";
|
|
278
|
-
import SignatureScreen from "react-native-signature-canvas";
|
|
279
|
-
|
|
280
|
-
const Sign = ({ onOK }) => {
|
|
237
|
+
const SignatureModal = ({ onSignature }) => {
|
|
238
|
+
const [show, setShow] = useState(false);
|
|
281
239
|
const ref = useRef();
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const handleClear = () => {
|
|
289
|
-
ref.current.clearSignature();
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const handleConfirm = () => {
|
|
293
|
-
console.log("end");
|
|
294
|
-
ref.current.readSignature();
|
|
240
|
+
|
|
241
|
+
const handleSignature = (signature) => {
|
|
242
|
+
onSignature(signature);
|
|
243
|
+
setShow(false);
|
|
295
244
|
};
|
|
296
245
|
|
|
297
|
-
const style = `.m-signature-pad--footer {display: none; margin: 0px;}`;
|
|
298
|
-
|
|
299
246
|
return (
|
|
300
|
-
<View
|
|
301
|
-
<
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
247
|
+
<View>
|
|
248
|
+
<TouchableOpacity onPress={() => setShow(true)}>
|
|
249
|
+
<Text>Open Signature Pad</Text>
|
|
250
|
+
</TouchableOpacity>
|
|
251
|
+
|
|
252
|
+
{show && (
|
|
253
|
+
<Modal>
|
|
254
|
+
<SignatureCanvas
|
|
255
|
+
ref={ref}
|
|
256
|
+
onOK={handleSignature}
|
|
257
|
+
onEmpty={() => console.log('Empty')}
|
|
258
|
+
descriptionText="Sign here"
|
|
259
|
+
penColor="rgba(255,117,2,1)"
|
|
260
|
+
/>
|
|
261
|
+
</Modal>
|
|
262
|
+
)}
|
|
306
263
|
</View>
|
|
307
264
|
);
|
|
308
265
|
};
|
|
309
|
-
|
|
310
|
-
export default Sign;
|
|
311
|
-
|
|
312
|
-
const styles = StyleSheet.create({
|
|
313
|
-
container: {
|
|
314
|
-
flex: 1,
|
|
315
|
-
alignItems: "center",
|
|
316
|
-
justifyContent: "center",
|
|
317
|
-
height: 250,
|
|
318
|
-
padding: 10,
|
|
319
|
-
},
|
|
320
|
-
row: {
|
|
321
|
-
display: "flex",
|
|
322
|
-
flexDirection: "row",
|
|
323
|
-
justifyContent: "space-between",
|
|
324
|
-
width: "100%",
|
|
325
|
-
alignItems: "center",
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
266
|
```
|
|
329
267
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
- Android <br/>
|
|
333
|
-
<img src="http://img.yanyuanfe.cn/signature-android.png" width="400" />
|
|
334
|
-
|
|
335
|
-
- iOS <br/>
|
|
336
|
-
<img src="http://img.yanyuanfe.cn/signature-ios.png" width="400" />
|
|
268
|
+
### Scrollable Signature Canvas
|
|
337
269
|
|
|
338
|
-
```
|
|
339
|
-
import React, { useState } from
|
|
340
|
-
import {
|
|
341
|
-
import
|
|
270
|
+
```jsx
|
|
271
|
+
import React, { useRef, useState } from 'react';
|
|
272
|
+
import { View, StyleSheet, ScrollView } from 'react-native';
|
|
273
|
+
import SignatureCanvas from 'react-native-signature-canvas';
|
|
342
274
|
|
|
343
|
-
|
|
344
|
-
const [
|
|
345
|
-
|
|
346
|
-
const handleOK = (signature) => {
|
|
347
|
-
console.log(signature);
|
|
348
|
-
setSign(signature);
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
const handleEmpty = () => {
|
|
352
|
-
console.log("Empty");
|
|
353
|
-
};
|
|
275
|
+
const ScrollableSignature = () => {
|
|
276
|
+
const [scrollEnabled, setScrollEnabled] = useState(true);
|
|
277
|
+
const signatureRef = useRef(null);
|
|
354
278
|
|
|
355
|
-
const style = `.m-signature-pad--footer
|
|
356
|
-
.button {
|
|
357
|
-
background-color: red;
|
|
358
|
-
color: #FFF;
|
|
359
|
-
}`;
|
|
360
279
|
return (
|
|
361
|
-
<
|
|
362
|
-
<View style={styles.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
) : null}
|
|
280
|
+
<ScrollView scrollEnabled={scrollEnabled}>
|
|
281
|
+
<View style={styles.container}>
|
|
282
|
+
<SignatureCanvas
|
|
283
|
+
ref={signatureRef}
|
|
284
|
+
style={styles.canvas}
|
|
285
|
+
onBegin={() => setScrollEnabled(false)}
|
|
286
|
+
onEnd={() => setScrollEnabled(true)}
|
|
287
|
+
/>
|
|
370
288
|
</View>
|
|
371
|
-
|
|
372
|
-
onOK={handleOK}
|
|
373
|
-
onEmpty={handleEmpty}
|
|
374
|
-
descriptionText="Sign"
|
|
375
|
-
clearText="Clear"
|
|
376
|
-
confirmText="Save"
|
|
377
|
-
webStyle={style}
|
|
378
|
-
/>
|
|
379
|
-
</View>
|
|
289
|
+
</ScrollView>
|
|
380
290
|
);
|
|
381
291
|
};
|
|
382
292
|
|
|
383
293
|
const styles = StyleSheet.create({
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
backgroundColor: "#F8F8F8",
|
|
388
|
-
justifyContent: "center",
|
|
389
|
-
alignItems: "center",
|
|
390
|
-
marginTop: 15,
|
|
294
|
+
container: {
|
|
295
|
+
flex: 1,
|
|
296
|
+
alignItems: 'center',
|
|
391
297
|
},
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
paddingLeft: 10,
|
|
398
|
-
paddingRight: 10,
|
|
399
|
-
backgroundColor: "#69B2FF",
|
|
400
|
-
width: 120,
|
|
401
|
-
textAlign: "center",
|
|
402
|
-
marginTop: 10,
|
|
298
|
+
canvas: {
|
|
299
|
+
width: '90%',
|
|
300
|
+
height: 300,
|
|
301
|
+
borderWidth: 1,
|
|
302
|
+
borderColor: '#000',
|
|
403
303
|
},
|
|
404
304
|
});
|
|
405
305
|
```
|
|
406
306
|
|
|
407
|
-
##
|
|
408
|
-
|
|
409
|
-
To use Typescript just import `SignatureViewRef` and in [useRef hook](https://reactjs.org/docs/hooks-reference.html#useref) inform that the reference is of the `SignatureViewRef` type, with that the regular `ref` methods will be available.
|
|
410
|
-
|
|
411
|
-
```ts
|
|
412
|
-
import React, { useRef } from "react";
|
|
413
|
-
import SignatureScreen, {
|
|
414
|
-
SignatureViewRef,
|
|
415
|
-
} from "react-native-signature-canvas";
|
|
416
|
-
|
|
417
|
-
interface Props {
|
|
418
|
-
text: string;
|
|
419
|
-
onOK: (signature) => void;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const Sign: React.FC<Props> = ({ text, onOK }) => {
|
|
423
|
-
const ref = useRef<SignatureViewRef>(null);
|
|
424
|
-
|
|
425
|
-
const handleSignature = (signature) => {
|
|
426
|
-
console.log(signature);
|
|
427
|
-
onOK(signature);
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
const handleEmpty = () => {
|
|
431
|
-
console.log("Empty");
|
|
432
|
-
};
|
|
433
|
-
|
|
434
|
-
const handleClear = () => {
|
|
435
|
-
console.log("clear success!");
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
const handleEnd = () => {
|
|
439
|
-
ref.current?.readSignature();
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
return (
|
|
443
|
-
<SignatureScreen
|
|
444
|
-
ref={ref}
|
|
445
|
-
onEnd={handleEnd}
|
|
446
|
-
onOK={handleSignature}
|
|
447
|
-
onEmpty={handleEmpty}
|
|
448
|
-
onClear={handleClear}
|
|
449
|
-
autoClear={true}
|
|
450
|
-
descriptionText={text}
|
|
451
|
-
/>
|
|
452
|
-
);
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
export default Sign;
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
## Example inside ScrollView
|
|
307
|
+
## Core Technology
|
|
459
308
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
309
|
+
This component is built on:
|
|
310
|
+
- [signature_pad.js](https://github.com/szimek/signature_pad) for the core signature functionality
|
|
311
|
+
- React Native WebView for cross-platform rendering
|
|
463
312
|
|
|
464
|
-
|
|
465
|
-
import React, {useState} from 'react';
|
|
466
|
-
import {ScrollView, View} from 'react-native';
|
|
467
|
-
import Signature from 'react-native-signature-canvas';
|
|
468
|
-
|
|
469
|
-
const SignInScroll = () => {
|
|
470
|
-
const [scrollEnabled, setScrollEnabled] = useState(true);
|
|
471
|
-
|
|
472
|
-
return (
|
|
473
|
-
<ScrollView scrollEnabled={scrollEnabled}>
|
|
474
|
-
<View style={{height: 300}}>
|
|
475
|
-
<Signature
|
|
476
|
-
onOK={(img) => console.log(img)}
|
|
477
|
-
onBegin={() => setScrollEnabled(false)}
|
|
478
|
-
onEnd={() => setScrollEnabled(true)}
|
|
479
|
-
descriptionText="Sign"
|
|
480
|
-
clearText="Clear"
|
|
481
|
-
confirmText="Save"
|
|
482
|
-
imageType="image/jpeg"
|
|
483
|
-
/>
|
|
484
|
-
</View>
|
|
485
|
-
</ScrollView>
|
|
486
|
-
);
|
|
487
|
-
};
|
|
313
|
+
## License
|
|
488
314
|
|
|
489
|
-
|
|
490
|
-
```
|
|
315
|
+
MIT
|
package/h5/js/app.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
declare module "react-native-signature-canvas" {
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {StyleProp, ViewStyle} from "react-native";
|
|
3
|
+
import { StyleProp, ViewStyle } from "react-native";
|
|
4
4
|
|
|
5
5
|
type ImageType = "image/png" | "image/jpeg" | "image/svg+xml";
|
|
6
6
|
|
|
7
7
|
type DataURL = "Base64" | string;
|
|
8
8
|
|
|
9
|
-
type ForwardRef<T, P> = React.ForwardRefExoticComponent<
|
|
9
|
+
type ForwardRef<T, P> = React.ForwardRefExoticComponent<
|
|
10
|
+
React.PropsWithoutRef<P> & React.RefAttributes<T>
|
|
11
|
+
>;
|
|
10
12
|
|
|
11
13
|
type SignatureViewProps = {
|
|
12
14
|
androidHardwareAccelerationDisabled?: boolean;
|
|
@@ -24,6 +26,9 @@ declare module "react-native-signature-canvas" {
|
|
|
24
26
|
imageType?: ImageType;
|
|
25
27
|
minWidth?: number;
|
|
26
28
|
maxWidth?: number;
|
|
29
|
+
minDistance?: number;
|
|
30
|
+
nestedScrollEnabled?: boolean;
|
|
31
|
+
showsVerticalScrollIndicator?: boolean;
|
|
27
32
|
onOK?: (signature: string) => void;
|
|
28
33
|
onEmpty?: () => void;
|
|
29
34
|
onClear?: () => void;
|
|
@@ -48,7 +53,7 @@ declare module "react-native-signature-canvas" {
|
|
|
48
53
|
webStyle?: string;
|
|
49
54
|
webviewContainerStyle?: StyleProp<ViewStyle>;
|
|
50
55
|
androidLayerType?: "none" | "software" | "hardware";
|
|
51
|
-
}
|
|
56
|
+
};
|
|
52
57
|
|
|
53
58
|
export type SignatureViewRef = {
|
|
54
59
|
changePenColor: (color: string) => void;
|
|
@@ -61,8 +66,8 @@ declare module "react-native-signature-canvas" {
|
|
|
61
66
|
readSignature: () => void;
|
|
62
67
|
undo: () => void;
|
|
63
68
|
redo: () => void;
|
|
64
|
-
}
|
|
69
|
+
};
|
|
65
70
|
|
|
66
|
-
const SignatureView: ForwardRef<SignatureViewRef, SignatureViewProps
|
|
71
|
+
const SignatureView: ForwardRef<SignatureViewRef, SignatureViewProps>;
|
|
67
72
|
export default SignatureView;
|
|
68
73
|
}
|
package/index.js
CHANGED
|
@@ -49,19 +49,22 @@ const SignatureView = forwardRef(
|
|
|
49
49
|
imageType = "",
|
|
50
50
|
minWidth = 0.5,
|
|
51
51
|
maxWidth = 2.5,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
minDistance = 5,
|
|
53
|
+
nestedScrollEnabled = false,
|
|
54
|
+
showsVerticalScrollIndicator = true,
|
|
55
|
+
onOK = () => { },
|
|
56
|
+
onEmpty = () => { },
|
|
57
|
+
onClear = () => { },
|
|
58
|
+
onUndo = () => { },
|
|
59
|
+
onRedo = () => { },
|
|
60
|
+
onDraw = () => { },
|
|
61
|
+
onErase = () => { },
|
|
62
|
+
onGetData = () => { },
|
|
63
|
+
onChangePenColor = () => { },
|
|
64
|
+
onChangePenSize = () => { },
|
|
65
|
+
onBegin = () => { },
|
|
66
|
+
onEnd = () => { },
|
|
67
|
+
onLoadEnd = () => { },
|
|
65
68
|
overlayHeight = 0,
|
|
66
69
|
overlayWidth = 0,
|
|
67
70
|
overlaySrc = null,
|
|
@@ -111,6 +114,10 @@ const SignatureView = forwardRef(
|
|
|
111
114
|
/<%maxWidth%>/g,
|
|
112
115
|
maxWidth
|
|
113
116
|
);
|
|
117
|
+
injectedJavaScript = injectedJavaScript.replace(
|
|
118
|
+
/<%minDistance%>/g,
|
|
119
|
+
minDistance
|
|
120
|
+
);
|
|
114
121
|
|
|
115
122
|
let html = htmlContentValue(injectedJavaScript);
|
|
116
123
|
html = html.replace(/<%bgWidth%>/g, bgWidth);
|
|
@@ -256,8 +263,8 @@ const SignatureView = forwardRef(
|
|
|
256
263
|
console.warn("WebView error: ", nativeEvent);
|
|
257
264
|
|
|
258
265
|
const handleLoadEnd = () => {
|
|
259
|
-
|
|
260
|
-
|
|
266
|
+
setLoading(false);
|
|
267
|
+
onLoadEnd();
|
|
261
268
|
}
|
|
262
269
|
|
|
263
270
|
return (
|
|
@@ -277,6 +284,8 @@ const SignatureView = forwardRef(
|
|
|
277
284
|
javaScriptEnabled={true}
|
|
278
285
|
onError={renderError}
|
|
279
286
|
onLoadEnd={handleLoadEnd}
|
|
287
|
+
nestedScrollEnabled={nestedScrollEnabled}
|
|
288
|
+
showsVerticalScrollIndicator={showsVerticalScrollIndicator}
|
|
280
289
|
/>
|
|
281
290
|
{loading && (
|
|
282
291
|
<View style={styles.loadingOverlayContainer}>
|