移动端手写签字画板——基于react-canvas-draw

公司最近的一个需求,需要在h5移动端实现上上签的电子签署的功能;
要求不依赖JQ,只能依赖react(因为h5项目使用react写的)
于是历经千辛万苦找到了一个相对适用的包react-canvas-draw
但是实际开发业务过程还是有很多不适用的地方需要调试

  • 使用方法

    1、安装
    npm install react-canvas-draw --saveoryarn add react-canvas-draw
    2、调用

    import React from "react";
    import ReactDOM from "react-dom";
    import CanvasDraw from "react-canvas-draw";
    
    ReactDOM.render(<CanvasDraw ref={canvasDraw => (store.saveableCanvas = canvasDraw)}/>,       document.getElementById("root"));
    

    3、内部方法 参数

    static defaultProps = {
     loadTimeOffset: 5,
     lazyRadius: 30,
     brushRadius: 12,
     brushColor: "#444",
     catenaryColor: "#0a0302",
     gridColor: "rgba(150,150,150,0.17)",
     hideGrid: false,
     canvasWidth: 400,
     canvasHeight: 400,
     disabled: false,
     imgSrc: "",
     saveData: null,
     immediateLoading: false
    }
    

    getSaveData():返回所画的图形的canvas编码
    loadSaveData(saveData: String, immediate: Boolean):加载savaData对应的图形
    clear():清空画布
    undo():撤销上一次操作
    4、生成结构分析

      <div class="canvasBox">
         <div style="display: block; background: rgb(255, 255, 255); touch-action: none; width: 375px; height: 667px;">
           <canvas style="display: block; position: absolute; z-index: 15;" width="375" height="667"></canvas>                                                  
           <canvas style="display: block; position: absolute; z-index: 11;" width="375" height="667"></canvas>
           <canvas style="display: block; position: absolute; z-index: 12;" width="375" height="667"></canvas>
           <canvas style="display: block; position: absolute; z-index: 10;" width="375" height="667"></canvas>
         </div>
       </div>
    

    react-canvas-draw会在代码里生成四个canvas,从上到下依次对应笔头、画布、轨迹、模版,具体功能自行选中元素尝试删除后操作画布。

  • 将签字转换成图片

    最终图片实际是画在第二个canvas上,也就是grid,如果需要转换成图片,将这个canvas进行转换即可

      let pic = store.saveableCanvas.canvas.grid.toDataURL('image/png');
    
  • 移动端进行手写签名时,会导致屏幕滚动

    需要监听在进入这个签名页的时候,将屏幕禁止滚动;退出页面后,把禁止打开

      // 进入页面后禁止滚动
      document.addEventListener('touchmove', store.preventDefault, {passive: false});
      // 退出后恢复滚动
       window.addEventListener('popstate', (e) => {
          // 恢复触摸滚动页面
          document.removeEventListener('touchmove', store.preventDefault, {passive: false});
       }, false);
    
      //store
      @action preventDefault = (e) => {
          e.preventDefault();
      };
    
  • 屏幕翻转,将react-canvas-draw画布横过来

    屏幕大小改变的时候,屏幕宽高发生改变,但是react-canvas-draw画布的大小不会跟着改变。解决方法是监听屏幕大小改变,对画布进行相应的调整。这里有一个坑,在苹果手机上的一些浏览器不能改变画布大小,所以采用了一些兼容写法

      window.addEventListener('resize', this.windowChangeEvent, {passive: false});
      windowChangeEvent = () => {
          store.canvasWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
          store.canvasHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
          let bowser = this.getExploreName();
          // 把对应生成的四个canvas的大小都进行修改
          for(var key in store.saveableCanvas.canvas) {
              store.saveableCanvas.canvas[key].width = store.canvasWidth;
              store.saveableCanvas.canvas[key].height = store.canvasHeight;
          }
          // 兼容苹果手机上的非原生浏览器
          if(window.orientation===90||window.orientation===-90){
              // 横屏
              if (store.canvasWidth <= store.canvasHeight || bowser === 'Unkonwn') {
                      store.canvasWidth = window.screen.height;
                      store.canvasHeight = window.screen.width;
              }
          }else{
              // 竖屏
              if (store.canvasWidth >= store.canvasHeight || bowser === 'Unkonwn') {
                      store.canvasWidth = window.screen.width;
                      store.canvasHeight = window.screen.height;
              }
          }
      }
      getExploreName = () => {
          var Sys = {};  
          var ua = navigator.userAgent.toLowerCase();  
          var s;  
          (s = ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1] : (s = ua.match(/msie ([\d\.]+)/)) ? Sys.ie = s[1] : (s = ua.match(/edge\/([\d\.]+)/)) ? Sys.edge = s[1] : (s = ua.match(/firefox\/([\d\.]+)/)) ? Sys.firefox = s[1] : (s = ua.match(/(?:opera|opr).([\d\.]+)/)) ? Sys.opera = s[1] : (s = ua.match(/chrome\/([\d\.]+)/)) ? Sys.chrome = s[1] : (s = ua.match(/version\/([\d\.]+).*safari/)) ? Sys.safari = s[1] : 0;  
          // 根据关系进行判断
          if (Sys.ie) return ('IE: ' + Sys.ie);  
          if (Sys.edge) return ('EDGE: ' + Sys.edge);
          if (Sys.firefox) return ('Firefox: ' + Sys.firefox);  
          if (Sys.chrome) return ('Chrome: ' + Sys.chrome);  
          if (Sys.opera) return ('Opera: ' + Sys.opera);  
          if (Sys.safari) return ('Safari: ' + Sys.safari);
          return 'Unkonwn';
      }
    
  • 最终效果

image.png

image.png

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278