1(function (root, factory) { 2 if (typeof define === 'function' && define.amd) { 3 // AMD. Register as an anonymous module unless amdModuleId is set 4 define([], function () { 5 return (root['SignaturePad'] = factory()); 6 }); 7 } else if (typeof exports === 'object') { 8 // Node. Does not work with strict CommonJS, but 9 // only CommonJS-like environments that support module.exports, 10 // like Node. 11 module.exports = factory(); 12 } else { 13 root['SignaturePad'] = factory(); 14 } 15}(this, function () { 16 17/*! 18 * Signature Pad v1.5.3 19 * https://github.com/szimek/signature_pad 20 * 21 * Copyright 2016 Szymon Nowak 22 * Released under the MIT license 23 * 24 * The main idea and some parts of the code (e.g. drawing variable width Bézier curve) are taken from: 25 * http://corner.squareup.com/2012/07/smoother-signatures.html 26 * 27 * Implementation of interpolation using cubic Bézier curves is taken from: 28 * http://benknowscode.wordpress.com/2012/09/14/path-interpolation-using-cubic-bezier-and-control-point-estimation-in-javascript 29 * 30 * Algorithm for approximated length of a Bézier curve is taken from: 31 * http://www.lemoda.net/maths/bezier-length/index.html 32 * 33 */ 34var SignaturePad = (function (document) { 35 "use strict"; 36 37 var SignaturePad = function (canvas, options) { 38 var self = this, 39 opts = options || {}; 40 41 this.velocityFilterWeight = opts.velocityFilterWeight || 0.7; 42 this.minWidth = opts.minWidth || 0.5; 43 this.maxWidth = opts.maxWidth || 2.5; 44 this.dotSize = opts.dotSize || function () { 45 return (this.minWidth + this.maxWidth) / 2; 46 }; 47 this.penColor = opts.penColor || "black"; 48 this.backgroundColor = opts.backgroundColor || "rgba(0,0,0,0)"; 49 this.onEnd = opts.onEnd; 50 this.onBegin = opts.onBegin; 51 52 this._canvas = canvas; 53 this._ctx = canvas.getContext("2d"); 54 this.clear(); 55 56 // we need add these inline so they are available to unbind while still having 57 // access to 'self' we could use _.bind but it's not worth adding a dependency 58 this._handleMouseDown = function (event) { 59 if (event.which === 1) { 60 self._mouseButtonDown = true; 61 self._strokeBegin(event); 62 } 63 }; 64 65 this._handleMouseMove = function (event) { 66 if (self._mouseButtonDown) { 67 self._strokeUpdate(event); 68 } 69 }; 70 71 this._handleMouseUp = function (event) { 72 if (event.which === 1 && self._mouseButtonDown) { 73 self._mouseButtonDown = false; 74 self._strokeEnd(event); 75 } 76 }; 77 78 this._handleTouchStart = function (event) { 79 if (event.targetTouches.length == 1) { 80 var touch = event.changedTouches[0]; 81 self._strokeBegin(touch); 82 } 83 }; 84 85 this._handleTouchMove = function (event) { 86 // Prevent scrolling. 87 event.preventDefault(); 88 89 var touch = event.targetTouches[0]; 90 self._strokeUpdate(touch); 91 }; 92 93 this._handleTouchEnd = function (event) { 94 var wasCanvasTouched = event.target === self._canvas; 95 if (wasCanvasTouched) { 96 event.preventDefault(); 97 self._strokeEnd(event); 98 } 99 }; 100 101 this._handleMouseEvents(); 102 this._handleTouchEvents(); 103 }; 104 105 SignaturePad.prototype.clear = function () { 106 var ctx = this._ctx, 107 canvas = this._canvas; 108 109 ctx.fillStyle = this.backgroundColor; 110 ctx.clearRect(0, 0, canvas.width, canvas.height); 111 ctx.fillRect(0, 0, canvas.width, canvas.height); 112 this._reset(); 113 }; 114 115 SignaturePad.prototype.toDataURL = function (imageType, quality) { 116 var canvas = this._canvas; 117 return canvas.toDataURL.apply(canvas, arguments); 118 }; 119 120 SignaturePad.prototype.fromDataURL = function (dataUrl) { 121 var self = this, 122 image = new Image(), 123 ratio = window.devicePixelRatio || 1, 124 width = this._canvas.width / ratio, 125 height = this._canvas.height / ratio; 126 127 this._reset(); 128 image.src = dataUrl; 129 image.onload = function () { 130 self._ctx.drawImage(image, 0, 0, width, height); 131 }; 132 this._isEmpty = false;
133 }; 134 135 SignaturePad.prototype._strokeUpdate = function (event) { 136 var point = this._createPoint(event); 137 this._addPoint(point); 138 }; 139 140 SignaturePad.prototype._strokeBegin = function (event) { 141 this._reset(); 142 this._strokeUpdate(event); 143 if (typeof this.onBegin === 'function') { 144 this.onBegin(event); 145 } 146 }; 147 148 SignaturePad.prototype._strokeDraw = function (point) { 149 var ctx = this._ctx, 150 dotSize = typeof(this.dotSize) === 'function' ? this.dotSize() : this.dotSize; 151 152 ctx.beginPath(); 153 this._drawPoint(point.x, point.y, dotSize); 154 ctx.closePath(); 155 ctx.fill(); 156 }; 157 158 SignaturePad.prototype._strokeEnd = function (event) { 159 var canDrawCurve = this.points.length > 2, 160 point = this.points[0]; 161 162 if (!canDrawCurve && point) { 163 this._strokeDraw(point); 164 } 165 if (typeof this.onEnd === 'function') { 166 this.onEnd(event); 167 } 168 }; 169 170 SignaturePad.prototype._handleMouseEvents = function () { 171 this._mouseButtonDown = false; 172 173 this._canvas.addEventListener("mousedown", this._handleMouseDown); 174 this._canvas.addEventListener("mousemove", this._handleMouseMove); 175 document.addEventListener("mouseup", this._handleMouseUp); 176 }; 177 178 SignaturePad.prototype._handleTouchEvents = function () { 179 // Pass touch events to canvas element on mobile IE11 and Edge. 180 this._canvas.style.msTouchAction = 'none'; 181 this._canvas.style.touchAction = 'none'; 182 183 this._canvas.addEventListener("touchstart", this._handleTouchStart); 184 this._canvas.addEventListener("touchmove", this._handleTouchMove); 185 this._canvas.addEventListener("touchend", this._handleTouchEnd); 186 }; 187 188 SignaturePad.prototype.on = function () { 189 this._handleMouseEvents(); 190 this._handleTouchEvents(); 191 }; 192 193 SignaturePad.prototype.off = function () { 194 this._canvas.removeEventListener("mousedown", this._handleMouseDown); 195 this._canvas.removeEventListener("mousemove", this._handleMouseMove); 196 document.removeEventListener("mouseup", this._handleMouseUp); 197 198 this._canvas.removeEventListener("touchstart", this._handleTouchStart); 199 this._canvas.removeEventListener("touchmove", this._handleTouchMove); 200 this._canvas.removeEventListener("touchend", this._handleTouchEnd); 201 }; 202 203 SignaturePad.prototype.isEmpty = function () { 204 return this._isEmpty; 205 }; 206 207 SignaturePad.prototype._reset = function () { 208 this.points = []; 209 this._lastVelocity = 0; 210 this._lastWidth = (this.minWidth + this.maxWidth) / 2; 211 this._isEmpty = true; 212 this._ctx.fillStyle = this.penColor; 213 }; 214 215 SignaturePad.prototype._createPoint = function (event) { 216 var rect = this._canvas.getBoundingClientRect(); 217 return new Point( 218 event.clientX - rect.left, 219 event.clientY - rect.top 220 ); 221 }; 222 223 SignaturePad.prototype._addPoint = function (point) { 224 var points = this.points, 225 c2, c3, 226 curve, tmp; 227 228 points.push(point); 229 230 if (points.length > 2) { 231 // To reduce the initial lag make it work with 3 points 232 // by copying the first point to the beginning. 233 if (points.length === 3) points.unshift(points[0]); 234 235 tmp = this._calculateCurveControlPoints(points[0], points[1], points[2]); 236 c2 = tmp.c2; 237 tmp = this._calculateCurveControlPoints(points[1], points[2], points[3]); 238 c3 = tmp.c1; 239 curve = new Bezier(points[1], c2, c3, points[2]); 240 this._addCurve(curve); 241 242 // Remove the first element from the list, 243 // so that we always have no more than 4 points in points array. 244 points.shift(); 245 } 246 }; 247 248 SignaturePad.prototype._calculateCurveControlPoints = function (s1, s2, s3) { 249 var dx1 = s1.x - s2.x, dy1 = s1.y - s2.y, 250 dx2 = s2.x - s3.x, dy2 = s2.y - s3.y, 251
252 m1 = {x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0}, 253 m2 = {x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0}, 254 255 l1 = Math.sqrt(dx1*dx1 + dy1*dy1), 256 l2 = Math.sqrt(dx2*dx2 + dy2*dy2), 257 258 dxm = (m1.x - m2.x), 259 dym = (m1.y - m2.y), 260 261 k = l2 / (l1 + l2), 262 cm = {x: m2.x + dxm*k, y: m2.y + dym*k}, 263 264 tx = s2.x - cm.x, 265 ty = s2.y - cm.y; 266 267 return { 268 c1: new Point(m1.x + tx, m1.y + ty), 269 c2: new Point(m2.x + tx, m2.y + ty) 270 }; 271 }; 272 273 SignaturePad.prototype._addCurve = function (curve) { 274 var startPoint = curve.startPoint, 275 endPoint = curve.endPoint, 276 velocity, newWidth; 277 278 velocity = endPoint.velocityFrom(startPoint); 279 velocity = this.velocityFilterWeight * velocity 280 + (1 - this.velocityFilterWeight) * this._lastVelocity; 281 282 newWidth = this._strokeWidth(velocity); 283 this._drawCurve(curve, this._lastWidth, newWidth); 284 285 this._lastVelocity = velocity; 286 this._lastWidth = newWidth; 287 }; 288 289 SignaturePad.prototype._drawPoint = function (x, y, size) { 290 var ctx = this._ctx; 291 292 ctx.moveTo(x, y); 293 ctx.arc(x, y, size, 0, 2 * Math.PI, false); 294 this._isEmpty = false; 295 }; 296 297 SignaturePad.prototype._drawCurve = function (curve, startWidth, endWidth) { 298 var ctx = this._ctx, 299 widthDelta = endWidth - startWidth, 300 drawSteps, width, i, t, tt, ttt, u, uu, uuu, x, y; 301 302 drawSteps = Math.floor(curve.length()); 303 ctx.beginPath(); 304 for (i = 0; i < drawSteps; i++) { 305 // Calculate the Bezier (x, y) coordinate for this step. 306 t = i / drawSteps; 307 tt = t * t; 308 ttt = tt * t; 309 u = 1 - t; 310 uu = u * u; 311 uuu = uu * u; 312 313 x = uuu * curve.startPoint.x; 314 x += 3 * uu * t * curve.control1.x; 315 x += 3 * u * tt * curve.control2.x; 316 x += ttt * curve.endPoint.x; 317 318 y = uuu * curve.startPoint.y; 319 y += 3 * uu * t * curve.control1.y; 320 y += 3 * u * tt * curve.control2.y; 321 y += ttt * curve.endPoint.y; 322 323 width = startWidth + ttt * widthDelta; 324 this._drawPoint(x, y, width); 325 } 326 ctx.closePath(); 327 ctx.fill(); 328 }; 329 330 SignaturePad.prototype._strokeWidth = function (velocity) { 331 return Math.max(this.maxWidth / (velocity + 1), this.minWidth); 332 }; 333 334 335 var Point = function (x, y, time) { 336 this.x = x; 337 this.y = y; 338 this.time = time || new Date().getTime(); 339 }; 340 341 Point.prototype.velocityFrom = function (start) { 342 return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 1; 343 }; 344 345 Point.prototype.distanceTo = function (start) { 346 return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2)); 347 }; 348 349 var Bezier = function (startPoint, control1, control2, endPoint) { 350 this.startPoint = startPoint; 351 this.control1 = control1; 352 this.control2 = control2; 353 this.endPoint = endPoint; 354 }; 355 356 // Returns approximated length. 357 Bezier.prototype.length = function () { 358 var steps = 10, 359 length = 0, 360 i, t, cx, cy, px, py, xdiff, ydiff; 361 362 for (i = 0; i <= steps; i++) { 363 t = i / steps; 364 cx = this._point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x); 365 cy = this._point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y); 366 if (i > 0) { 367 xdiff = cx - px; 368 ydiff = cy - py; 369 length += Math.sqrt(xdiff * xdiff + ydiff * ydiff); 370 } 371 px = cx; 372 py = cy; 373 } 374 return length; 375 }; 376 377 Bezier.prototype._point = function (t, start, c1, c2, end) { 378 return start * (1.0 - t) * (1.0 - t) * (1.0 - t) 379 + 3.0 * c1 * (1.0 - t) * (1.0 - t) * t 380 + 3.0 * c2 * (1.0 - t) * t * t 381 + end * t * t * t; 382 }; 383 384 return SignaturePad; 385})(document); 386 387return SignaturePad; 388 389}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.