UNPKG

smooth-signature-v

Version:

前端H5带笔锋手写签名,支持PC端和移动端,无框架限制,Vue、React等均可使用

2 lines (1 loc) 8.19 kB
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).SmoothSignature=i()}(this,(function(){"use strict";function t(t,i){for(var e=0;i.length>e;e++){var n=i[e];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}var i=function(){function i(t,e){var n=this;!function(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")}(this,i),this.canvas={},this.ctx={},this.width=320,this.height=200,this.scale=window.devicePixelRatio||1,this.color="black",this.bgColor="",this.canDraw=!1,this.openSmooth=!0,this.minWidth=2,this.maxWidth=6,this.minSpeed=1.5,this.maxWidthDiffRate=20,this.points=[],this.canAddHistory=!0,this.historyList=[],this.maxHistoryLength=20,this.onStart=function(){},this.onEnd=function(){},this.addListener=function(){n.removeListener(),n.canvas.style.touchAction="none","ontouchstart"in window||navigator.maxTouchPoints?(n.canvas.addEventListener("touchstart",n.onDrawStart),n.canvas.addEventListener("touchmove",n.onDrawMove),document.addEventListener("touchcancel",n.onDrawEnd),document.addEventListener("touchend",n.onDrawEnd)):(n.canvas.addEventListener("mousedown",n.onDrawStart),n.canvas.addEventListener("mousemove",n.onDrawMove),document.addEventListener("mouseup",n.onDrawEnd))},this.removeListener=function(){n.canvas.style.touchAction="auto",n.canvas.removeEventListener("touchstart",n.onDrawStart),n.canvas.removeEventListener("touchmove",n.onDrawMove),document.removeEventListener("touchend",n.onDrawEnd),document.removeEventListener("touchcancel",n.onDrawEnd),n.canvas.removeEventListener("mousedown",n.onDrawStart),n.canvas.removeEventListener("mousemove",n.onDrawMove),document.removeEventListener("mouseup",n.onDrawEnd)},this.onDrawStart=function(t){t.preventDefault(),n.canDraw=!0,n.canAddHistory=!0,n.ctx.strokeStyle=n.color,n.initPoint(t),n.onStart&&n.onStart(t)},this.onDrawMove=function(t){if(t.preventDefault(),n.canDraw&&(n.initPoint(t),n.points.length>=2)){n.addHistory();var i=n.points.slice(-1)[0],e=n.points.slice(-2,-1)[0];window.requestAnimationFrame?window.requestAnimationFrame((function(){return n.onDraw(e,i)})):n.onDraw(e,i)}},this.onDraw=function(t,i){n.openSmooth?n.drawSmoothLine(t,i):n.drawNoSmoothLine(t,i)},this.onDrawEnd=function(t){n.canDraw&&(n.canDraw=!1,n.canAddHistory=!0,n.points=[],n.onEnd&&n.onEnd(t))},this.getLineWidth=function(t){return Math.min(Math.max(n.maxWidth-(n.maxWidth-n.minWidth)*t/(n.minSpeed>10?10:1>n.minSpeed?1:n.minSpeed),n.minWidth),n.maxWidth)},this.getRadianData=function(t,i,e,n){var a=e-t,o=n-i;if(0===a)return{val:0,pos:-1};if(0===o)return{val:0,pos:1};var s=Math.abs(Math.atan(o/a));return e>t&&i>n||t>e&&n>i?{val:s,pos:1}:{val:s,pos:-1}},this.getRadianPoints=function(t,i,e,n){if(0===t.val)return 1===t.pos?[{x:i,y:e+n},{x:i,y:e-n}]:[{y:e,x:i+n},{y:e,x:i-n}];var a=Math.sin(t.val)*n,o=Math.cos(t.val)*n;return 1===t.pos?[{x:i+a,y:e+o},{x:i-a,y:e-o}]:[{x:i+a,y:e-o},{x:i-a,y:e+o}]},this.initPoint=function(t){var i=Date.now(),e=n.points.slice(-1)[0];if(!e||e.t!==i){var a=n.canvas.getBoundingClientRect(),o=t.touches&&t.touches[0]||t,s=o.clientX-a.left,h=o.clientY-a.top;if(!e||e.x!==s||e.y!==h){var r={x:s,y:h,t:i};if(n.openSmooth&&e){var d=n.points.slice(-2,-1)[0];if(r.distance=Math.sqrt(Math.pow(r.x-e.x,2)+Math.pow(r.y-e.y,2)),r.speed=r.distance/(r.t-e.t||.1),r.lineWidth=n.getLineWidth(r.speed),d&&d.lineWidth&&e.lineWidth){var c=(r.lineWidth-e.lineWidth)/e.lineWidth,l=n.maxWidthDiffRate/100;if(l=l>1?1:.01>l?.01:l,Math.abs(c)>l)r.lineWidth=e.lineWidth*(1+(c>0?l:-l))}}n.points.push(r),n.points=n.points.slice(-3)}}},this.drawSmoothLine=function(t,i){var e=i.x-t.x,a=i.y-t.y;if(Math.abs(e)+Math.abs(a)>n.scale?(i.lastX1=t.x+.3*e,i.lastY1=t.y+.3*a,i.lastX2=t.x+.7*e,i.lastY2=t.y+.7*a):(i.lastX1=i.lastX2=t.x+.5*e,i.lastY1=i.lastY2=t.y+.5*a),i.perLineWidth=(t.lineWidth+i.lineWidth)/2,"number"==typeof t.lastX1){if(n.drawCurveLine(t.lastX2,t.lastY2,t.x,t.y,i.lastX1,i.lastY1,i.perLineWidth),t.isFirstPoint)return;if(t.lastX1===t.lastX2&&t.lastY1===t.lastY2)return;var o=n.getRadianData(t.lastX1,t.lastY1,t.lastX2,t.lastY2),s=n.getRadianPoints(o,t.lastX1,t.lastY1,t.perLineWidth/2),h=n.getRadianPoints(o,t.lastX2,t.lastY2,i.perLineWidth/2);n.drawTrapezoid(s[0],h[0],h[1],s[1])}else i.isFirstPoint=!0},this.drawNoSmoothLine=function(t,i){i.lastX=t.x+.5*(i.x-t.x),i.lastY=t.y+.5*(i.y-t.y),"number"==typeof t.lastX&&n.drawCurveLine(t.lastX,t.lastY,t.x,t.y,i.lastX,i.lastY,n.maxWidth)},this.drawCurveLine=function(t,i,e,a,o,s,h){n.ctx.lineWidth=Number(h.toFixed(1)),n.ctx.beginPath(),n.ctx.moveTo(Number(t.toFixed(1)),Number(i.toFixed(1))),n.ctx.quadraticCurveTo(Number(e.toFixed(1)),Number(a.toFixed(1)),Number(o.toFixed(1)),Number(s.toFixed(1))),n.ctx.stroke()},this.drawTrapezoid=function(t,i,e,a){n.ctx.beginPath(),n.ctx.moveTo(Number(t.x.toFixed(1)),Number(t.y.toFixed(1))),n.ctx.lineTo(Number(i.x.toFixed(1)),Number(i.y.toFixed(1))),n.ctx.lineTo(Number(e.x.toFixed(1)),Number(e.y.toFixed(1))),n.ctx.lineTo(Number(a.x.toFixed(1)),Number(a.y.toFixed(1))),n.ctx.fillStyle=n.color,n.ctx.fill()},this.drawBgColor=function(){n.bgColor&&(n.ctx.fillStyle=n.bgColor,n.ctx.fillRect(0,0,n.width,n.height))},this.drawByImageUrl=function(t){var i=new Image;i.onload=function(){n.ctx.clearRect(0,0,n.width,n.height),n.ctx.drawImage(i,0,0,n.width,n.height)},i.crossOrigin="anonymous",i.src=t},this.addHistory=function(){n.maxHistoryLength&&n.canAddHistory&&(n.canAddHistory=!1,n.historyList.push(n.canvas.toDataURL()),n.historyList=n.historyList.slice(-n.maxHistoryLength))},this.clear=function(){n.ctx.clearRect(0,0,n.width,n.height),n.drawBgColor(),n.historyList.length=0},this.undo=function(){var t=n.historyList.splice(-1)[0];t&&n.drawByImageUrl(t)},this.toDataURL=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"image/png",i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;if(n.canvas.width===n.width)return n.canvas.toDataURL(t,i);var e=document.createElement("canvas");e.width=n.width,e.height=n.height;var a=e.getContext("2d");return a.drawImage(n.canvas,0,0,e.width,e.height),e.toDataURL(t,i)},this.getPNG=function(){return n.toDataURL()},this.getJPG=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:.8;return n.toDataURL("image/jpeg",t)},this.isEmpty=function(){var t=document.createElement("canvas"),i=t.getContext("2d");return t.width=n.canvas.width,t.height=n.canvas.height,n.bgColor?(i.fillStyle=n.bgColor,i.fillRect(0,0,t.width,t.height)):1!==n.scale&&i.scale(n.scale,n.scale),t.toDataURL()===n.canvas.toDataURL()},this.getRotateCanvas=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:90;t=t>0?t>90?180:90:-90>t?180:-90;var i=document.createElement("canvas"),e=n.width,a=n.height;180===t?(i.width=e,i.height=a):(i.width=a,i.height=e);var o=i.getContext("2d");return o.rotate(t*Math.PI/180),90===t?o.drawImage(n.canvas,0,-a,e,a):-90===t?o.drawImage(n.canvas,-e,0,e,a):180===t&&o.drawImage(n.canvas,-e,-a,e,a),i},this.init(t,e)}var e,n,a;return e=i,n=[{key:"init",value:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t&&(this.canvas=t,this.ctx=t.getContext("2d"),this.width=i.width||t.clientWidth||this.width,this.height=i.height||t.clientHeight||this.height,this.scale=i.scale||this.scale,this.color=i.color||this.color,this.bgColor=i.bgColor||this.bgColor,this.openSmooth=void 0===i.openSmooth?this.openSmooth:!!i.openSmooth,this.minWidth=i.minWidth||this.minWidth,this.maxWidth=i.maxWidth||this.maxWidth,this.minSpeed=i.minSpeed||this.minSpeed,this.maxWidthDiffRate=i.maxWidthDiffRate||this.maxWidthDiffRate,this.maxHistoryLength=i.maxHistoryLength||this.maxHistoryLength,this.onStart=i.onStart,this.onEnd=i.onEnd,this.scale>0&&(this.canvas.height=this.height*this.scale,this.canvas.width=this.width*this.scale,1!==this.scale&&(this.canvas.style.width=this.width+"px",this.canvas.style.height=this.height+"px",this.ctx.scale(this.scale,this.scale))),this.ctx.lineCap="round",this.drawBgColor(),this.addListener())}}],n&&t(e.prototype,n),a&&t(e,a),i}();return i}));