From 3de87ad59019b3c8662dcdb52dc249a45511c9b2 Mon Sep 17 00:00:00 2001 From: yujk <990961482@qq.com> Date: Fri, 1 Apr 2022 11:35:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87=E5=92=8Cjs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- image/icon/arrowRight.png | Bin 0 -> 406 bytes image/icon/contract.png | Bin 0 -> 442 bytes image/icon/e-sign.png | Bin 0 -> 386 bytes image/icon/stop.png | Bin 0 -> 375 bytes image/icon/triangle.png | Bin 0 -> 220 bytes utils/signature_pad.js | 390 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 390 insertions(+) create mode 100644 image/icon/arrowRight.png create mode 100644 image/icon/contract.png create mode 100644 image/icon/e-sign.png create mode 100644 image/icon/stop.png create mode 100644 image/icon/triangle.png create mode 100644 utils/signature_pad.js diff --git a/image/icon/arrowRight.png b/image/icon/arrowRight.png new file mode 100644 index 0000000000000000000000000000000000000000..40b46edabac741d406fcda452edd651ff6682289 GIT binary patch literal 406 zcmV;H0crk;P)Z3tTuaIUSI;g|K!ua34dv}+Sk+Ep^ z?%j(hbs^CfgDi4!aXAaLSRaTN?%K60nG(xMvKZv+_wV2L11*fB)N+z6hWXId)pZ`o zav(k+C@2`bYSpTbr23vLi$RvSxw-WLOT9cG^8(OvXHqRE+hUOAK%awr4f6d3c6RpQ zEnBucB-ZB?S&VEs(DxrWIXRs-Z{B>77|SWP7-WgBudn`(A3yd1E&tEK!C_2{Xu zr>Cd?@87@Y0#iC8FvyMQVlh%Ye+2s0i7r76vlJM@7lnj`oJdL8WCt}YFOy>_C|!_c zF;W4t2$+WpN%1Kx#gk+)w8&fw)a(Gni-46y5;0i^n;McVMye#5fR#iOxt5X?)X-}2 z95BZ;(!E-w#E0m5Neb#wizx|#(V(Uz^hnYR0QLsdAB@~enE(I)07*qoM6N<$f-3^A A^Z)<= literal 0 HcmV?d00001 diff --git a/image/icon/contract.png b/image/icon/contract.png new file mode 100644 index 0000000000000000000000000000000000000000..239d447e817e38b381379cf2480b94d83d0f7544 GIT binary patch literal 442 zcmV;r0Y(0aP)E#CE3FHWJ10HD{LJ@BOg@KYX!~%{$0gO#Z zJb`$F+`xDODRsu#bzhh;W(=9&*tj#P-sanX|K0bnzZoR}a3$YwV!P~4+vZ0U5K9bE zDFdt>Ow>ZenSk&B0>t)G``g+SN$f}CYhZr*Cm?6zEfDacszvcLS=qs`vNb342I5?! z5(Kal(ELw5V&ZsZPqV_=`17ebn^7!^&Px?BKQHZI^8L(>291TD?|y)K;n-C`%`y-v zj@SA=$#Rfpq9L*HLzjZ;?2!|WL;+7^8C}_eU!}ERPvF$nc2$$m;+> k>zEn>l^Rgh^)Wm41u%{VpNhe&+yDRo07*qoM6N<$f)k3q{{R30 literal 0 HcmV?d00001 diff --git a/image/icon/e-sign.png b/image/icon/e-sign.png new file mode 100644 index 0000000000000000000000000000000000000000..74a05dd5463b79538e9ae9b842f71dbfcea41f5e GIT binary patch literal 386 zcmV-|0e$|7P)t<>IDr)ws1sNwfDt-^ zET3IPfD}OH-W$QzZCEc* zgaDWpg*`47-VFxkjr~M>CG#gJKr)GA7FUDPOn|J&KtT1z^)9Vljxyq`0`}0m*QjDq)uN;TwC+*?pq_2>RL*?OYPi5x`dzCFc#B gn$E#E_A}~#00a~05!7ueuK)l507*qoM6N<$g8L1ijQ{`u literal 0 HcmV?d00001 diff --git a/image/icon/stop.png b/image/icon/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..adf876fddf0cb31160bdc26c35ec3c4425aef455 GIT binary patch literal 375 zcmV--0f_#IP)A#$C9R=Dm4=c3z{Wx%5uJsI!KMk37$uTUcAJmM zBqp;#VnM<{I$F9l5sJZAM5F4tmn)4p$;o@p`F*^<^9KB^2N-HV=@WVbcyTw~+ug7i zbG*YntVo(pz)~G5AJ9lc-nXqbsCL0zBn}+~H`EmJa2vaX^%^>pu+xNNvCW_c2Rg2) zK5He$XVn9q_n%-SxPh|D@pj1BVOYTH_cBJs7?(yk^*Rx#ESqzz0|o^r1%JtsF2WDm z{m}QBFvf|F#Xh+DFGdxz8XehrG`NFVt%^Dnbb9+Mu=BdEDe=WEak7 z5uV%=7rw1wVx!@_Mvf2jAO3f8yMLB9re^>C`DrN$7Y;3dZqIyptN)rg%N$C1crHqJ zZI$@HaSof&&Vr0z-{!yUe|f3lUUmYng22{oN{yW#|JUS5{rj8l6C-wKBZCV2b%t%6 z-SrOd;-s!jWiaM&W!_bv@b2E5+aGvWvzh!iIB=);jgN@*gul#5hwt>RVPx2yWwq(e TmMT7=^B6o`{an^LB{Ts5*J4 0) { + var xdiff = cx - px; + var ydiff = cy - py; + length += Math.sqrt(xdiff * xdiff + ydiff * ydiff); + } + px = cx; + py = cy; + } + + return length; + }; + + /* eslint-disable no-multi-spaces, space-in-parens */ + Bezier.prototype._point = function(t, start, c1, c2, end) { + return start * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * c1 * (1.0 - t) * (1.0 - t) * t + 3.0 * c2 * (1.0 - t) * t * t + end * t * t * t; + }; + + /* eslint-disable */ + + // http://stackoverflow.com/a/27078401/815507 + function throttle(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function later() { + previous = options.leading === false ? 0 : Date.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = Date.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + } + + function SignaturePad(canvas, options) { + var self = this; + var opts = options || {}; + + this.velocityFilterWeight = opts.velocityFilterWeight || 0.7; + this.minWidth = opts.minWidth || 0.5; + this.maxWidth = opts.maxWidth || 2.5; + this.throttle = 'throttle' in opts ? opts.throttle : 16; // in miliseconds + + if (this.throttle) { + this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); + } else { + this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; + } + + this.dotSize = opts.dotSize || function() { + return (this.minWidth + this.maxWidth) / 2; + }; + this.penColor = opts.penColor || 'black'; //签字板的颜色 + this.backgroundColor = opts.backgroundColor || 'rgba(0,0,0,0)'; + this.onBegin = opts.onBegin; + this.onEnd = opts.onEnd; + this.devicePixelRatio = opts.devicePixelRatio || 1; + this.lineWidth = opts.lineWidth || 1; //签字板的粗细 + this._canvas = canvas; + this._ctx = canvas; + this.clear(); + + // We need add these inline so they are available to unbind while still having + // access to 'self' we could use _.bind but it's not worth adding a dependency. + + this._handleTouchStart = function(event, data) { + self.penColor = data.penColor || self.penColor; + self.lineWidth = data.lineWidth || self.lineWidth; + if (event.touches.length === 1) { + var touch = event.changedTouches[0]; + self._strokeBegin(touch); + } + }; + + this._handleTouchMove = function(event) { + // Prevent scrolling. + var touch = event.touches[0]; + self._strokeMoveUpdate(touch); + }; + + this._handleTouchEnd = function(event) { + self._strokeEnd(event); + }; + this.clear = function() { + var ctx = this._ctx; + var canvas = this._canvas; + + ctx.fillStyle = this.backgroundColor; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.draw() + this._data = []; + this._reset(); + this._isEmpty = true; + }; + } + + // Public methods + SignaturePad.prototype.clear = function() { + var ctx = this._ctx; + var canvas = this._canvas; + + ctx.fillStyle = this.backgroundColor; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.fillRect(0, 0, canvas.width, canvas.height); + + this._data = []; + this._reset(); + this._isEmpty = true; + }; + + SignaturePad.prototype.isEmpty = function() { + return this._isEmpty; + }; + + // Private methods + SignaturePad.prototype._strokeBegin = function(event) { + this._data.push([]); + this._reset(); + this._strokeUpdate(event); + + if (typeof this.onBegin === 'function') { + this.onBegin(event); + } + }; + + SignaturePad.prototype._strokeUpdate = function(event) { + var x = event.x; + var y = event.y; + + var point = this._createPoint(x, y); + + var _addPoint = this._addPoint(point), + curve = _addPoint.curve, + widths = _addPoint.widths; + + if (curve && widths) { + this._drawCurve(curve, widths.start, widths.end); + } + this._data[this._data.length - 1].push({ + x: point.x, + y: point.y, + time: point.time, + color: this.penColor + }); + }; + + SignaturePad.prototype._strokeEnd = function(event) { + var canDrawCurve = this.points.length > 2; + var point = this.points[0]; + + if (!canDrawCurve && point) { + this._drawDot(point); + } + + if (typeof this.onEnd === 'function') { + this.onEnd(event); + } + }; + + SignaturePad.prototype._reset = function() { + this.points = []; + this._lastVelocity = 0; + this._lastWidth = (this.minWidth + this.maxWidth) / 2; + this._ctx.fillStyle = this.penColor; + }; + + SignaturePad.prototype._createPoint = function(x, y, time) { + var rect = { + left: 10, + top: 10 + }; + return new Point(x - rect.left, y - rect.top, time || new Date().getTime()); + }; + + SignaturePad.prototype._addPoint = function(point) { + var points = this.points; + var tmp = void 0; + + points.push(point); + if (points.length > 2) { + // To reduce the initial lag make it work with 3 points + // by copying the first point to the beginning. + if (points.length === 3) points.unshift(points[0]); + + tmp = this._calculateCurveControlPoints(points[0], points[1], points[2]); + var c2 = tmp.c2; + tmp = this._calculateCurveControlPoints(points[1], points[2], points[3]); + var c3 = tmp.c1; + var curve = new Bezier(points[1], c2, c3, points[2]); + var widths = this._calculateCurveWidths(curve); + // Remove the first element from the list, + // so that we always have no more than 4 points in points array. + points.shift(); + + return { curve: curve, widths: widths }; + } + + return {}; + }; + + SignaturePad.prototype._calculateCurveControlPoints = function(s1, s2, s3) { + var dx1 = s1.x - s2.x; + var dy1 = s1.y - s2.y; + var dx2 = s2.x - s3.x; + var dy2 = s2.y - s3.y; + var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 }; + var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0 }; + + var l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); + var l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); + + var dxm = m1.x - m2.x; + var dym = m1.y - m2.y; + + var k = l2 / (l1 + l2); + var cm = { x: m2.x + dxm * k, y: m2.y + dym * k }; + + var tx = s2.x - cm.x; + var ty = s2.y - cm.y; + + return { + c1: new Point(m1.x + tx, m1.y + ty), + c2: new Point(m2.x + tx, m2.y + ty) + }; + }; + + SignaturePad.prototype._calculateCurveWidths = function(curve) { + var startPoint = curve.startPoint; + var endPoint = curve.endPoint; + var widths = { start: null, end: null }; + + var velocity = this.velocityFilterWeight * endPoint.velocityFrom(startPoint) + (1 - this.velocityFilterWeight) * this._lastVelocity; + + var newWidth = this._strokeWidth(velocity); + + widths.start = this._lastWidth; + widths.end = newWidth; + + this._lastVelocity = velocity; + this._lastWidth = newWidth; + + return widths; + }; + + SignaturePad.prototype._strokeWidth = function(velocity) { + return Math.max(this.maxWidth / (velocity + 1), this.minWidth); + }; + + SignaturePad.prototype._drawPoint = function(x, y, size) { + var ctx = this._ctx; + var lineWidth = this.lineWidth; + ctx.moveTo(x, y); + ctx.arc(x, y, size * lineWidth, 0, 2 * Math.PI, false); + this._isEmpty = false; + }; + + SignaturePad.prototype._drawCurve = function(curve, startWidth, endWidth) { + var ctx = this._ctx; + var widthDelta = endWidth - startWidth; + var drawSteps = Math.floor(curve.length()); + + ctx.beginPath(); + for (var i = 0; i < drawSteps; i += 1) { + // Calculate the Bezier (x, y) coordinate for this step. + var t = i / drawSteps; + var tt = t * t; + var ttt = tt * t; + var u = 1 - t; + var uu = u * u; + var uuu = uu * u; + + var x = uuu * curve.startPoint.x; + x += 3 * uu * t * curve.control1.x; + x += 3 * u * tt * curve.control2.x; + x += ttt * curve.endPoint.x; + + var y = uuu * curve.startPoint.y; + y += 3 * uu * t * curve.control1.y; + y += 3 * u * tt * curve.control2.y; + y += ttt * curve.endPoint.y; + + var width = startWidth + ttt * widthDelta; + this._drawPoint(x, y, width); + } + var penColor = this.penColor; + ctx.closePath(); + ctx.setStrokeStyle(penColor); + ctx.setFillStyle(penColor); + ctx.fill(); + ctx.stroke(); + ctx.draw(true) + }; + + SignaturePad.prototype._drawDot = function(point) { + var ctx = this._ctx; + var width = typeof this.dotSize === 'function' ? this.dotSize() : this.dotSize; + var penColor = this.penColor; + ctx.beginPath(); + this._drawPoint(point.x, point.y, width); + ctx.closePath(); + ctx.setStrokeStyle(penColor); + ctx.setFillStyle(penColor); + ctx.fill(); + ctx.stroke(); + ctx.draw(true) + }; + + SignaturePad.prototype.toData = function() { + return this._data; + }; + + return SignaturePad; + +}))); \ No newline at end of file