smooth-signature
Version:
前端H5带笔锋手写签名,支持PC端和移动端,无框架限制,Vue、React等均可使用
2 lines (1 loc) • 8.8 kB
JavaScript
!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,e){for(var n=0;e.length>n;n++){var a=e[n];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,i(a.key),a)}}function i(t){var i=function(t,i){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var n=e.call(t,i||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===i?String:Number)(t)}(t,"string");return"symbol"==typeof i?i:i+""}var e=/Android|iPhone|iPad|Mobile/i.test(navigator.userAgent),n=function(){function i(t,n){var a=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.undoList=[],this.redoList=[],this.onStart=function(){},this.onEnd=function(){},this.addListener=function(){a.removeListener(),a.canvas.style.touchAction="none",e&&("ontouchstart"in window||navigator.maxTouchPoints)?(a.canvas.addEventListener("touchstart",a.onDrawStart,{passive:!1}),a.canvas.addEventListener("touchmove",a.onDrawMove,{passive:!1}),document.addEventListener("touchcancel",a.onDrawEnd,{passive:!1}),document.addEventListener("touchend",a.onDrawEnd,{passive:!1})):(a.canvas.addEventListener("mousedown",a.onDrawStart),a.canvas.addEventListener("mousemove",a.onDrawMove),document.addEventListener("mouseup",a.onDrawEnd))},this.removeListener=function(){a.canvas.style.touchAction="auto",a.canvas.removeEventListener("touchstart",a.onDrawStart),a.canvas.removeEventListener("touchmove",a.onDrawMove),document.removeEventListener("touchend",a.onDrawEnd),document.removeEventListener("touchcancel",a.onDrawEnd),a.canvas.removeEventListener("mousedown",a.onDrawStart),a.canvas.removeEventListener("mousemove",a.onDrawMove),document.removeEventListener("mouseup",a.onDrawEnd)},this.onDrawStart=function(t){t.preventDefault(),a.canDraw=!0,a.initPoint(t),a.onStart&&a.onStart(t)},this.onDrawMove=function(t){if(t.preventDefault(),a.canDraw&&(a.initPoint(t),a.points.length>=2)){var i=a.points.slice(-1)[0],e=a.points.slice(-2,-1)[0];window.requestAnimationFrame?window.requestAnimationFrame((function(){return a.onDraw(e,i)})):a.onDraw(e,i)}},this.onDraw=function(t,i){a.ctx.strokeStyle=i.color||a.color,a.openSmooth?a.drawSmoothLine(t,i):a.drawNoSmoothLine(t,i)},this.onDrawEnd=function(t){a.canDraw&&(a.undoList.push(a.points),a.redoList=[],a.canDraw=!1,a.points=[],a.onEnd&&a.onEnd(t))},this.getLineWidth=function(t){return Math.min(Math.max(a.maxWidth-(a.maxWidth-a.minWidth)*t/(a.minSpeed>10?10:1>a.minSpeed?1:a.minSpeed),a.minWidth),a.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=a.points.slice(-1)[0];if(!e||e.t!==i){var n=a.canvas.getBoundingClientRect(),o=t.touches&&t.touches[0]||t,s=o.clientX-n.left,r=o.clientY-n.top;if(!e||e.x!==s||e.y!==r){var h={x:s,y:r,t:i,color:a.color};if(a.openSmooth&&e){var d=a.points.slice(-2,-1)[0];if(h.distance=Math.sqrt(Math.pow(h.x-e.x,2)+Math.pow(h.y-e.y,2)),h.speed=h.distance/(h.t-e.t||.1),h.lineWidth=a.getLineWidth(h.speed),d&&d.lineWidth&&e.lineWidth){var c=(h.lineWidth-e.lineWidth)/e.lineWidth,l=a.maxWidthDiffRate/100;if(l=l>1?1:.01>l?.01:l,Math.abs(c)>l)h.lineWidth=e.lineWidth*(1+(c>0?l:-l))}}a.points.push(h)}}},this.drawSmoothLine=function(t,i){var e=i.x-t.x,n=i.y-t.y;if(Math.abs(e)+Math.abs(n)>a.scale?(i.lastX1=t.x+.3*e,i.lastY1=t.y+.3*n,i.lastX2=t.x+.7*e,i.lastY2=t.y+.7*n):(i.lastX1=i.lastX2=t.x+.5*e,i.lastY1=i.lastY2=t.y+.5*n),i.perLineWidth=(t.lineWidth+i.lineWidth)/2,"number"==typeof t.lastX1){if(a.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=a.getRadianData(t.lastX1,t.lastY1,t.lastX2,t.lastY2),s=a.getRadianPoints(o,t.lastX1,t.lastY1,t.perLineWidth/2),r=a.getRadianPoints(o,t.lastX2,t.lastY2,i.perLineWidth/2);a.drawTrapezoid(s[0],r[0],r[1],s[1],i.color)}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&&a.drawCurveLine(t.lastX,t.lastY,t.x,t.y,i.lastX,i.lastY,a.maxWidth)},this.drawCurveLine=function(t,i,e,n,o,s,r){a.ctx.lineWidth=Number(r.toFixed(1)),a.ctx.beginPath(),a.ctx.moveTo(Number(t.toFixed(1)),Number(i.toFixed(1))),a.ctx.quadraticCurveTo(Number(e.toFixed(1)),Number(n.toFixed(1)),Number(o.toFixed(1)),Number(s.toFixed(1))),a.ctx.stroke()},this.drawTrapezoid=function(t,i,e,n,o){a.ctx.beginPath(),a.ctx.moveTo(Number(t.x.toFixed(1)),Number(t.y.toFixed(1))),a.ctx.lineTo(Number(i.x.toFixed(1)),Number(i.y.toFixed(1))),a.ctx.lineTo(Number(e.x.toFixed(1)),Number(e.y.toFixed(1))),a.ctx.lineTo(Number(n.x.toFixed(1)),Number(n.y.toFixed(1))),a.ctx.fillStyle=o||a.color,a.ctx.fill()},this.drawBgColor=function(){a.bgColor&&(a.ctx.fillStyle=a.bgColor,a.ctx.fillRect(0,0,a.width,a.height))},this.drawByImageUrl=function(t){var i=new Image;i.onload=function(){a.ctx.clearRect(0,0,a.width,a.height),a.ctx.drawImage(i,0,0,a.width,a.height)},i.crossOrigin="anonymous",i.src=t},this.clear=function(){a.ctx.clearRect(0,0,a.width,a.height),a.drawBgColor(),a.undoList=[],a.redoList=[]},this.undo=function(){if(a.undoList.length){var t=a.undoList.pop();t&&a.redoList.unshift(t),a.ctx.clearRect(0,0,a.width,a.height),a.drawBgColor(),a.undoList.forEach((function(t){t.forEach((function(i,e){0!==e&&a.onDraw(t[e-1],i)}))}))}},this.redo=function(){if(a.redoList.length){var t=a.redoList.shift();t&&a.undoList.push(t),a.ctx.clearRect(0,0,a.width,a.height),a.drawBgColor(),a.undoList.forEach((function(t){t.forEach((function(i,e){0!==e&&a.onDraw(t[e-1],i)}))}))}},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(a.canvas.width===a.width)return a.canvas.toDataURL(t,i);var e=document.createElement("canvas");e.width=a.width,e.height=a.height;var n=e.getContext("2d");return n.drawImage(a.canvas,0,0,e.width,e.height),e.toDataURL(t,i)},this.getPNG=function(){return a.toDataURL()},this.getJPG=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:.8;return a.toDataURL("image/jpeg",t)},this.isEmpty=function(){var t=document.createElement("canvas"),i=t.getContext("2d");return t.width=a.canvas.width,t.height=a.canvas.height,a.bgColor?(i.fillStyle=a.bgColor,i.fillRect(0,0,t.width,t.height)):1!==a.scale&&i.scale(a.scale,a.scale),t.toDataURL()===a.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=a.width,n=a.height;180===t?(i.width=e,i.height=n):(i.width=n,i.height=e);var o=i.getContext("2d");return o.rotate(t*Math.PI/180),90===t?o.drawImage(a.canvas,0,-n,e,n):-90===t?o.drawImage(a.canvas,-e,0,e,n):180===t&&o.drawImage(a.canvas,-e,-n,e,n),i},this.init(t,n)}var n,a,o;return n=i,a=[{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.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())}}],a&&t(n.prototype,a),o&&t(n,o),Object.defineProperty(n,"prototype",{writable:!1}),i}();return n}));