@dmsi/react-native-signature-pad-b64jpeg

React Native wrapper around szimek's Canvas based Signature Pad

Stats

stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
@dmsi/react-native-signature-pad-b64jpeg
Minified + gzip package size for @dmsi/react-native-signature-pad-b64jpeg in KB

Readme

react-native-signature-pad

React Native wrapper around @szimek's HTML5 Canvas based Signature Pad

  • Supports Android and iOS
  • Pure JavaScript implementation with no native dependencies
  • Tested with RN 0.55 & Expo SDK 28.0
  • Generates a base64 encoded image of the signature - default is png.

Demo

SignaturePadDemo SignaturePadDemoAndroid

Installation

yarn add @dmsi/react-native-signature-pad-b64jpeg
or
npm install @dmsi/react-native-signature-pad-b64jpeg

##Props #####b64DataType (optional) - string

  • Defaults to png if left blank, for JPG use "image/jpeg"

    b64DataType="image/jpeg"
    

    #####backgroundColor (optional) - string

  • Set the background of the webview - NOTE: this is not the canvas element

    backgroundColor='#fff'
    

    #####canvasDrawing (optional) - string

  • This string is browser javascript and will be called on load of the webview as well as when the page is cleared. This should be used to draw a guide line or any sort of drawing you want included in your signature.

    canvasDrawing={`
      var ctx = canvas.getContext('2d');
      ctx.fillStyle = '#fff';
      ctx.fillRect(0,0,canvas.width, canvas.height);
    
      /* draw a signature line */
      var ctx = canvas.getContext('2d');
      ctx.beginPath();
      ctx.strokeStyle= '#405a65';
      ctx.lineWidth = '2';
      var h = canvas.height / devicePixelRatio;
      var w = canvas.width / devicePixelRatio;
      /* you can also add a debug using postMessage and the 'log' action. 
      It is handled in the index.js and is sent up to your onMessage prop  */
      var payload = {
        action: 'log',
        value: {
          message: 'drawing line - debug',
          canvas_width: canvas.width,
          canvas_height: canvas.height,
          new_w: w,
          new_h: h,
          pixelRatio: devicePixelRatio,
        },
      };
      window.postMessage(JSON.stringify(payload));
    
      ctx.moveTo((w - (w* 0.95)), (h - (h * 0.1)));
      ctx.lineTo((w - (w * 0.05)), (h - (h * 0.1)));
      ctx.stroke();
    `}
    

    #####dataURL (optional) - string

  • Any data you want to send in to the canvas can be done here. Images etc will work as long as they are b64 images. Can be null. ```javascript

#####defaultHeight (optional) - number
* TODO
```javascript

#####defaultWidth (optional) - number

  • TODO ```javascript
#####onChange (optional) - function() => object
* on the end of every stroke returns a base64 image of the signature page. Here you can create a stroke counter, save off the data, etc. **It is recommended that you use this to save the data to the state in case your pad is erased (rotation)** 
```javascript
onChange={(data) => {
  this.props.strokeIncrement();
  this.setState({ b64Data: data.base64DataUrl });
}}

#####onError (optional) - function() => ({err, details})

  • Any error that happens natively in the webview is handled here.
    onError={({ err, details }) => Logger.error(err, `details: ${JSON.stringify(details)}`)}
    
    #####penColor (optional) - string
  • Default pen color is black. Can set any color here. #####penMaxWidth (optional) - number
    penMaxWidth={2}
    
    #####penMinWidth (optional) - number
    penMinWidth={0.5}
    
    #####pixelRatio (optional) - number
  • If you want to set a different pixelRatio then the device's, here is where you would do it. #####style styleSheet.create() required
  • NOTE: you must use a stylesheet.create() for this style. Causes issues with extra rendering if using regular objects here.
    ...
    const flexStyle = StyleSheet.create({
    pad: {
      flex: 1,
    },
    });
    ...
    // SigPad props
    style={flexStyle.pad}
    
    #####webViewBackgroundColor PropTypes.string,
  • Here is where you set your canvas background color. Can be transparent.
    webViewBackgroundColor="rgba(0, 0, 0, 0)"
    
    #####onLoad PropTypes.func,
  • This event happens after the webview is loaded and the javascript in the page executes. Should be used to save off inital signature pad state especially if you have a canvasDrawing. Anything not saved to the state will be removed on rotation of the page.
    onLoad={ async() => {
    const initPadWithDrawing = await this._pad.getBase64Data();
    this.setState({ b64Data: initPadWithDrawing });
    }}
    

Example

#####From original Fork

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';

import SignaturePad from 'react-native-signature-pad';

export default class Demo extends Component {
  render () {
    return (
      <View style={styles.flex1}>
        <SignaturePad 
          onError={this._signaturePadError}
          onChange={this._signaturePadChange}
          style={styles.pad}
        />
      </View>
    )
  }

  _signaturePadError = (error) => {
    console.error(error);
  }

  _signaturePadChange = ({ base64DataUrl }) => {
    console.log('Got new signature:', base64DataUrl);
  }
}

const styles = StyleSheet.create({
  flex1: { flex: 1 },
  pad: { flex: 1, backgroundColor: 'white' }
});

#####Current example

import React, { Component } from 'react';
import { View, StyleSheet, Alert } from 'react-native';

import SignaturePad from 'react-native-signature-pad';

// Adjust accordingly
var defaultWidth = 100;
var defaultHeight = 100;

export default class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      b64Data: null,
    }
  }
  render () {
    return (
      <View style={styles.flex1}>
        <SignaturePad 
          ref={(ref) => { this._pad = ref }}
          onError={this._signaturePadError}
          style={styles.pad}
          canvasDrawing={`
            var ctx = canvas.getContext('2d');
            ctx.fillStyle = '#fff';
            ctx.fillRect(0,0,canvas.width, canvas.height);

            /* draw a signature line */
            var ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.strokeStyle= '#405a65';
            ctx.lineWidth = '2';
            var h = canvas.height / devicePixelRatio;
            var w = canvas.width / devicePixelRatio;
            ctx.moveTo((w - (w* 0.95)), (h - (h * 0.1)));
            ctx.lineTo((w - (w * 0.05)), (h - (h * 0.1)));
            ctx.stroke();
          `}
          b64DataType="image/jpeg"
          onLoad={ async() => {
            const initPadWithDrawing = await this._pad.getBase64Data();
            this.setState({ b64Data: initPadWithDrawing });
          }}
        />
        <Button
          onPress={this._getSig}
          title='Get sig'
        />
      </View>
    )
  }

  drawSig() {
    if (this.state.b64Data !== null) {
      this._pad.drawBase64ImageToBackground(this.state.b64Data);
    }
  }

  _signaturePadError = (error) => {
    console.error(error);
  }

  _getSig = async () => {
    if (!this._pad) return;

    try {
      const isEmpty = await this._pad.isEmpty()
      if (isEmpty) {
        Alert.alert('Signature is empty!')
        return
      }
    } catch (err) {
      console.error(err)
      return
    }

    let base64DataUrl
    try {
      base64DataUrl = await this._pad.getBase64Data()
    } catch (err) {
      console.error(err)
      return
    }

    console.log('Got new signature:', base64DataUrl);
  }
}

const styles = StyleSheet.create({
  flex1: { flex: 1 },
  pad: { width: 600, height: 300, backgroundColor: '#eee' }
});

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.