电子签名功能 原生js

适用于移动端,项目做了移动端的自适配

html文件

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,maximum-scale=1,initial-scale=1,user-scalable=no">
  <title>sing2</title>
  <!-- <link rel="stylesheet" href="addicon/iconfont.css" /> -->
  <link rel="stylesheet" href="signature.css" />
  <script type="text/javascript" src="signature.js"></script>
</head>

<body>
</body>

</html>

css文件

body,p,dl,dd,ul,ol,li,div,h1,h2,h3,h4,h5,h6,form,input,table,tr,td{
	margin:0;
	padding:0;
}
html{
  font-size: 26.67vw;
}
html,body,.cancas-cont{
  height: 100%;
  height: 100%;
  font-size: 1rem;
}
ul,ol{
	list-style:none;
}
img{
	border: 0;
	display: block;
}
a{
	text-decoration: none;
	display: block;
}
span{
  display: block;
}
.cancas-cont{
  display: flex;
	flex-direction: column;
}
.sign-footer{
  width: 100%;
  height: 2rem;
  position: fixed;
  top: 0;
}
.sign-footer{
  display: flex;
}
.sign-footer,.sign-header{
  background-color: #fff;
}
.cell-top,.cell-bottom{
  display: flex;
  flex-direction: row-reverse;
  width: 50%;
  height: 2rem;
  text-align: center;
  border-bottom: 1px solid #d0cccc;
  position: relative;

}
.cell-bottom{
  border-left: 1px solid #d0cccc;
}
.cell-bottom span{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(90deg);
  width: 1rem;
  color: #72f572;
}
.cell-top span{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(90deg);
  width: 1rem;
  color: #cc1313;
}



/* 画布 */
.sign-context{
  width: 100%;
height: 100%;
overflow: hidden;
}
/* canvas{
  width: 100%;
  height: 100%;
} */


.sign-header{
  position: fixed;
  bottom: 0;
  height: 2rem;
  display: flex;
  justify-content: space-between;
  border-top: 1px solid #d0cccc;
  width: 100%;
}
.title{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(90deg);
  width: 1rem;
}
.close-con{
  margin-right: .4rem;
  display: flex;
  justify-content: center;
  align-items: center;
}

javascript文件

 function Signature (param) {
  this.param = param;
  this.init();
  this.paintInit({});
  this.addListener();

};
/**
 * 对象初始化
 */
Signature.prototype.init = function () {
  var clientWidth = document.body.clientWidth || document.documentElement.clientWidth;
  var clientHeight = document.body.clientHeight || document.documentElement.clientHeight;
  var con = document.createElement('div');
  con.id = 'sign-con';
  con.className = 'sign-con';
  con.style.height = clientHeight + 'px';
  document.body.appendChild(con);
  var arcHtml =
    `<div class="cancas-cont">
        <div class="sign-footer">
          <div class="cell-top"><span id="rewrite">重写</span></div>
          <div class="cell-bottom"><span id="signcommit">提交</span></div>
        </div>
        <div class="sign-context" id="sign-context"><canvas id="sign-canvas"></canvas></div>
        <div class="sign-header">
          <div></div>
          <span class="title" id="sign-title">电子签名</span>
          <div class="close-con" id="sign-close"><i class="addiconfont icon-123"></i></div>
        </div>
      </div>`
  con.innerHTML = arcHtml;
  this.con = con;
  this.canvas = document.getElementById('sign-canvas');
  this.ctx = this.canvas.getContext('2d');
  var clientWidth = document.documentElement.clientWidth;
  var clientHeight = document.documentElement.clientHeight;
  var canvasWidth = Math.floor(clientWidth);
  var canvasHeight = Math.floor(clientHeight);
  this.canvas.setAttribute('width', canvasWidth + 'px');
  this.canvas.setAttribute('height', canvasHeight + 'px');
};
//设置监听事件
Signature.prototype.addListener = function () {
  var _this = this;
  var point = {
    boxTop: 0,
    boxLeft: 0,
    startX: 0,
    startY: 0,
  };
  var eventObj = {
    touchStart: function (ev) {
      ev.preventDefault();
      var box = _this.canvas.getBoundingClientRect();
      var targetTouch = ev.targetTouches[0];
      point.boxTop = box.top;
      point.boxLeft = box.left;
      point.startX = targetTouch.clientX;
      point.startY = targetTouch.clientY;
      _this.ctx.beginPath();
      _this.ctx.moveTo(point.startX - point.boxLeft, point.startY - point.boxTop);
      _this.ctx.lineTo(targetTouch.clientX - point.boxLeft, targetTouch.clientY - point.boxTop);
      _this.ctx.stroke();
    },
    touchMove: function (ev) {
      ev.preventDefault();
      var targetTouch = ev.targetTouches[0];
      _this.ctx.beginPath();
      _this.ctx.moveTo(point.startX - point.boxLeft, point.startY - point.boxTop);
      _this.ctx.lineTo(targetTouch.clientX - point.boxLeft, targetTouch.clientY - point.boxTop);
      _this.ctx.stroke();
      point.startX = targetTouch.clientX;
      point.startY = targetTouch.clientY;
    },
    //提交/重写
    controlEvent: function (ev) {
      var targetId = ev.target.id;
      if (targetId == 'sign-close') {
        alert("路由跳转")
      } else if (targetId == 'rewrite') {
        _this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
      } else if (targetId == 'signcommit') {
        if (maxX - minX <= 100 || maxY - minY <= 300) {
          alert("亲,签名太小啦,请重新输入嘛!!!")
          _this.ctx.clearRect(0, 0, _this.canvas.width, _this.canvas.height);
          return
        }
        var signData = _this.canvas.toDataURL();
        _this.param.cb.call(null, signData);
      };
    }
  };
  this.eventObj = eventObj;
  this.canvas.addEventListener('touchstart', eventObj.touchStart, false);
  this.canvas.addEventListener('touchmove', eventObj.touchMove, false);
  this.con.addEventListener('click', eventObj.controlEvent, false);
};
/**
 * 画笔初始化
 * @param {Object} opt
 */
Signature.prototype.paintInit = function (opt) {
  var paintOpt = opt || {};
  this.ctx.lineJoin = 'round';
  this.ctx.lineCap = 'round';
  this.ctx.strokeStyle = opt.strokeStyle || '#000';
  this.ctx.lineWidth = opt.lineWidth || 3;

};
//移除监听
Signature.prototype.removeListener = function () {
  this.canvas.removeEventListener('touchstart', this.eventObj.touchStart);
  this.canvas.removeEventListener('touchmove', this.eventObj.touchMove);
  this.con.removeEventListener('click', this.eventObj.controlEvent);
};
//关闭签名器
Signature.prototype.close = function () {
  this.removeListener();
  document.body.removeChild(this.con);
};
let arrX = []
let arrY = []
let maxX
let minX
let maxY
let minY
window.onload = function () {
  var sign = new Signature({
    cb: function (signData) {
      let baseAcreage =
        (maxX - minX) *
        (maxY - minY);
      let canvasAcreage = document.getElementById('sign-canvas').width * document.getElementById('sign-canvas').height;
      if (canvasAcreage / baseAcreage >= 4) {
        alert("亲,签名太小啦,请重新签名嘛!!!");
        document.getElementById('rewrite').addEventListener('click', sign.eventObj.controlEvent, false);
      } else {
        dealImage(signData, 200, (callback) => {
          console.log(callback)
        })
      }
      function dealImage (base64, w, callback) {
        var newImage = new Image();
        var quality = 0.6;    //压缩系数0-1之间
        newImage.src = base64;
        newImage.setAttribute("crossOrigin", 'Anonymous');	//url为外域时需要
        var imgWidth, imgHeight;
        newImage.onload = function () {
          imgWidth = this.width;
          imgHeight = this.height;
          var canvas = document.createElement("canvas");
          var ctx = canvas.getContext("2d");
          if (Math.max(imgWidth, imgHeight) > w) {
            if (imgWidth > imgHeight) {
              canvas.width = w;
              canvas.height = w * imgHeight / imgWidth;
            } else {
              canvas.height = w;
              canvas.width = w * imgWidth / imgHeight;
            }
          } else {
            canvas.width = imgWidth;
            canvas.height = imgHeight;
            quality = 0.6;
          }
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
          var base64 = canvas.toDataURL("image/png", quality); //压缩语句
          callback(base64)
        }
      }
      sign.removeListener();
    },
  })
  var pad = document.getElementById('sign-context');
  pad.addEventListener('touchmove', function (e) {
    var ev = e || window.event;
    var touch = ev.targetTouches[0];
    arrX.push(touch.clientX)
    arrY.push(touch.clientY)
    maxX = Math.max.apply(null, arrX);
    minX = Math.min.apply(null, arrX);
    maxY = Math.max.apply(null, arrY);
    minY = Math.min.apply(null, arrY);
  });
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值