React 前端导航

React 实现 H5 签名签字(signature)

React 实现 H5 签名签字(signature)

基本功能

签字,切换颜色 ,可清空,可提交图片。

接入参考

1.依赖安装,这里用到了开源库《signature_pad》文档地址


npm i signature_pad 

2.引入对应的npm包


import SignaturePad from 'signature_pad';

3.挂载相应的canvas dom和SignaturePad实例这里前端用到的技术栈是 react,函数式组件


<canvas ref={canvasRef}>
     暂不支持手绘功能。
</canvas>

import React, { useRef, useEffect, useState } from 'react';
  const canvasRef = useRef<HTMLCanvasElement>(null); // canvas dom
  const signaturePadRef = useRef<SignaturePad>(); // signature_pad实例
  const [penColor, setPenColor] = useState(blackPenColor);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (canvas) {
      canvas.width = canvas.getBoundingClientRect().width; // 让画布自适应
      canvas.height = canvas.getBoundingClientRect().height;
      signaturePadRef.current = new SignaturePad(canvas, {
        // backgroundColor: '#fff', // 签字区域背景色 Defaults to "rgba(0,0,0,0)"
        minWidth: 1, // 签字线最小宽度 Defaults to 0.5
        maxWidth: 4, // 签字线最大宽度 Defaults to 2.5
        penColor, // 签字线颜色 Defaults to "black"
      });
    }
  }, []);

4.到这里签字区域应该展示出来了。额外的需求去参考文档api即可

签字图片提交的提交方式

1.base64


signaturePadRef?.current?.toDataURL() // 返回签字图片的base64地址

不过因为base64比较大,直接保存比较占内存,这里会用到一些优化处理。把base64做文件上传然后后端返回cdn链接即可。


 const convertBase64UrlToBlob = (urlData: any, callback: any) => {
    // 将base64转化为文件格式
    const arr = urlData.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]); // atob方法用于解码base64
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new Promise((resolve) => {
      resolve(
        callback(
          new Blob([u8arr], {
            type: mime,
          }),
        ),
      );
    });
  };

convertBase64UrlToBlob(res, (res1) => {
          const compresFile = new File([res1], 'sign.png', {
            type: 'image/png',
          });

          const formData = new FormData();
          formData.append('file', compresFile);
          // 这里调用上传文件服务,上传binary
          uploadFile(formData).then((res2: any) => {
            if (res2?.datasuccess) {
              // 成功后续逻辑。。

            }
        
          }).catch(
            (err2)  => {
            // 异常捕获下
            }
            
          );
        });

保存图片支持格式:


signaturePad.toDataURL(); // save image as PNG 
signaturePad.toDataURL("image/jpeg"); // save image as JPEG 
signaturePad.toDataURL("image/jpeg", 0.5); // save image as JPEG with 0.5 image quality 
signaturePad.toDataURL("image/svg+xml"); // save image as SVG

2.canvas坐标数组


// Returns signature image as an array of point groups
const data = signaturePad.toData();

回显,base64,坐标数组都能回显


// Draws signature image from an array of point groups
signaturePad.fromData(data);

// Draws signature image from an array of point groups, without clearing your existing image (clear defaults to true if not provided)
signaturePad.fromData(data, { clear: false });

其他问题,可参考官方文档issues,比如画布自适应问题


function resizeCanvas() {
    const ratio =  Math.max(window.devicePixelRatio || 1, 1);
    canvas.width = canvas.offsetWidth * ratio;
    canvas.height = canvas.offsetHeight * ratio;
    canvas.getContext("2d").scale(ratio, ratio);
    signaturePad.clear(); // otherwise isEmpty() might return incorrect value
}

window.addEventListener("resize", resizeCanvas);
resizeCanvas();

效果图

React 手签

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/59
想做或者在做副业的朋友欢迎加微信交流:farmerlzj,公众号:生财空间站。

#react#手写签名

相关推荐

react中实现markdown文件读取展示

react中实现markdown文件读取展示

umi实践问题汇总--持续更新

在使用umi的过程中所遇到问题的记录汇总