当前位置: 首页 > 工具软件 > react-canvas > 使用案例 >

react-signature-canvas 实现 移动端电子签名功能

呼延曜灿
2023-12-01

1、使用 react-signature-canvas 插件,npm i react-signature-canvas --save

2、此功能签名后生成的图片是base64格式,如需其他格式,可参考文档修改

3、封装的组件代码

import { SignatureCanvasWrapper } from './style';
import React, {
  useState,
  useRef,
  useImperativeHandle,
  forwardRef,
  useEffect,
} from 'react';
import SignatureCanvas from 'react-signature-canvas';
import { useSize } from 'ahooks';

interface IProps {
  width?: string;
  height?: string;
  imageWidth?: number; // 签名图片的宽高
  imageHeight?: number;  
  rotated?: boolean;  // 移动端横屏签名
  signMess?: string;
  renderContent: (e?) => void; // 生成的图片
}
// 签名 组件
function SignatureCanvasComponent(props: IProps, ref) {
  const {
    renderContent,
    width,
    signMess,
    imageWidth,
    imageHeight,
    rotated,
    height,
  } = props;

  const [signTip, setSignTip] = useState(signMess || '请在此区域签署本人姓名');
  const sigCanvasRef = useRef<SignatureCanvas | null>(null);
  const canvasContainer = useRef<HTMLDivElement>(null);
  const size = useSize(canvasContainer);

  useImperativeHandle(ref, () => ({
    clearSign,
  }));

  // 重签
  const clearSign = () => {
    sigCanvasRef.current.clear();
  };

  useEffect(() => {
    if (rotated && size?.height) {
      var canvas = document.querySelector('#sigCanvas') as HTMLCanvasElement;
      if (canvas) {
        var ctx = canvas.getContext('2d');
        if (ctx) {
          ctx.rotate(1.5 * Math.PI);
          ctx.translate(-canvas!.height, 0);
        }
      }
    }
  }, [rotated, size]);

  return (
    <SignatureCanvasWrapper ref={canvasContainer}>
      <SignatureCanvas
        penColor="#000"  // 笔刷颜色
        minWidth={3}  、、 笔刷粗细
        maxWidth={5}
        canvasProps={{
          id: 'sigCanvas',
          width: size.width,
          height: size.height,  // 画布尺寸
          className: 'LegalRisk-signature',
        }}  
        ref={sigCanvasRef}
        onBegin={() => setSignTip('')}
        onEnd={() => {
          // 图片
          const trimedCanvas: HTMLCanvasElement = sigCanvasRef.current.getTrimmedCanvas();
          if (trimedCanvas) {
            var resizedCanvas = document.createElement('canvas');
            var resizedContext = resizedCanvas.getContext('2d');

            resizedCanvas.height = imageHeight || 50;  // 传给后台的图片尺寸
            resizedCanvas.width = imageWidth || 100;

            resizedContext?.drawImage(
              trimedCanvas,
              0,
              0,
              imageWidth || 100,
              imageHeight || 50,
            );
            var myResizedData = resizedCanvas.toDataURL();
            console.log('签名图片:', myResizedData);
            renderContent(myResizedData);
          }
        }}
      />

      {signTip && <div className="SignatureTips">{signTip}</div>}
    </SignatureCanvasWrapper>
  );
}

export default forwardRef(SignatureCanvasComponent);

4.在使用的页面:

   <SignatureCanvasComponent
       ref={childRef}
       renderContent={e => {
       // 暂存
       setSign(e);
      }}
  ></SignatureCanvasComponent>
  1. 相关样式

import styled from 'styled-components/macro';
export const mainColor = '#286bff';

export const SignatureCanvasWrapper = styled.div`
  width: 100%;
  position: relative;
  .LegalRisk-signature {
    width: 100%;
    border-radius: 10px;
    background: #f5f7fe;
    border: 2px dashed ${mainColor};
  }
  .SignatureTips {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    color: #a2a0a8;
    font-weight: regular;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
  }
`;
 类似资料: