jQuery实现移动端笔触canvas电子签名


Posted in jQuery onMay 21, 2020

本文实例为大家分享了jQuery实现移动端笔触canvas电子签名的具体代码,供大家参考,具体内容如下

本文主要是通过jq实现电子签名,其中ios有一个坑,已修复。基于mui+vue框架实现的,如果使用此框架,稍稍改动代码即可。

1.相关代码

1.1引入jq

<script src="jquery-1.11.0.min.js" type="text/javascript"></script>

1.2封装signature.js

(function(window, document, $) {
 'use strict';

 // Get a regular interval for drawing to the screen
 window.requestAnimFrame = (function (callback) {
 return window.requestAnimationFrame || 
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  window.oRequestAnimationFrame ||
  window.msRequestAnimaitonFrame ||
  function (callback) {
  window.setTimeout(callback, 1000/60);
  };
 })();

 /*
 * Plugin Constructor
 */

 var pluginName = 'jqSignature',
  defaults = {
  lineColor: '#222222',
  lineWidth: 1,
  border: '1px dashed #AAAAAA',
  background: '#FFFFFF',
  width: 375,
  height: 200,
  autoFit: false
  },
  canvasFixture = '<canvas></canvas>';

 function Signature(element, options) {
 // DOM elements/objects
 this.element = element;
 this.$element = $(this.element);
 this.canvas = false;
 this.$canvas = false;
 this.ctx = false;
 // Drawing state
 this.drawing = false;
 this.currentPos = {
  x: 0,
  y: 0
 };
 this.lastPos = this.currentPos;
 // Determine plugin settings
 this._data = this.$element.data();
 this.settings = $.extend({}, defaults, options, this._data);
 // Initialize the plugin
 this.init();
 }

 Signature.prototype = {
 // Initialize the signature canvas
 init: function() {
  // Set up the canvas
  this.$canvas = $(canvasFixture).appendTo(this.$element);
  this.$canvas.attr({
  width: this.settings.width,
  height: this.settings.height
  });
  this.$canvas.css({
  boxSizing: 'border-box',
  width: this.settings.width + 'px',
  height: this.settings.height + 'px',
  border: this.settings.border,
  background: this.settings.background,
  cursor: 'crosshair'
  });
  // Fit canvas to width of parent
  if (this.settings.autoFit === true) {
  this._resizeCanvas();
  // TO-DO - allow for dynamic canvas resizing 
  // (need to save canvas state before changing width to avoid getting cleared)
   var timeout = false;
   $(window).on('resize', $.proxy(function(e) {
    clearTimeout(timeout);
    timeout = setTimeout($.proxy(this._resizeCanvas, this), 250);
   }, this));
  }
  this.canvas = this.$canvas[0];
  this._resetCanvas();
  // Set up mouse events
  this.$canvas.on('mousedown touchstart', $.proxy(function(e) {
  this.drawing = true;
  this.lastPos = this.currentPos = this._getPosition(e);
  }, this));
  this.$canvas.on('mousemove touchmove', $.proxy(function(e) {
  this.currentPos = this._getPosition(e);
  }, this));
  this.$canvas.on('mouseup touchend', $.proxy(function(e) {
  this.drawing = false;
  // Trigger a change event
  var changedEvent = $.Event('jq.signature.changed');
  this.$element.trigger(changedEvent);
  }, this));
  // Prevent document scrolling when touching canvas
  $(document).on('touchstart touchmove touchend', $.proxy(function(e) {
  if (e.target === this.canvas) {
   e.preventDefault();
  }
  }, this));
  // Start drawing
  var that = this;
  (function drawLoop() {
  window.requestAnimFrame(drawLoop);
  that._renderCanvas();
  })();
 },
 // Clear the canvas
 clearCanvas: function() {
  this.canvas.width = this.canvas.width;
  this._resetCanvas();
 },
 // Get the content of the canvas as a base64 data URL
 getDataURL: function() {
  return this.canvas.toDataURL();
 },
 // Get the position of the mouse/touch
 _getPosition: function(event) {
  var u = navigator.userAgent;
  var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  var xPos, yPos, rect, getRect;
  rect = this.canvas.getBoundingClientRect();
  event = event.originalEvent;
  // Touch event
  if (event.type.indexOf('touch') !== -1) { // event.constructor === TouchEvent
  xPos = event.touches[0].clientX - rect.left;
  yPos = event.touches[0].clientY - 50;
  $('#yPos').html('<p><em>当您点击“保存签名”时,W您的签名将出现在这里'+yPos+','+rect.top+','+rect.bottom+'</em></p>');
  
  }

  // Mouse event
  else {
  xPos = event.clientX - rect.left;
  yPos = event.clientY - rect.top;
  $('#yPos').html(yPos);
  }
  return {
  x: xPos,
  y: yPos
//  y: isIOS?1.7*yPos:yPos
  };
 },
 // Render the signature to the canvas
 _renderCanvas: function() {
  if (this.drawing) {
  this.ctx.moveTo(this.lastPos.x, this.lastPos.y);
  this.ctx.lineTo(this.currentPos.x, this.currentPos.y);
  this.ctx.stroke();
  this.lastPos = this.currentPos;
  }
 },
 // Reset the canvas context
 _resetCanvas: function() {
  this.ctx = this.canvas.getContext("2d");
  this.ctx.strokeStyle = this.settings.lineColor;
  this.ctx.lineWidth = this.settings.lineWidth;
 },
 // Resize the canvas element
 _resizeCanvas: function() {
  var width = this.$element.outerWidth();
  this.$canvas.attr('width', width);
  this.$canvas.css('width', width + 'px');
 }
 };

 /*
 * Plugin wrapper and initialization
 */

 $.fn[pluginName] = function ( options ) {
 var args = arguments;
 if (options === undefined || typeof options === 'object') {
  return this.each(function () {
  if (!$.data(this, 'plugin_' + pluginName)) {
   $.data(this, 'plugin_' + pluginName, new Signature( this, options ));
  }
  });
 } 
 else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
  var returns;
  this.each(function () {
  var instance = $.data(this, 'plugin_' + pluginName);
  if (instance instanceof Signature && typeof instance[options] === 'function') {
   returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
  }
  if (options === 'destroy') {
   $.data(this, 'plugin_' + pluginName, null);
  }
  });
  return returns !== undefined ? returns : this;
 }
 };

})(window, document, jQuery);

1.3DOM页面index.html

<div class="signature-wrapper" v-show="isSignature" :class="isSignature?'isSignature':''">
 <header class="mui-bar mui-bar-nav head-color">
 <a class="mui-icon mui-icon-back mui-pull-left" @tap="closeSignature"></a>
 <h1 class="mui-title">签名</h1>
 <a id="menu" class="mui-icon mui-pull-right menu-btn" @tap="saveSignature">保存</a>
 </header>

 <div class="container">
 <div class="row">
 <div class="col-xs-12">
 <div class="js-signature" data-width="600" data-height="200" data-border="1px solid black" data-line-color="#000000" data-auto-fit="true"></div>
 <p><button id="clearBtn" class="btn btn-default" @tap="clearCanvas();">重置签名</button> <button id="saveBtn" class="btn btn-default" @tap="previewSignature();" disabled>保存签名</button></p>
 <div id="signature">
  <p><em>当您点击“保存签名”时,您的签名将出现在这里</em></p>
 </div>
 <span id="yPos"><p><em>ypos</em></p></span>
 </div>
 </div>
 </div>
</div>

1.4JS

注:由于此次的$被模型其他框架所替换,因此以jq替代

mounted: function() {
this.$nextTick(function() {
 this.init();
 });
},
methods:{
 init: function() {
 jq('.js-signature').eq(0).on('jq.signature.changed', function() { //canvas签名 初始化 
 jq('#saveBtn').attr('disabled', false);
 });
 }
},
clearCanvas:function(){ // 清除重置签名
 jq('#signature').html('<p><em>当您点击“保存签名”时,您的签名将出现在这里</em></p>');
 jq('.js-signature').eq(0).jqSignature('clearCanvas');
 jq('#saveBtn').attr('disabled', true);
 vm.signatureImg="";
},
previewSignature:function(){ //保存签名
 jq('#signature').empty();
 var dataUrl = jq('.js-signature').eq(0).jqSignature('getDataURL');
 var img = jq('<img>').attr('src', dataUrl);
 jq('#signature').append(img);
 console.log(dataUrl)
 vm.signatureImg=dataUrl;
},
saveSignature:function(){ // 保存按钮 逻辑
if(!vm.signatureImg){
 $.toast("请先保存签名");
 return;
 }
 vm.closeSignature();
},
closeSignature:function(){// 关闭签名弹出层
 vm.isSignature = false;
 },
openSignature:function(){ // 打开签名弹出层
 vm.isSignature = true;
 this.$nextTick(function() {
 if ($('.js-signature').length) {
 jq('.js-signature').jqSignature();
 }
 });
}

2.页面效果图如下

jQuery实现移动端笔触canvas电子签名

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

jQuery 相关文章推荐
jQuery自定义图片上传插件实例代码
Apr 04 jQuery
利用jQuery异步上传文件的插件用法详解
Jul 19 jQuery
jQuery Validate插件ajax方式验证输入值的实例
Dec 21 jQuery
jQuery插件Validation表单验证详解
May 26 jQuery
jQuery实现基本隐藏与显示效果的方法详解
Sep 05 jQuery
js jquery 获取某一元素到浏览器顶端的距离实现方法
Sep 05 jQuery
jQuery中实现text()的方法
Apr 04 jQuery
JQuery事件委托原理与用法实例分析
May 13 jQuery
jquery.pager.js实现分页效果
Jul 29 jQuery
jQuery实现html可联动的百分比进度条
Mar 26 jQuery
jquery插件实现轮播图效果
Oct 19 jQuery
jQuery ajax - getScript() 方法和getJSON方法
May 14 jQuery
jQuery HTML获取内容和属性操作实例分析
May 20 #jQuery
jQuery HTML设置内容和属性操作实例分析
May 20 #jQuery
jquery html添加元素/删除元素操作实例详解
May 20 #jQuery
jQuery HTML css()方法与css类实例详解
May 20 #jQuery
jQuery 隐藏/显示效果函数用法实例分析
May 20 #jQuery
jQuery 淡入/淡出效果函数用法分析
May 19 #jQuery
jQuery 动画与停止动画效果实例详解
May 19 #jQuery
You might like
CI框架中cookie的操作方法分析
2014/12/12 PHP
PHP中基本HTTP认证技巧分析
2015/03/16 PHP
PHP中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例
2015/02/13 Javascript
jQuery如何防止这种冒泡事件发生
2015/02/27 Javascript
JavaScript分页功能的实现方法
2015/04/25 Javascript
JavaScript中Function()函数的使用教程
2015/06/04 Javascript
Javascript实现div的toggle效果实例分析
2015/06/09 Javascript
JavaScript导航脚本判断当前导航
2016/07/12 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
详解javascript表单的Ajax提交插件的使用
2016/12/29 Javascript
jQuery插件FusionCharts实现的Marimekko图效果示例【附demo源码】
2017/03/24 jQuery
ECMAScript6变量的解构赋值实例详解
2017/09/19 Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
2018/05/24 jQuery
vue router的基本使用和配置教程
2018/11/05 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
js实现消灭星星(web简易版)
2020/03/24 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
2021/03/01 Vue.js
[01:04:32]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第二场 2月23日
2021/03/11 DOTA
python+os根据文件名自动生成文本
2019/03/21 Python
提升Python效率之使用循环机制代替递归函数
2019/07/23 Python
python实现自动打卡的示例代码
2020/10/10 Python
用Python自动清理系统垃圾的实现
2021/01/18 Python
家乐福巴西网上超市:Carrefour巴西
2016/10/31 全球购物
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
举例说明类变量和实例变量的区别
2016/06/30 面试题
物业管理求职自荐信
2013/09/25 职场文书
商务助理岗位职责
2013/11/13 职场文书
护士演讲稿优秀范文
2014/04/30 职场文书
庆元旦演讲稿
2014/09/15 职场文书
领导干部整治奢华浪费之风思想汇报
2014/10/07 职场文书
导游词之桂林山水
2019/09/20 职场文书
Go各时间字符串使用解析
2021/04/02 Golang
聊聊JS ES6中的解构
2021/04/29 Javascript