智慧申请系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
15 KiB

  1. /*!
  2. * Signature Pad v3.0.0-beta.3 | https://github.com/szimek/signature_pad
  3. * (c) 2018 Szymon Nowak | Released under the MIT license
  4. */
  5. (function (global, factory) {
  6. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  7. typeof define === 'function' && define.amd ? define(factory) :
  8. (global.SignaturePad = factory());
  9. }(this, (function () { 'use strict';
  10. var Point = (function () {
  11. function Point(x, y, time) {
  12. this.x = x;
  13. this.y = y;
  14. this.time = time || Date.now();
  15. }
  16. Point.prototype.distanceTo = function (start) {
  17. return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2));
  18. };
  19. Point.prototype.equals = function (other) {
  20. return this.x === other.x && this.y === other.y && this.time === other.time;
  21. };
  22. Point.prototype.velocityFrom = function (start) {
  23. return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 0;
  24. };
  25. return Point;
  26. }());
  27. var Bezier = (function () {
  28. function Bezier(startPoint, control2, control1, endPoint, startWidth, endWidth) {
  29. this.startPoint = startPoint;
  30. this.control2 = control2;
  31. this.control1 = control1;
  32. this.endPoint = endPoint;
  33. this.startWidth = startWidth;
  34. this.endWidth = endWidth;
  35. }
  36. Bezier.fromPoints = function (points, widths) {
  37. var c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2;
  38. var c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1;
  39. return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end);
  40. };
  41. Bezier.calculateControlPoints = function (s1, s2, s3) {
  42. var dx1 = s1.x - s2.x;
  43. var dy1 = s1.y - s2.y;
  44. var dx2 = s2.x - s3.x;
  45. var dy2 = s2.y - s3.y;
  46. var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 };
  47. var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0 };
  48. var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));
  49. var l2 = Math.sqrt((dx2 * dx2) + (dy2 * dy2));
  50. var dxm = (m1.x - m2.x);
  51. var dym = (m1.y - m2.y);
  52. var k = l2 / (l1 + l2);
  53. var cm = { x: m2.x + (dxm * k), y: m2.y + (dym * k) };
  54. var tx = s2.x - cm.x;
  55. var ty = s2.y - cm.y;
  56. return {
  57. c1: new Point(m1.x + tx, m1.y + ty),
  58. c2: new Point(m2.x + tx, m2.y + ty)
  59. };
  60. };
  61. Bezier.prototype.length = function () {
  62. var steps = 10;
  63. var length = 0;
  64. var px;
  65. var py;
  66. for (var i = 0; i <= steps; i += 1) {
  67. var t = i / steps;
  68. var cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x);
  69. var cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y);
  70. if (i > 0) {
  71. var xdiff = cx - px;
  72. var ydiff = cy - py;
  73. length += Math.sqrt((xdiff * xdiff) + (ydiff * ydiff));
  74. }
  75. px = cx;
  76. py = cy;
  77. }
  78. return length;
  79. };
  80. Bezier.prototype.point = function (t, start, c1, c2, end) {
  81. return (start * (1.0 - t) * (1.0 - t) * (1.0 - t))
  82. + (3.0 * c1 * (1.0 - t) * (1.0 - t) * t)
  83. + (3.0 * c2 * (1.0 - t) * t * t)
  84. + (end * t * t * t);
  85. };
  86. return Bezier;
  87. }());
  88. function throttle(fn, wait) {
  89. if (wait === void 0) { wait = 250; }
  90. var previous = 0;
  91. var timeout = null;
  92. var result;
  93. var storedContext;
  94. var storedArgs;
  95. var later = function () {
  96. previous = Date.now();
  97. timeout = null;
  98. result = fn.apply(storedContext, storedArgs);
  99. if (!timeout) {
  100. storedContext = null;
  101. storedArgs = [];
  102. }
  103. };
  104. return function () {
  105. var args = [];
  106. for (var _i = 0; _i < arguments.length; _i++) {
  107. args[_i] = arguments[_i];
  108. }
  109. var now = Date.now();
  110. var remaining = wait - (now - previous);
  111. storedContext = this;
  112. storedArgs = args;
  113. if (remaining <= 0 || remaining > wait) {
  114. if (timeout) {
  115. clearTimeout(timeout);
  116. timeout = null;
  117. }
  118. previous = now;
  119. result = fn.apply(storedContext, storedArgs);
  120. if (!timeout) {
  121. storedContext = null;
  122. storedArgs = [];
  123. }
  124. }
  125. else if (!timeout) {
  126. timeout = setTimeout(later, remaining);
  127. }
  128. return result;
  129. };
  130. }
  131. var SignaturePad = (function () {
  132. function SignaturePad(canvas, options) {
  133. if (options === void 0) { options = {}; }
  134. var _this = this;
  135. this.canvas = canvas;
  136. this.options = options;
  137. this._handleTouchStart = function (event) {
  138. if (event.touches.length === 1) {
  139. var touch = event.changedTouches[0];
  140. _this._strokeBegin(touch);
  141. }
  142. };
  143. this._handleTouchMove = function (event) {
  144. var touch = event.touches[0];
  145. _this._strokeMoveUpdate(touch);
  146. };
  147. this._handleTouchEnd = function (event) {
  148. var wasCanvasTouched = event.target === _this.canvas;
  149. if (wasCanvasTouched) {
  150. event.preventDefault();
  151. var touch = event.changedTouches[0];
  152. _this._strokeEnd(touch);
  153. }
  154. };
  155. this.velocityFilterWeight = options.velocityFilterWeight || 0.7;
  156. this.minWidth = options.minWidth || 0.5;
  157. this.maxWidth = options.maxWidth || 2.5;
  158. this.throttle = ('throttle' in options ? options.throttle : 16);
  159. this.minDistance = ('minDistance' in options ? options.minDistance : 5);
  160. if (this.throttle) {
  161. this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle);
  162. }
  163. else {
  164. this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate;
  165. }
  166. this.dotSize = options.dotSize || function () {
  167. return (this.minWidth + this.maxWidth) / 2;
  168. };
  169. this.penColor = options.penColor || 'black';
  170. this.backgroundColor = options.backgroundColor || 'rgba(0,0,0,0)';
  171. this.onBegin = options.onBegin;
  172. this.onEnd = options.onEnd;
  173. this._ctx = canvas.getContext('2d');
  174. this.clear();
  175. }
  176. SignaturePad.prototype.clear = function () {
  177. var ctx = this._ctx;
  178. var canvas = this.canvas;
  179. ctx.fillStyle = this.backgroundColor;
  180. ctx.clearRect(0, 0, canvas.width, canvas.height);
  181. ctx.fillRect(0, 0, canvas.width, canvas.height);
  182. this._data = [];
  183. this._reset();
  184. this._isEmpty = true;
  185. };
  186. SignaturePad.prototype.fromDataURL = function (dataUrl, options, callback) {
  187. var _this = this;
  188. if (options === void 0) { options = {}; }
  189. var image = new Image();
  190. var ratio = options.ratio || 1;
  191. var width = options.width || (this.canvas.width / ratio);
  192. var height = options.height || (this.canvas.height / ratio);
  193. this._reset();
  194. image.onload = function () {
  195. _this._ctx.drawImage(image, 0, 0, width, height);
  196. if (callback) {
  197. callback();
  198. }
  199. };
  200. image.onerror = function (error) {
  201. if (callback) {
  202. callback(error);
  203. }
  204. };
  205. image.src = dataUrl;
  206. this._isEmpty = false;
  207. };
  208. SignaturePad.prototype.toDataURL = function (type, encoderOptions) {
  209. if (type === void 0) { type = 'image/png'; }
  210. return this.canvas.toDataURL(type, encoderOptions);
  211. };
  212. SignaturePad.prototype.isEmpty = function () {
  213. return this._isEmpty;
  214. };
  215. SignaturePad.prototype.fromData = function (pointGroups) {
  216. var _this = this;
  217. this.clear();
  218. this._fromData(pointGroups, function (_a) {
  219. var color = _a.color, curve = _a.curve;
  220. return _this._drawCurve({ color: color, curve: curve });
  221. }, function (_a) {
  222. var color = _a.color, point = _a.point;
  223. return _this._drawDot({ color: color, point: point });
  224. });
  225. this._data = pointGroups;
  226. };
  227. SignaturePad.prototype.toData = function () {
  228. return this._data;
  229. };
  230. SignaturePad.prototype._strokeBegin = function (event) {
  231. var newPointGroup = {
  232. color: this.penColor,
  233. points: []
  234. };
  235. this._data.push(newPointGroup);
  236. this._reset();
  237. this._strokeUpdate(event);
  238. if (typeof this.onBegin === 'function') {
  239. this.onBegin(event);
  240. }
  241. };
  242. SignaturePad.prototype._strokeUpdate = function (event) {
  243. var x = event.x;
  244. var y = event.y;
  245. var point = this._createPoint(x, y);
  246. var lastPointGroup = this._data[this._data.length - 1];
  247. var lastPoints = lastPointGroup.points;
  248. var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1];
  249. var isLastPointTooClose = lastPoint ? point.distanceTo(lastPoint) <= this.minDistance : false;
  250. var color = lastPointGroup.color;
  251. if (!lastPoint || !(lastPoint && isLastPointTooClose)) {
  252. var curve = this._addPoint(point);
  253. if (!lastPoint) {
  254. this._drawDot({ color: color, point: point });
  255. }
  256. else if (curve) {
  257. this._drawCurve({ color: color, curve: curve });
  258. }
  259. lastPoints.push({
  260. time: point.time,
  261. x: point.x,
  262. y: point.y
  263. });
  264. }
  265. };
  266. SignaturePad.prototype._strokeEnd = function (event) {
  267. this._strokeUpdate(event);
  268. if (typeof this.onEnd === 'function') {
  269. this.onEnd(event);
  270. }
  271. };
  272. SignaturePad.prototype._reset = function () {
  273. this._lastPoints = [];
  274. this._lastVelocity = 0;
  275. this._lastWidth = (this.minWidth + this.maxWidth) / 2;
  276. this._ctx.fillStyle = this.penColor;
  277. };
  278. SignaturePad.prototype._createPoint = function (x, y) {
  279. return new Point(x, y, new Date().getTime());
  280. };
  281. SignaturePad.prototype._addPoint = function (point) {
  282. var _lastPoints = this._lastPoints;
  283. _lastPoints.push(point);
  284. if (_lastPoints.length > 2) {
  285. if (_lastPoints.length === 3) {
  286. _lastPoints.unshift(_lastPoints[0]);
  287. }
  288. var widths = this._calculateCurveWidths(_lastPoints[1], _lastPoints[2]);
  289. var curve = Bezier.fromPoints(_lastPoints, widths);
  290. _lastPoints.shift();
  291. return curve;
  292. }
  293. return null;
  294. };
  295. SignaturePad.prototype._calculateCurveWidths = function (startPoint, endPoint) {
  296. var velocity = (this.velocityFilterWeight * endPoint.velocityFrom(startPoint))
  297. + ((1 - this.velocityFilterWeight) * this._lastVelocity);
  298. var newWidth = this._strokeWidth(velocity);
  299. var widths = {
  300. end: newWidth,
  301. start: this._lastWidth
  302. };
  303. this._lastVelocity = velocity;
  304. this._lastWidth = newWidth;
  305. return widths;
  306. };
  307. SignaturePad.prototype._strokeWidth = function (velocity) {
  308. return Math.max(this.maxWidth / (velocity + 1), this.minWidth);
  309. };
  310. SignaturePad.prototype._drawCurveSegment = function (x, y, width) {
  311. var ctx = this._ctx;
  312. ctx.moveTo(x, y);
  313. ctx.arc(x, y, width, 0, 2 * Math.PI, false);
  314. this._isEmpty = false;
  315. };
  316. SignaturePad.prototype._drawCurve = function (_a) {
  317. var color = _a.color, curve = _a.curve;
  318. var ctx = this._ctx;
  319. var widthDelta = curve.endWidth - curve.startWidth;
  320. var drawSteps = Math.floor(curve.length()) * 2;
  321. ctx.beginPath();
  322. ctx.fillStyle = color;
  323. for (var i = 0; i < drawSteps; i += 1) {
  324. var t = i / drawSteps;
  325. var tt = t * t;
  326. var ttt = tt * t;
  327. var u = 1 - t;
  328. var uu = u * u;
  329. var uuu = uu * u;
  330. var x = uuu * curve.startPoint.x;
  331. x += 3 * uu * t * curve.control1.x;
  332. x += 3 * u * tt * curve.control2.x;
  333. x += ttt * curve.endPoint.x;
  334. var y = uuu * curve.startPoint.y;
  335. y += 3 * uu * t * curve.control1.y;
  336. y += 3 * u * tt * curve.control2.y;
  337. y += ttt * curve.endPoint.y;
  338. var width = curve.startWidth + (ttt * widthDelta);
  339. this._drawCurveSegment(x, y, width);
  340. }
  341. ctx.closePath();
  342. ctx.fill();
  343. };
  344. SignaturePad.prototype._drawDot = function (_a) {
  345. var color = _a.color, point = _a.point;
  346. var ctx = this._ctx;
  347. var width = 1;
  348. ctx.beginPath();
  349. this._drawCurveSegment(point.x, point.y, width);
  350. ctx.closePath();
  351. ctx.fillStyle = color;
  352. ctx.fill();
  353. };
  354. SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) {
  355. for (var _i = 0, pointGroups_1 = pointGroups; _i < pointGroups_1.length; _i++) {
  356. var group = pointGroups_1[_i];
  357. var color = group.color, points = group.points;
  358. if (points.length > 1) {
  359. for (var j = 0; j < points.length; j += 1) {
  360. var basicPoint = points[j];
  361. var point = new Point(basicPoint.x, basicPoint.y, basicPoint.time);
  362. this.penColor = color;
  363. if (j === 0) {
  364. this._reset();
  365. }
  366. var curve = this._addPoint(point);
  367. if (curve) {
  368. drawCurve({ color: color, curve: curve });
  369. }
  370. }
  371. }
  372. else {
  373. this._reset();
  374. drawDot({
  375. color: color,
  376. point: points[0]
  377. });
  378. }
  379. }
  380. };
  381. return SignaturePad;
  382. }());
  383. return SignaturePad;
  384. })));