react-native-signature-canvas 4.7.2 → 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 -382
- package/h5/js/app.js +1 -0
- package/index.d.ts +8 -5
- package/index.js +21 -16
- package/package.json +1 -1
- package/tea.yaml +0 -6
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,142 +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
|
-
| nestedScrollEnabled | `boolean` | enable nested scrolling for use inside of a scrollview |
|
|
71
|
-
| showsVerticalScrollIndicator | `boolean` | Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`, The default value is `true`. |
|
|
72
|
-
| onOK | `function` | callback function after saving non-empty signature |
|
|
73
|
-
| onEmpty | `function` | callback function after trying to save an empty signature |
|
|
74
|
-
| onClear | `function` | callback function after clearing the signature |
|
|
75
|
-
| onGetData | `function` | callback function when getData() is called
|
|
76
|
-
| onBegin | `function` | callback function when a new stroke is started |
|
|
77
|
-
| onEnd | `function` | callback function when the stroke has ended |
|
|
78
|
-
| onLoadEnd | `function` | callback function when the webview canvas load ended |
|
|
79
|
-
| onUndo | `function` | callback function when undo() is called |
|
|
80
|
-
| onRedo | `function` | callback function when redo() is called |
|
|
81
|
-
| onDraw | `function` | callback function when drawing is enabled |
|
|
82
|
-
| onErase | `function` | callback function when erasing is enabled |
|
|
83
|
-
| onChangePenColor | `function` | callback function after changing the pen color |
|
|
84
|
-
| onChangePenSize | `function` | callback function after changing the pen size
|
|
85
|
-
| overlayHeight | `number` | height of the overlay image |
|
|
86
|
-
| overlayWidth | `number` | width of the overlay image |
|
|
87
|
-
| overlaySrc | `string` | overlay image source uri (url) _must be .png with a transparent background_
|
|
88
|
-
| penColor | `string` | default is "black", color of pen |
|
|
89
|
-
| rotated | `boolean` | rotate signature pad 90 degrees |
|
|
90
|
-
| style | `object` | style of wrapper view |
|
|
91
|
-
| trimWhitespace | `boolean` | trim image whitespace |
|
|
92
|
-
| 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 |
|
|
93
|
-
| androidLayerType | `none、software、hardware` | Sets the android webview layerType |
|
|
94
|
-
|
|
95
|
-
## Methods
|
|
96
|
-
|
|
97
|
-
---
|
|
49
|
+
## Basic Usage
|
|
98
50
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
| changePenSize(minW, maxW) | Change pen size |
|
|
104
|
-
| draw() | Enable drawing signature |
|
|
105
|
-
| erase() | Enable erasing signature |
|
|
106
|
-
| getData() | Triggers the `onGetData` callback with a single `data` JSON string |
|
|
107
|
-
| readSignature() | Reads the current signature on the canvas and triggers either the `onOK` or `onEmpty` callbacks |
|
|
108
|
-
| undo() | Undo last stroke |
|
|
109
|
-
| 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';
|
|
110
55
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```js
|
|
114
|
-
import SignatureScreen from "react-native-signature-canvas";
|
|
115
|
-
|
|
116
|
-
const Sign = ({ text, onOK }) => {
|
|
56
|
+
const SignatureScreen = () => {
|
|
57
|
+
const [signature, setSignature] = useState(null);
|
|
117
58
|
const ref = useRef();
|
|
118
59
|
|
|
119
|
-
|
|
120
|
-
const handleOK = (signature) => {
|
|
60
|
+
const handleSignature = (signature) => {
|
|
121
61
|
console.log(signature);
|
|
122
|
-
|
|
62
|
+
setSignature(signature);
|
|
123
63
|
};
|
|
124
64
|
|
|
125
|
-
// Called after ref.current.readSignature() reads an empty string
|
|
126
65
|
const handleEmpty = () => {
|
|
127
|
-
console.log(
|
|
66
|
+
console.log('Empty');
|
|
128
67
|
};
|
|
129
68
|
|
|
130
|
-
// Called after ref.current.clearSignature()
|
|
131
69
|
const handleClear = () => {
|
|
132
|
-
console.log(
|
|
70
|
+
console.log('Clear success!');
|
|
133
71
|
};
|
|
134
72
|
|
|
135
|
-
// Called after end of stroke
|
|
136
73
|
const handleEnd = () => {
|
|
137
74
|
ref.current.readSignature();
|
|
138
75
|
};
|
|
139
76
|
|
|
140
|
-
// Called after ref.current.getData()
|
|
141
|
-
const handleData = (data) => {
|
|
142
|
-
console.log(data);
|
|
143
|
-
};
|
|
144
|
-
|
|
145
77
|
return (
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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>
|
|
156
100
|
);
|
|
157
101
|
};
|
|
158
102
|
|
|
159
|
-
|
|
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;
|
|
160
118
|
```
|
|
161
|
-
## Using a background image
|
|
162
|
-
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.
|
|
163
119
|
|
|
164
|
-
|
|
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
|
|
165
187
|
const imgWidth = 300;
|
|
166
188
|
const imgHeight = 200;
|
|
167
189
|
const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
@@ -169,24 +191,22 @@ const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
|
169
191
|
.m-signature-pad--footer {display: none; margin: 0px;}
|
|
170
192
|
body,html {
|
|
171
193
|
width: ${imgWidth}px; height: ${imgHeight}px;}`;
|
|
172
|
-
|
|
194
|
+
|
|
173
195
|
<View style={{ width: imgWidth, height: imgHeight }}>
|
|
174
|
-
<
|
|
196
|
+
<SignatureCanvas
|
|
175
197
|
ref={ref}
|
|
176
|
-
bgSrc="https://
|
|
198
|
+
bgSrc="https://example.com/background.jpg"
|
|
177
199
|
bgWidth={imgWidth}
|
|
178
200
|
bgHeight={imgHeight}
|
|
179
201
|
webStyle={style}
|
|
180
|
-
onOK={
|
|
202
|
+
onOK={handleSignature}
|
|
181
203
|
/>
|
|
182
204
|
</View>
|
|
183
205
|
```
|
|
184
206
|
|
|
185
|
-
|
|
186
|
-
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.
|
|
187
|
-
Use the `overlaySrc` prop to provide the link.
|
|
207
|
+
### Using an Overlay Image
|
|
188
208
|
|
|
189
|
-
```
|
|
209
|
+
```jsx
|
|
190
210
|
const imgWidth = 256;
|
|
191
211
|
const imgHeight = 256;
|
|
192
212
|
const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
@@ -194,299 +214,102 @@ const style = `.m-signature-pad {box-shadow: none; border: none; }
|
|
|
194
214
|
.m-signature-pad--footer {display: none; margin: 0px;}
|
|
195
215
|
body,html {
|
|
196
216
|
width: ${imgWidth}px; height: ${imgHeight}px;}`;
|
|
197
|
-
|
|
217
|
+
|
|
198
218
|
<View style={{ width: imgWidth, height: imgHeight }}>
|
|
199
|
-
<
|
|
219
|
+
<SignatureCanvas
|
|
200
220
|
ref={ref}
|
|
201
|
-
overlaySrc="
|
|
221
|
+
overlaySrc="https://example.com/overlay.png" // Must be PNG with transparent background
|
|
202
222
|
overlayWidth={imgWidth}
|
|
203
223
|
overlayHeight={imgHeight}
|
|
204
224
|
webStyle={style}
|
|
205
|
-
onOK={
|
|
225
|
+
onOK={handleSignature}
|
|
206
226
|
/>
|
|
207
227
|
</View>
|
|
208
228
|
```
|
|
209
229
|
|
|
210
|
-
|
|
230
|
+
### Using in a Modal
|
|
211
231
|
|
|
212
|
-
|
|
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';
|
|
213
236
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const handleOK = (signature) => {
|
|
218
|
-
const path = FileSystem.cacheDirectory + "sign.png";
|
|
219
|
-
FileSystem.writeAsStringAsync(
|
|
220
|
-
path,
|
|
221
|
-
signature.replace("data:image/png;base64,", ""),
|
|
222
|
-
{ encoding: FileSystem.EncodingType.Base64 }
|
|
223
|
-
)
|
|
224
|
-
.then(() => FileSystem.getInfoAsync(path))
|
|
225
|
-
.then(console.log)
|
|
226
|
-
.catch(console.error);
|
|
227
|
-
};
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Basic parameters
|
|
231
|
-
|
|
232
|
-
```js
|
|
233
|
-
<Signature
|
|
234
|
-
// handle when you click save button
|
|
235
|
-
onOK={(img) => console.log(img)}
|
|
236
|
-
onEmpty={() => console.log("empty")}
|
|
237
|
-
// description text for signature
|
|
238
|
-
descriptionText="Sign"
|
|
239
|
-
// clear button text
|
|
240
|
-
clearText="Clear"
|
|
241
|
-
// save button text
|
|
242
|
-
confirmText="Save"
|
|
243
|
-
// String, webview style for overwrite default style, all style: https://github.com/YanYuanFE/react-native-signature-canvas/blob/master/h5/css/signature-pad.css
|
|
244
|
-
webStyle={`.m-signature-pad--footer
|
|
245
|
-
.button {
|
|
246
|
-
background-color: red;
|
|
247
|
-
color: #FFF;
|
|
248
|
-
}`}
|
|
249
|
-
autoClear={true}
|
|
250
|
-
imageType={"image/svg+xml"}
|
|
251
|
-
/>
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
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.
|
|
255
|
-
|
|
256
|
-
```js
|
|
257
|
-
const webStyle = `.m-signature-pad--footer
|
|
258
|
-
.save {
|
|
259
|
-
display: none;
|
|
260
|
-
}
|
|
261
|
-
.clear {
|
|
262
|
-
display: none;
|
|
263
|
-
}
|
|
264
|
-
`;
|
|
265
|
-
...
|
|
266
|
-
<Signature
|
|
267
|
-
webStyle={webStyle}
|
|
268
|
-
onOK={handleOK}
|
|
269
|
-
onEmpty={handleEmpty}
|
|
270
|
-
onEnd={handleEnd}
|
|
271
|
-
/>
|
|
272
|
-
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Custom Button for Confirm and Clear
|
|
276
|
-
|
|
277
|
-
```js
|
|
278
|
-
import React, { useRef } from "react";
|
|
279
|
-
import { StyleSheet, View, Button } from "react-native";
|
|
280
|
-
import SignatureScreen from "react-native-signature-canvas";
|
|
281
|
-
|
|
282
|
-
const Sign = ({ onOK }) => {
|
|
237
|
+
const SignatureModal = ({ onSignature }) => {
|
|
238
|
+
const [show, setShow] = useState(false);
|
|
283
239
|
const ref = useRef();
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const handleClear = () => {
|
|
291
|
-
ref.current.clearSignature();
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const handleConfirm = () => {
|
|
295
|
-
console.log("end");
|
|
296
|
-
ref.current.readSignature();
|
|
240
|
+
|
|
241
|
+
const handleSignature = (signature) => {
|
|
242
|
+
onSignature(signature);
|
|
243
|
+
setShow(false);
|
|
297
244
|
};
|
|
298
245
|
|
|
299
|
-
const style = `.m-signature-pad--footer {display: none; margin: 0px;}`;
|
|
300
|
-
|
|
301
246
|
return (
|
|
302
|
-
<View
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
+
)}
|
|
308
263
|
</View>
|
|
309
264
|
);
|
|
310
265
|
};
|
|
311
|
-
|
|
312
|
-
export default Sign;
|
|
313
|
-
|
|
314
|
-
const styles = StyleSheet.create({
|
|
315
|
-
container: {
|
|
316
|
-
flex: 1,
|
|
317
|
-
alignItems: "center",
|
|
318
|
-
justifyContent: "center",
|
|
319
|
-
height: 250,
|
|
320
|
-
padding: 10,
|
|
321
|
-
},
|
|
322
|
-
row: {
|
|
323
|
-
display: "flex",
|
|
324
|
-
flexDirection: "row",
|
|
325
|
-
justifyContent: "space-between",
|
|
326
|
-
width: "100%",
|
|
327
|
-
alignItems: "center",
|
|
328
|
-
},
|
|
329
|
-
});
|
|
330
266
|
```
|
|
331
267
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
- Android <br/>
|
|
335
|
-
<img src="http://img.yanyuanfe.cn/signature-android.png" width="400" />
|
|
336
|
-
|
|
337
|
-
- iOS <br/>
|
|
338
|
-
<img src="http://img.yanyuanfe.cn/signature-ios.png" width="400" />
|
|
268
|
+
### Scrollable Signature Canvas
|
|
339
269
|
|
|
340
|
-
```
|
|
341
|
-
import React, { useState } from
|
|
342
|
-
import {
|
|
343
|
-
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';
|
|
344
274
|
|
|
345
|
-
|
|
346
|
-
const [
|
|
347
|
-
|
|
348
|
-
const handleOK = (signature) => {
|
|
349
|
-
console.log(signature);
|
|
350
|
-
setSign(signature);
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
const handleEmpty = () => {
|
|
354
|
-
console.log("Empty");
|
|
355
|
-
};
|
|
275
|
+
const ScrollableSignature = () => {
|
|
276
|
+
const [scrollEnabled, setScrollEnabled] = useState(true);
|
|
277
|
+
const signatureRef = useRef(null);
|
|
356
278
|
|
|
357
|
-
const style = `.m-signature-pad--footer
|
|
358
|
-
.button {
|
|
359
|
-
background-color: red;
|
|
360
|
-
color: #FFF;
|
|
361
|
-
}`;
|
|
362
279
|
return (
|
|
363
|
-
<
|
|
364
|
-
<View style={styles.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
) : 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
|
+
/>
|
|
372
288
|
</View>
|
|
373
|
-
|
|
374
|
-
onOK={handleOK}
|
|
375
|
-
onEmpty={handleEmpty}
|
|
376
|
-
descriptionText="Sign"
|
|
377
|
-
clearText="Clear"
|
|
378
|
-
confirmText="Save"
|
|
379
|
-
webStyle={style}
|
|
380
|
-
/>
|
|
381
|
-
</View>
|
|
289
|
+
</ScrollView>
|
|
382
290
|
);
|
|
383
291
|
};
|
|
384
292
|
|
|
385
293
|
const styles = StyleSheet.create({
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
backgroundColor: "#F8F8F8",
|
|
390
|
-
justifyContent: "center",
|
|
391
|
-
alignItems: "center",
|
|
392
|
-
marginTop: 15,
|
|
294
|
+
container: {
|
|
295
|
+
flex: 1,
|
|
296
|
+
alignItems: 'center',
|
|
393
297
|
},
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
paddingLeft: 10,
|
|
400
|
-
paddingRight: 10,
|
|
401
|
-
backgroundColor: "#69B2FF",
|
|
402
|
-
width: 120,
|
|
403
|
-
textAlign: "center",
|
|
404
|
-
marginTop: 10,
|
|
298
|
+
canvas: {
|
|
299
|
+
width: '90%',
|
|
300
|
+
height: 300,
|
|
301
|
+
borderWidth: 1,
|
|
302
|
+
borderColor: '#000',
|
|
405
303
|
},
|
|
406
304
|
});
|
|
407
305
|
```
|
|
408
306
|
|
|
409
|
-
##
|
|
410
|
-
|
|
411
|
-
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.
|
|
412
|
-
|
|
413
|
-
```ts
|
|
414
|
-
import React, { useRef } from "react";
|
|
415
|
-
import SignatureScreen, {
|
|
416
|
-
SignatureViewRef,
|
|
417
|
-
} from "react-native-signature-canvas";
|
|
418
|
-
|
|
419
|
-
interface Props {
|
|
420
|
-
text: string;
|
|
421
|
-
onOK: (signature) => void;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
const Sign: React.FC<Props> = ({ text, onOK }) => {
|
|
425
|
-
const ref = useRef<SignatureViewRef>(null);
|
|
426
|
-
|
|
427
|
-
const handleSignature = (signature) => {
|
|
428
|
-
console.log(signature);
|
|
429
|
-
onOK(signature);
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const handleEmpty = () => {
|
|
433
|
-
console.log("Empty");
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
const handleClear = () => {
|
|
437
|
-
console.log("clear success!");
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
const handleEnd = () => {
|
|
441
|
-
ref.current?.readSignature();
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
return (
|
|
445
|
-
<SignatureScreen
|
|
446
|
-
ref={ref}
|
|
447
|
-
onEnd={handleEnd}
|
|
448
|
-
onOK={handleSignature}
|
|
449
|
-
onEmpty={handleEmpty}
|
|
450
|
-
onClear={handleClear}
|
|
451
|
-
autoClear={true}
|
|
452
|
-
descriptionText={text}
|
|
453
|
-
/>
|
|
454
|
-
);
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
export default Sign;
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
## Example inside ScrollView
|
|
307
|
+
## Core Technology
|
|
461
308
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
|
465
312
|
|
|
466
|
-
|
|
467
|
-
import React, {useState} from 'react';
|
|
468
|
-
import {ScrollView, View} from 'react-native';
|
|
469
|
-
import Signature from 'react-native-signature-canvas';
|
|
470
|
-
|
|
471
|
-
const SignInScroll = () => {
|
|
472
|
-
const [scrollEnabled, setScrollEnabled] = useState(true);
|
|
473
|
-
|
|
474
|
-
return (
|
|
475
|
-
<ScrollView scrollEnabled={scrollEnabled}>
|
|
476
|
-
<View style={{height: 300}}>
|
|
477
|
-
<Signature
|
|
478
|
-
onOK={(img) => console.log(img)}
|
|
479
|
-
onBegin={() => setScrollEnabled(false)}
|
|
480
|
-
onEnd={() => setScrollEnabled(true)}
|
|
481
|
-
descriptionText="Sign"
|
|
482
|
-
clearText="Clear"
|
|
483
|
-
confirmText="Save"
|
|
484
|
-
imageType="image/jpeg"
|
|
485
|
-
/>
|
|
486
|
-
</View>
|
|
487
|
-
</ScrollView>
|
|
488
|
-
);
|
|
489
|
-
};
|
|
313
|
+
## License
|
|
490
314
|
|
|
491
|
-
|
|
492
|
-
```
|
|
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,7 @@ declare module "react-native-signature-canvas" {
|
|
|
24
26
|
imageType?: ImageType;
|
|
25
27
|
minWidth?: number;
|
|
26
28
|
maxWidth?: number;
|
|
29
|
+
minDistance?: number;
|
|
27
30
|
nestedScrollEnabled?: boolean;
|
|
28
31
|
showsVerticalScrollIndicator?: boolean;
|
|
29
32
|
onOK?: (signature: string) => void;
|
|
@@ -50,7 +53,7 @@ declare module "react-native-signature-canvas" {
|
|
|
50
53
|
webStyle?: string;
|
|
51
54
|
webviewContainerStyle?: StyleProp<ViewStyle>;
|
|
52
55
|
androidLayerType?: "none" | "software" | "hardware";
|
|
53
|
-
}
|
|
56
|
+
};
|
|
54
57
|
|
|
55
58
|
export type SignatureViewRef = {
|
|
56
59
|
changePenColor: (color: string) => void;
|
|
@@ -63,8 +66,8 @@ declare module "react-native-signature-canvas" {
|
|
|
63
66
|
readSignature: () => void;
|
|
64
67
|
undo: () => void;
|
|
65
68
|
redo: () => void;
|
|
66
|
-
}
|
|
69
|
+
};
|
|
67
70
|
|
|
68
|
-
const SignatureView: ForwardRef<SignatureViewRef, SignatureViewProps
|
|
71
|
+
const SignatureView: ForwardRef<SignatureViewRef, SignatureViewProps>;
|
|
69
72
|
export default SignatureView;
|
|
70
73
|
}
|
package/index.js
CHANGED
|
@@ -49,21 +49,22 @@ const SignatureView = forwardRef(
|
|
|
49
49
|
imageType = "",
|
|
50
50
|
minWidth = 0.5,
|
|
51
51
|
maxWidth = 2.5,
|
|
52
|
+
minDistance = 5,
|
|
52
53
|
nestedScrollEnabled = false,
|
|
53
|
-
showsVerticalScrollIndicator= true,
|
|
54
|
-
onOK = () => {},
|
|
55
|
-
onEmpty = () => {},
|
|
56
|
-
onClear = () => {},
|
|
57
|
-
onUndo = () => {},
|
|
58
|
-
onRedo = () => {},
|
|
59
|
-
onDraw = () => {},
|
|
60
|
-
onErase = () => {},
|
|
61
|
-
onGetData = () => {},
|
|
62
|
-
onChangePenColor = () => {},
|
|
63
|
-
onChangePenSize = () => {},
|
|
64
|
-
onBegin = () => {},
|
|
65
|
-
onEnd = () => {},
|
|
66
|
-
onLoadEnd = () => {},
|
|
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 = () => { },
|
|
67
68
|
overlayHeight = 0,
|
|
68
69
|
overlayWidth = 0,
|
|
69
70
|
overlaySrc = null,
|
|
@@ -113,6 +114,10 @@ const SignatureView = forwardRef(
|
|
|
113
114
|
/<%maxWidth%>/g,
|
|
114
115
|
maxWidth
|
|
115
116
|
);
|
|
117
|
+
injectedJavaScript = injectedJavaScript.replace(
|
|
118
|
+
/<%minDistance%>/g,
|
|
119
|
+
minDistance
|
|
120
|
+
);
|
|
116
121
|
|
|
117
122
|
let html = htmlContentValue(injectedJavaScript);
|
|
118
123
|
html = html.replace(/<%bgWidth%>/g, bgWidth);
|
|
@@ -258,8 +263,8 @@ const SignatureView = forwardRef(
|
|
|
258
263
|
console.warn("WebView error: ", nativeEvent);
|
|
259
264
|
|
|
260
265
|
const handleLoadEnd = () => {
|
|
261
|
-
|
|
262
|
-
|
|
266
|
+
setLoading(false);
|
|
267
|
+
onLoadEnd();
|
|
263
268
|
}
|
|
264
269
|
|
|
265
270
|
return (
|
package/package.json
CHANGED