signature.js 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Signature = {}));
  5. }(this, (function (exports) { 'use strict';
  6. function ownKeys(object, enumerableOnly) {
  7. var keys = Object.keys(object);
  8. if (Object.getOwnPropertySymbols) {
  9. var symbols = Object.getOwnPropertySymbols(object);
  10. enumerableOnly && (symbols = symbols.filter(function (sym) {
  11. return Object.getOwnPropertyDescriptor(object, sym).enumerable;
  12. })), keys.push.apply(keys, symbols);
  13. }
  14. return keys;
  15. }
  16. function _objectSpread2(target) {
  17. for (var i = 1; i < arguments.length; i++) {
  18. var source = null != arguments[i] ? arguments[i] : {};
  19. i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
  20. _defineProperty(target, key, source[key]);
  21. }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
  22. Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
  23. });
  24. }
  25. return target;
  26. }
  27. function _typeof(obj) {
  28. "@babel/helpers - typeof";
  29. return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
  30. return typeof obj;
  31. } : function (obj) {
  32. return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  33. }, _typeof(obj);
  34. }
  35. function _classCallCheck(instance, Constructor) {
  36. if (!(instance instanceof Constructor)) {
  37. throw new TypeError("Cannot call a class as a function");
  38. }
  39. }
  40. function _defineProperties(target, props) {
  41. for (var i = 0; i < props.length; i++) {
  42. var descriptor = props[i];
  43. descriptor.enumerable = descriptor.enumerable || false;
  44. descriptor.configurable = true;
  45. if ("value" in descriptor) descriptor.writable = true;
  46. Object.defineProperty(target, descriptor.key, descriptor);
  47. }
  48. }
  49. function _createClass(Constructor, protoProps, staticProps) {
  50. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  51. if (staticProps) _defineProperties(Constructor, staticProps);
  52. Object.defineProperty(Constructor, "prototype", {
  53. writable: false
  54. });
  55. return Constructor;
  56. }
  57. function _defineProperty(obj, key, value) {
  58. if (key in obj) {
  59. Object.defineProperty(obj, key, {
  60. value: value,
  61. enumerable: true,
  62. configurable: true,
  63. writable: true
  64. });
  65. } else {
  66. obj[key] = value;
  67. }
  68. return obj;
  69. }
  70. function _inherits(subClass, superClass) {
  71. if (typeof superClass !== "function" && superClass !== null) {
  72. throw new TypeError("Super expression must either be null or a function");
  73. }
  74. subClass.prototype = Object.create(superClass && superClass.prototype, {
  75. constructor: {
  76. value: subClass,
  77. writable: true,
  78. configurable: true
  79. }
  80. });
  81. Object.defineProperty(subClass, "prototype", {
  82. writable: false
  83. });
  84. if (superClass) _setPrototypeOf(subClass, superClass);
  85. }
  86. function _getPrototypeOf(o) {
  87. _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
  88. return o.__proto__ || Object.getPrototypeOf(o);
  89. };
  90. return _getPrototypeOf(o);
  91. }
  92. function _setPrototypeOf(o, p) {
  93. _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
  94. o.__proto__ = p;
  95. return o;
  96. };
  97. return _setPrototypeOf(o, p);
  98. }
  99. function _isNativeReflectConstruct() {
  100. if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  101. if (Reflect.construct.sham) return false;
  102. if (typeof Proxy === "function") return true;
  103. try {
  104. Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
  105. return true;
  106. } catch (e) {
  107. return false;
  108. }
  109. }
  110. function _assertThisInitialized(self) {
  111. if (self === void 0) {
  112. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  113. }
  114. return self;
  115. }
  116. function _possibleConstructorReturn(self, call) {
  117. if (call && (typeof call === "object" || typeof call === "function")) {
  118. return call;
  119. } else if (call !== void 0) {
  120. throw new TypeError("Derived constructors may only return object or undefined");
  121. }
  122. return _assertThisInitialized(self);
  123. }
  124. function _createSuper(Derived) {
  125. var hasNativeReflectConstruct = _isNativeReflectConstruct();
  126. return function _createSuperInternal() {
  127. var Super = _getPrototypeOf(Derived),
  128. result;
  129. if (hasNativeReflectConstruct) {
  130. var NewTarget = _getPrototypeOf(this).constructor;
  131. result = Reflect.construct(Super, arguments, NewTarget);
  132. } else {
  133. result = Super.apply(this, arguments);
  134. }
  135. return _possibleConstructorReturn(this, result);
  136. };
  137. }
  138. var isObject = function isObject(value) {
  139. /**
  140. * isObject({}) => true
  141. * isObject([1, 2, 3]) => true
  142. * isObject(Function) => true
  143. * isObject(null) => false
  144. */
  145. var type = _typeof(value);
  146. return value !== null && type === 'object' || type === 'function';
  147. };
  148. var toString = {}.toString;
  149. var isType = function isType(value, type) {
  150. return toString.call(value) === '[object ' + type + ']';
  151. };
  152. var isString = function isString(str) {
  153. return isType(str, 'String');
  154. };
  155. var isNumber = function isNumber(value) {
  156. return isType(value, 'Number');
  157. };
  158. var isFunction = function isFunction(value) {
  159. return isType(value, 'Function');
  160. };
  161. var EventEmit = /*#__PURE__*/function () {
  162. function EventEmit() {
  163. _classCallCheck(this, EventEmit);
  164. this.__events = void 0;
  165. this.__events = {};
  166. }
  167. _createClass(EventEmit, [{
  168. key: "on",
  169. value: function on(type, listener) {
  170. if (!type || !listener) {
  171. return;
  172. }
  173. var events = this.__events[type] || [];
  174. events.push(listener);
  175. this.__events[type] = events;
  176. }
  177. }, {
  178. key: "emit",
  179. value: function emit(type, e) {
  180. var _this = this;
  181. if (isObject(type)) {
  182. e = type;
  183. type = e && e.type;
  184. }
  185. if (!type) {
  186. return;
  187. }
  188. var events = this.__events[type];
  189. if (!events || !events.length) {
  190. return;
  191. }
  192. events.forEach(function (listener) {
  193. listener.call(_this, e);
  194. });
  195. }
  196. }, {
  197. key: "off",
  198. value: function off(type, listener) {
  199. var __events = this.__events;
  200. var events = __events[type];
  201. if (!events || !events.length) {
  202. return;
  203. } // 如果没有指定方法,则删除所有项
  204. if (!listener) {
  205. delete __events[type];
  206. return;
  207. } // 删除指定的 listener
  208. for (var i = 0, len = events.length; i < len; i++) {
  209. if (events[i] === listener) {
  210. events.splice(i, 1);
  211. i--;
  212. }
  213. }
  214. }
  215. /* 当前所有的事件 */
  216. }, {
  217. key: "getEvents",
  218. value: function getEvents() {
  219. return this.__events;
  220. }
  221. }]);
  222. return EventEmit;
  223. }();
  224. var CanvasElement = /*#__PURE__*/function (_EventEmit) {
  225. _inherits(CanvasElement, _EventEmit);
  226. var _super = _createSuper(CanvasElement);
  227. // width: number;
  228. // height: number;
  229. function CanvasElement(ctx, attrs) {
  230. var _this;
  231. _classCallCheck(this, CanvasElement);
  232. _this = _super.call(this);
  233. _this.context = void 0;
  234. _this.canvas = void 0;
  235. _this.attrs = void 0;
  236. _this.isCanvasElement = void 0;
  237. _this.context = ctx; // canvas实际的宽高 (width/height) * pixelRatio
  238. // 有可能是 小程序 或 node canvas 创建的 context 对象
  239. _this.canvas = attrs.canvas || ctx.canvas || {
  240. width: attrs.width || 0,
  241. height: attrs.height || 0
  242. }; // this.width = canvas.width || attrs.width || 0;
  243. // this.height = canvas.height || attrs.height || 0;
  244. // this.el = attrs.canvas || {}
  245. _this.attrs = attrs || {}; // 用来标识是CanvasElement实例
  246. _this.isCanvasElement = true;
  247. return _this;
  248. }
  249. _createClass(CanvasElement, [{
  250. key: "width",
  251. get: function get() {
  252. return this.canvas.width;
  253. },
  254. set: function set(v) {
  255. this.canvas.width = v;
  256. }
  257. }, {
  258. key: "height",
  259. get: function get() {
  260. return this.canvas.height;
  261. },
  262. set: function set(v) {
  263. this.canvas.height = v;
  264. }
  265. }, {
  266. key: "getContext",
  267. value: function
  268. /* type */
  269. getContext() {
  270. return this.context;
  271. }
  272. }, {
  273. key: "getBoundingClientRect",
  274. value: function getBoundingClientRect() {
  275. // const width = this.width;
  276. // const height = this.height;
  277. var _ref = this.attrs || {},
  278. _ref$top = _ref.top,
  279. top = _ref$top === void 0 ? 0 : _ref$top,
  280. _ref$right = _ref.right,
  281. right = _ref$right === void 0 ? 0 : _ref$right,
  282. _ref$width = _ref.width,
  283. width = _ref$width === void 0 ? 0 : _ref$width,
  284. _ref$height = _ref.height,
  285. height = _ref$height === void 0 ? 0 : _ref$height,
  286. _ref$left = _ref.left,
  287. left = _ref$left === void 0 ? 0 : _ref$left,
  288. _ref$bottom = _ref.bottom,
  289. bottom = _ref$bottom === void 0 ? 0 : _ref$bottom; // 默认都处理成可视窗口的顶部位置
  290. return {
  291. top: top,
  292. width: width,
  293. right: right,
  294. height: height,
  295. bottom: bottom,
  296. left: left
  297. };
  298. }
  299. }, {
  300. key: "setAttribute",
  301. value: function setAttribute(key, value) {
  302. this.attrs[key] = value;
  303. }
  304. }, {
  305. key: "addEventListener",
  306. value: function addEventListener(type, listener) {
  307. this.on(type, listener);
  308. }
  309. }, {
  310. key: "removeEventListener",
  311. value: function removeEventListener(type, listener) {
  312. this.off(type, listener);
  313. }
  314. }, {
  315. key: "dispatchEvent",
  316. value: function dispatchEvent(type, e) {
  317. this.emit(type, e);
  318. }
  319. }]);
  320. return CanvasElement;
  321. }(EventEmit);
  322. function supportEventListener(canvas) {
  323. if (!canvas) {
  324. return false;
  325. } // 非 HTMLCanvasElement
  326. if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') {
  327. return false;
  328. } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
  329. // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
  330. var support = false;
  331. try {
  332. canvas.addEventListener('eventTest', function () {
  333. support = true;
  334. });
  335. canvas.dispatchEvent(new Event('eventTest'));
  336. } catch (error) {
  337. support = false;
  338. }
  339. return support;
  340. }
  341. var CanvasElement$1 = {
  342. create: function create(ctx, cfg) {
  343. if (!ctx) {
  344. return null;
  345. }
  346. if (supportEventListener(ctx.canvas)) {
  347. return ctx.canvas;
  348. }
  349. return new CanvasElement(ctx, cfg);
  350. }
  351. };
  352. function getPixelRatio() {
  353. return window && window.devicePixelRatio || 1;
  354. }
  355. function getDomById(id) {
  356. if (!id) {
  357. return null;
  358. }
  359. return document.getElementById(id);
  360. }
  361. function getWidth(el) {
  362. var width = getStyle(el, 'width');
  363. if (width === 'auto') {
  364. width = el.offsetWidth;
  365. }
  366. return parseFloat(width);
  367. }
  368. function getHeight(el) {
  369. var height = getStyle(el, 'height');
  370. if (height === 'auto') {
  371. height = el.offsetHeight;
  372. }
  373. return parseFloat(height);
  374. }
  375. function getStyle(el, property) {
  376. try {
  377. return el.currentStyle ? el.currentStyle[property] : document.defaultView && document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
  378. } catch (e) {
  379. var result = {
  380. width: 300,
  381. height: 150
  382. };
  383. return result[property];
  384. }
  385. }
  386. function isCanvasElement(el) {
  387. if (!el || _typeof(el) !== 'object') return false;
  388. if (el.nodeType === 1 && el.nodeName) {
  389. // HTMLCanvasElement
  390. return true;
  391. } // CanvasElement
  392. return !!el.isCanvasElement;
  393. }
  394. function getRelativePosition(point, canvas) {
  395. var canvasDom = canvas.get('el');
  396. if (!canvasDom) return point;
  397. var _canvasDom$getBoundin = canvasDom.getBoundingClientRect(),
  398. _canvasDom$getBoundin2 = _canvasDom$getBoundin.top,
  399. top = _canvasDom$getBoundin2 === void 0 ? 0 : _canvasDom$getBoundin2,
  400. _canvasDom$getBoundin3 = _canvasDom$getBoundin.left,
  401. left = _canvasDom$getBoundin3 === void 0 ? 0 : _canvasDom$getBoundin3;
  402. var paddingLeft = parseFloat(getStyle(canvasDom, 'padding-left')) || 0;
  403. var paddingTop = parseFloat(getStyle(canvasDom, 'padding-top')) || 0;
  404. var mouseX = point.x - left - paddingLeft;
  405. var mouseY = point.y - top - paddingTop;
  406. return {
  407. x: mouseX,
  408. y: mouseY
  409. };
  410. }
  411. function landscapePoint(point, canvas) {
  412. var landscape = canvas.get('landscape');
  413. if (!landscape) {
  414. return point;
  415. }
  416. if (isFunction(landscape)) {
  417. return landscape(point, canvas);
  418. } // 默认顺时针旋转90度
  419. var height = canvas.get('height');
  420. var x = point.y;
  421. var y = height - point.x;
  422. return {
  423. x: x,
  424. y: y
  425. };
  426. }
  427. function convertPoints(ev, canvas) {
  428. var touches = ev.touches; // 认为是mouse事件
  429. if (!touches || !touches.length) {
  430. var point = getRelativePosition({
  431. x: ev.clientX,
  432. y: ev.clientY
  433. }, canvas);
  434. return [landscapePoint(point, canvas)];
  435. } // 单指 touchend 后,touchs 会变空,最后的触点要从changedTouches里拿
  436. if (!touches.length) {
  437. // 为了防止万一,加个空逻辑
  438. touches = ev.changedTouches || [];
  439. }
  440. var points = [];
  441. for (var i = 0, len = touches.length; i < len; i++) {
  442. var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置 pageX, pageY 相对页面
  443. var x = touch.x,
  444. y = touch.y,
  445. clientX = touch.clientX,
  446. clientY = touch.clientY;
  447. var _point = void 0; // 小程序环境会有x,y
  448. if (isNumber(x) || isNumber(y)) {
  449. _point = {
  450. x: x,
  451. y: y
  452. };
  453. } else {
  454. // 浏览器环境再计算下canvas的相对位置
  455. _point = getRelativePosition({
  456. x: clientX,
  457. y: clientY
  458. }, canvas);
  459. }
  460. points.push(landscapePoint(_point, canvas));
  461. }
  462. return points;
  463. }
  464. var convertPoints$1 = convertPoints; // 计算滑动的方向
  465. var calcDirection = function calcDirection(start, end) {
  466. var xDistance = end.x - start.x;
  467. var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向
  468. if (Math.abs(xDistance) > Math.abs(yDistance)) {
  469. return xDistance > 0 ? 'right' : 'left';
  470. }
  471. return yDistance > 0 ? 'down' : 'up';
  472. }; // 计算2点之间的距离
  473. var calcDistance = function calcDistance(point1, point2) {
  474. var xDistance = Math.abs(point2.x - point1.x);
  475. var yDistance = Math.abs(point2.y - point1.y);
  476. return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
  477. }; // 获取2点之间的中点
  478. var getCenter = function getCenter(point1, point2) {
  479. var x = point1.x + (point2.x - point1.x) / 2;
  480. var y = point1.y + (point2.y - point1.y) / 2;
  481. return {
  482. x: x,
  483. y: y
  484. };
  485. };
  486. var PRESS_DELAY = 250;
  487. var EventController = /*#__PURE__*/function () {
  488. //NodeJS.Timeout;
  489. function EventController(_ref) {
  490. var _this = this;
  491. var canvas = _ref.canvas,
  492. el = _ref.el;
  493. _classCallCheck(this, EventController);
  494. this.processEvent = void 0;
  495. this.canvas = void 0;
  496. this.startTime = 0;
  497. this.endTime = 0;
  498. this.startPoints = null;
  499. this.startDistance = 0;
  500. this.center = null;
  501. this.pressTimeout = void 0;
  502. this.eventType = null;
  503. this.direction = null;
  504. this.lastMoveTime = 0;
  505. this.prevMovePoints = null;
  506. this.prevMoveTime = 0;
  507. this.lastMovePoints = null;
  508. this.pinch = false;
  509. this._click = function (ev) {
  510. var points = convertPoints$1(ev, _this.canvas);
  511. ev.points = points;
  512. _this.emitEvent('click', ev);
  513. };
  514. this._start = function (ev) {
  515. var points = convertPoints$1(ev, _this.canvas);
  516. if (!points) {
  517. return;
  518. }
  519. ev.points = points;
  520. _this.emitEvent('touchstart', ev); // 以下新增
  521. // 防止上次的内容没有清理掉,重新reset下
  522. _this.reset(); // 记录touch start 的时间
  523. _this.startTime = Date.now(); // 记录touch start 的点
  524. _this.startPoints = points;
  525. if (points.length > 1) {
  526. _this.startDistance = calcDistance(points[0], points[1]);
  527. _this.center = getCenter(points[0], points[1]);
  528. } else {
  529. // 如果touchstart后停顿250ms, 则也触发press事件
  530. _this.pressTimeout = setTimeout(function () {
  531. // 这里固定触发press事件
  532. var eventType = 'press';
  533. var direction = 'none';
  534. ev.direction = direction;
  535. _this.emitStart(eventType, ev);
  536. _this.emitEvent(eventType, ev);
  537. _this.eventType = eventType;
  538. _this.direction = direction;
  539. }, PRESS_DELAY);
  540. }
  541. };
  542. this._move = function (ev) {
  543. var points = convertPoints$1(ev, _this.canvas);
  544. if (!points) return;
  545. ev.points = points;
  546. _this.emitEvent('touchmove', ev); // 以下为新增
  547. var startPoints = _this.startPoints;
  548. if (!startPoints) return; // 多指触控
  549. if (points.length > 1) {
  550. // touchstart的距离
  551. var startDistance = _this.startDistance;
  552. var currentDistance = calcDistance(points[0], points[1]);
  553. ev.zoom = currentDistance / startDistance;
  554. ev.center = _this.center; // 触发缩放事件
  555. _this.emitStart('pinch', ev);
  556. _this.emitEvent('pinch', ev);
  557. } else {
  558. var deltaX = points[0].x - startPoints[0].x;
  559. var deltaY = points[0].y - startPoints[0].y;
  560. var direction = _this.direction || calcDirection(startPoints[0], points[0]);
  561. _this.direction = direction; // 获取press或者pan的事件类型
  562. // press 按住滑动, pan表示平移
  563. // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
  564. var eventType = _this.getEventType(points);
  565. ev.direction = direction;
  566. ev.deltaX = deltaX;
  567. ev.deltaY = deltaY;
  568. _this.emitStart(eventType, ev);
  569. _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用
  570. var prevMoveTime = _this.lastMoveTime;
  571. var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算
  572. if (now - prevMoveTime > 0) {
  573. _this.prevMoveTime = prevMoveTime;
  574. _this.prevMovePoints = _this.lastMovePoints;
  575. _this.lastMoveTime = now;
  576. _this.lastMovePoints = points;
  577. }
  578. }
  579. };
  580. this._end = function (ev) {
  581. var points = convertPoints$1(ev, _this.canvas);
  582. ev.points = points;
  583. _this.emitEnd(ev);
  584. _this.emitEvent('touchend', ev); // 以下为新增
  585. // swipe事件处理, 在touchend之后触发
  586. var lastMoveTime = _this.lastMoveTime;
  587. var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
  588. // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
  589. if (now - lastMoveTime < 100) {
  590. var prevMoveTime = _this.prevMoveTime || _this.startTime;
  591. var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义
  592. if (intervalTime > 0) {
  593. var prevMovePoints = _this.prevMovePoints || _this.startPoints;
  594. var lastMovePoints = _this.lastMovePoints; // move速率
  595. if (!prevMovePoints || !lastMovePoints) return;
  596. var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置
  597. if (velocity > 0.3) {
  598. ev.velocity = velocity;
  599. ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
  600. _this.emitEvent('swipe', ev);
  601. }
  602. }
  603. }
  604. _this.reset();
  605. var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start
  606. if (touches && touches.length > 0) {
  607. _this._start(ev);
  608. }
  609. };
  610. this._cancel = function (ev) {
  611. _this.emitEvent('touchcancel', ev);
  612. _this.reset();
  613. };
  614. this.canvas = canvas;
  615. this.delegateEvent(el); // 用来记录当前触发的事件
  616. this.processEvent = {};
  617. }
  618. _createClass(EventController, [{
  619. key: "delegateEvent",
  620. value: function delegateEvent(canvasEl) {
  621. // 代理这几个事件
  622. canvasEl.addEventListener('click', this._click);
  623. canvasEl.addEventListener('touchstart', this._start);
  624. canvasEl.addEventListener('touchmove', this._move);
  625. canvasEl.addEventListener('touchend', this._end);
  626. canvasEl.addEventListener('touchcancel', this._cancel);
  627. }
  628. }, {
  629. key: "emitEvent",
  630. value: function emitEvent(type, ev) {
  631. var canvas = this.canvas;
  632. canvas.emit(type, ev);
  633. }
  634. }, {
  635. key: "getEventType",
  636. value: function getEventType(points) {
  637. var eventType = this.eventType,
  638. canvas = this.canvas,
  639. startTime = this.startTime,
  640. startPoints = this.startPoints;
  641. if (eventType) {
  642. return eventType;
  643. }
  644. var type;
  645. var panEventListeners = canvas.__events.pan; // 如果没有pan事件的监听,默认都是press
  646. if (!panEventListeners || !panEventListeners.length) {
  647. type = 'press';
  648. } else {
  649. // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
  650. var now = Date.now();
  651. if (!startPoints) return;
  652. if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
  653. type = 'press';
  654. } else {
  655. type = 'pan';
  656. }
  657. }
  658. this.eventType = type;
  659. return type;
  660. }
  661. }, {
  662. key: "enable",
  663. value: function enable(eventType) {
  664. this.processEvent[eventType] = true;
  665. } // 是否进行中的事件
  666. }, {
  667. key: "isProcess",
  668. value: function isProcess(eventType) {
  669. return this.processEvent[eventType];
  670. } // 触发start事件
  671. }, {
  672. key: "emitStart",
  673. value: function emitStart(type, ev) {
  674. if (this.isProcess(type)) {
  675. return;
  676. }
  677. this.enable(type);
  678. this.emitEvent("".concat(type, "start"), ev);
  679. }
  680. }, {
  681. key: "emitEnd",
  682. value: function emitEnd(ev) {// const processEvent = this.processEvent;
  683. // Object.keys(processEvent).forEach((type) => {
  684. // this.emitEvent(`${type}end`, ev);
  685. // delete processEvent[type];
  686. // });
  687. }
  688. }, {
  689. key: "clearPressTimeout",
  690. value: function clearPressTimeout() {
  691. if (this.pressTimeout) {
  692. clearTimeout(this.pressTimeout);
  693. this.pressTimeout = null;
  694. }
  695. }
  696. }, {
  697. key: "reset",
  698. value: function reset() {
  699. this.clearPressTimeout();
  700. this.startTime = 0;
  701. this.startPoints = null;
  702. this.startDistance = 0;
  703. this.direction = null;
  704. this.eventType = null;
  705. this.pinch = false;
  706. this.prevMoveTime = 0;
  707. this.prevMovePoints = null;
  708. this.lastMoveTime = 0;
  709. this.lastMovePoints = null;
  710. }
  711. }]);
  712. return EventController;
  713. }();
  714. var Canvas = /*#__PURE__*/function (_EventEmit) {
  715. _inherits(Canvas, _EventEmit);
  716. var _super = _createSuper(Canvas);
  717. function Canvas(cfg) {
  718. var _this;
  719. _classCallCheck(this, Canvas);
  720. _this = _super.call(this);
  721. _this._attrs = {};
  722. _this._isWindow = void 0;
  723. _this._attrs = Object.assign({}, cfg);
  724. _this._isWindow = typeof window != 'undefined';
  725. _this._initPixelRatio();
  726. _this._initCanvas();
  727. var attrs = ['createImage', 'toDataURL', 'requestAnimationFrame'];
  728. attrs.forEach(function (name) {
  729. _this._initAttrs(name, cfg.canvas || _this.get('el'));
  730. });
  731. return _this;
  732. }
  733. _createClass(Canvas, [{
  734. key: "get",
  735. value: // _node: HTMLCanvasElement = {}
  736. function get(name) {
  737. // if(['createImage','toDataURL', 'requestAnimationFrame' ].includes(name) && !this._attrs[name]) {
  738. // if(this._attrs['el'][name]){
  739. // return this._attrs['el'][name]
  740. // } else if(typeof window != 'undefined') {
  741. // return window[name] || function() {return new Image() }
  742. // }
  743. // }
  744. return this._attrs[name];
  745. }
  746. }, {
  747. key: "set",
  748. value: function set(name, value) {
  749. this._attrs[name] = value;
  750. }
  751. }, {
  752. key: "_initAttrs",
  753. value: function _initAttrs(name, node) {
  754. var _this2 = this;
  755. if (!this.get(name)) {
  756. var fu = function fu() {
  757. if (node[name]) {
  758. return node[name].apply(node, arguments);
  759. } else if (_this2._isWindow) {
  760. var _window;
  761. return window[name] ? (_window = window)[name].apply(_window, arguments) : name == 'createImage' ? new Image() : null;
  762. }
  763. };
  764. this.set(name, fu);
  765. }
  766. }
  767. }, {
  768. key: "_initCanvas",
  769. value: function _initCanvas() {
  770. var el = this.get('el');
  771. var context = this.get('context');
  772. if (!el && !context) {
  773. throw new Error('请指定 id、el 或 context!');
  774. }
  775. var canvas;
  776. if (el) {
  777. // DOMElement or String
  778. canvas = isString(el) ? getDomById(el) : el;
  779. } else {
  780. // 说明没有指定el
  781. canvas = CanvasElement$1.create(context, this._attrs);
  782. }
  783. if (context && canvas && !canvas.getContext) {
  784. canvas.getContext = function () {
  785. return context;
  786. };
  787. }
  788. var width = this.get('width') || getWidth(canvas) || canvas.width;
  789. var height = this.get('height') || getHeight(canvas) || canvas.height;
  790. this.set('canvas', this);
  791. this.set('el', canvas);
  792. this.set('context', context || canvas.getContext('2d'));
  793. this.changeSize(width, height); // 初始化事件控制器
  794. var eventController = new EventController({
  795. canvas: this,
  796. el: canvas,
  797. parent: this.get('parent')
  798. });
  799. this.set('eventController', eventController);
  800. }
  801. }, {
  802. key: "_initPixelRatio",
  803. value: function _initPixelRatio() {
  804. var pixelRatio = this.get('pixelRatio');
  805. if (!pixelRatio) {
  806. this.set('pixelRatio', getPixelRatio());
  807. }
  808. }
  809. }, {
  810. key: "changeSize",
  811. value: function changeSize(width, height) {
  812. var pixelRatio = this.get('pixelRatio');
  813. var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
  814. // 浏览器环境设置style样式
  815. if (canvasDOM.style) {
  816. canvasDOM.style.width = width + 'px';
  817. canvasDOM.style.height = height + 'px';
  818. }
  819. if (isCanvasElement(canvasDOM)) {
  820. canvasDOM.width = width * pixelRatio;
  821. canvasDOM.height = height * pixelRatio;
  822. if (pixelRatio !== 1) {
  823. var ctx = this.get('context');
  824. ctx.scale(pixelRatio, pixelRatio);
  825. }
  826. }
  827. this.set('width', width);
  828. this.set('height', height);
  829. }
  830. }, {
  831. key: "destroy",
  832. value: function destroy() {
  833. if (this.get('destroyed')) {
  834. return;
  835. }
  836. var el = this.get('el');
  837. el.width = 0;
  838. el.height = 0;
  839. this.clear();
  840. this._attrs = {};
  841. this.set('destroyed', true);
  842. }
  843. }, {
  844. key: "clear",
  845. value: function clear() {}
  846. }, {
  847. key: "isDestroyed",
  848. value: function isDestroyed() {
  849. return this.get('destroyed');
  850. }
  851. }]);
  852. return Canvas;
  853. }(EventEmit);
  854. function createCanvas(cfg) {
  855. return new Canvas(cfg);
  856. }
  857. var options = {
  858. // 画笔颜色
  859. penColor: 'black',
  860. // 画板背景颜色
  861. backgroundColor: '',
  862. // 笔锋
  863. openSmooth: true,
  864. // 画笔大小
  865. penSize: 2,
  866. // 画笔最小值
  867. minLineWidth: 2,
  868. // 画笔最大值
  869. maxLineWidth: 6,
  870. // 画笔达到最小宽度所需最小速度(px/ms),取值范围1.0-10.0,值越小,画笔越容易变细,笔锋效果会比较明显,可以自行调整查看效果,选出自己满意的值。
  871. minSpeed: 1.5,
  872. // 相邻两线宽度增(减)量最大百分比,取值范围1-100,为了达到笔锋效果,画笔宽度会随画笔速度而改变,如果相邻两线宽度差太大,过渡效果就会很突兀,使用maxWidthDiffRate限制宽度差,让过渡效果更自然。可以自行调整查看效果,选出自己满意的值。
  873. maxWidthDiffRate: 20,
  874. // 限制历史记录数,即最大可撤销数,传入0则关闭历史记录功能
  875. maxHistoryLength: 20
  876. };
  877. var Pen = /*#__PURE__*/function () {
  878. // emptyData: any
  879. function Pen(canvas) {
  880. var _this = this;
  881. _classCallCheck(this, Pen);
  882. this.canAddHistory = true;
  883. this.points = [];
  884. this.historyList = [];
  885. this.canvas = void 0;
  886. this._isEmpty = true;
  887. this.active = false;
  888. this.getLineWidth = function (speed) {
  889. var _this$get = _this.get('options'),
  890. minSpeed = _this$get.minSpeed,
  891. minLineWidth = _this$get.minLineWidth;
  892. var maxLineWidth = _this.getMaxLineWidth();
  893. var addWidth = (maxLineWidth - minLineWidth) * speed / Math.max(Math.min(minSpeed, 10), 1);
  894. var lineWidth = Math.max(maxLineWidth - addWidth, minLineWidth);
  895. return Math.min(lineWidth, maxLineWidth);
  896. };
  897. this.drawTrapezoid = function (point1, point2, point3, point4) {
  898. var ctx = _this.get('context');
  899. ctx.beginPath();
  900. ctx.moveTo(Number(point1.x.toFixed(1)), Number(point1.y.toFixed(1)));
  901. ctx.lineTo(Number(point2.x.toFixed(1)), Number(point2.y.toFixed(1)));
  902. ctx.lineTo(Number(point3.x.toFixed(1)), Number(point3.y.toFixed(1)));
  903. ctx.lineTo(Number(point4.x.toFixed(1)), Number(point4.y.toFixed(1)));
  904. ctx.fillStyle = _this.get('options').penColor;
  905. ctx.fill();
  906. ctx.draw && ctx.draw(true);
  907. };
  908. this.drawNoSmoothLine = function (prePoint, point) {
  909. point.lastX = prePoint.x + (point.x - prePoint.x) * 0.5;
  910. point.lastY = prePoint.y + (point.y - prePoint.y) * 0.5;
  911. if (typeof prePoint.lastX === 'number') {
  912. _this.drawCurveLine(prePoint.lastX, prePoint.lastY, prePoint.x, prePoint.y, point.lastX, point.lastY, _this.getMaxLineWidth());
  913. }
  914. };
  915. this.drawCurveLine = function (x1, y1, x2, y2, x3, y3, lineWidth) {
  916. lineWidth = Number(lineWidth.toFixed(1));
  917. var ctx = _this.get('context');
  918. ctx.lineWidth = lineWidth;
  919. ctx.beginPath();
  920. ctx.moveTo(Number(x1.toFixed(1)), Number(y1.toFixed(1)));
  921. ctx.quadraticCurveTo(Number(x2.toFixed(1)), Number(y2.toFixed(1)), Number(x3.toFixed(1)), Number(y3.toFixed(1)));
  922. ctx.stroke();
  923. ctx.draw && ctx.draw(true);
  924. };
  925. this.getRadianData = function (x1, y1, x2, y2) {
  926. var dis_x = x2 - x1;
  927. var dis_y = y2 - y1;
  928. if (dis_x === 0) {
  929. return {
  930. val: 0,
  931. pos: -1
  932. };
  933. }
  934. if (dis_y === 0) {
  935. return {
  936. val: 0,
  937. pos: 1
  938. };
  939. }
  940. var val = Math.abs(Math.atan(dis_y / dis_x));
  941. if (x2 > x1 && y2 < y1 || x2 < x1 && y2 > y1) {
  942. return {
  943. val: val,
  944. pos: 1
  945. };
  946. }
  947. return {
  948. val: val,
  949. pos: -1
  950. };
  951. };
  952. this.getRadianPoints = function (radianData, x, y, halfLineWidth) {
  953. if (radianData.val === 0) {
  954. if (radianData.pos === 1) {
  955. return [{
  956. x: x,
  957. y: y + halfLineWidth
  958. }, {
  959. x: x,
  960. y: y - halfLineWidth
  961. }];
  962. }
  963. return [{
  964. y: y,
  965. x: x + halfLineWidth
  966. }, {
  967. y: y,
  968. x: x - halfLineWidth
  969. }];
  970. }
  971. var dis_x = Math.sin(radianData.val) * halfLineWidth;
  972. var dis_y = Math.cos(radianData.val) * halfLineWidth;
  973. if (radianData.pos === 1) {
  974. return [{
  975. x: x + dis_x,
  976. y: y + dis_y
  977. }, {
  978. x: x - dis_x,
  979. y: y - dis_y
  980. }];
  981. }
  982. return [{
  983. x: x + dis_x,
  984. y: y - dis_y
  985. }, {
  986. x: x - dis_x,
  987. y: y + dis_y
  988. }];
  989. };
  990. this.drawSmoothLine = function (prePoint, point) {
  991. var dis_x = point.x - prePoint.x;
  992. var dis_y = point.y - prePoint.y;
  993. if (Math.abs(dis_x) + Math.abs(dis_y) <= 2) {
  994. point.lastX1 = point.lastX2 = prePoint.x + dis_x * 0.5;
  995. point.lastY1 = point.lastY2 = prePoint.y + dis_y * 0.5;
  996. } else {
  997. point.lastX1 = prePoint.x + dis_x * 0.3;
  998. point.lastY1 = prePoint.y + dis_y * 0.3;
  999. point.lastX2 = prePoint.x + dis_x * 0.7;
  1000. point.lastY2 = prePoint.y + dis_y * 0.7;
  1001. }
  1002. point.perLineWidth = (prePoint.lineWidth + point.lineWidth) / 2;
  1003. if (typeof prePoint.lastX1 === 'number') {
  1004. _this.drawCurveLine(prePoint.lastX2, prePoint.lastY2, prePoint.x, prePoint.y, point.lastX1, point.lastY1, point.perLineWidth);
  1005. if (prePoint.isFirstPoint) return;
  1006. if (prePoint.lastX1 === prePoint.lastX2 && prePoint.lastY1 === prePoint.lastY2) return;
  1007. var data = _this.getRadianData(prePoint.lastX1, prePoint.lastY1, prePoint.lastX2, prePoint.lastY2);
  1008. var points1 = _this.getRadianPoints(data, prePoint.lastX1, prePoint.lastY1, prePoint.perLineWidth / 2);
  1009. var points2 = _this.getRadianPoints(data, prePoint.lastX2, prePoint.lastY2, point.perLineWidth / 2);
  1010. _this.drawTrapezoid(points1[0], points2[0], points2[1], points1[1]);
  1011. } else {
  1012. point.isFirstPoint = true;
  1013. }
  1014. };
  1015. this.addHistory = function () {
  1016. var _this$get2 = _this.get('options'),
  1017. maxHistoryLength = _this$get2.maxHistoryLength;
  1018. if (!maxHistoryLength || !_this.canAddHistory) return;
  1019. _this.canAddHistory = false; // || !this.get('toDataURL')
  1020. if (!_this.get('createImage')) {
  1021. _this.historyList.length++;
  1022. return;
  1023. } // this.set('loading', true);
  1024. var image = null;
  1025. image = _this.get('createImage')();
  1026. var toDataURL = _this.get('toDataURL') && _this.get('toDataURL')();
  1027. if (isString(toDataURL)) {
  1028. image.src = toDataURL;
  1029. } else {
  1030. toDataURL.then(function (res) {
  1031. image.src = res;
  1032. });
  1033. } // if (isPromise(toDataURL)) {
  1034. // toDataURL.then(res => {
  1035. // image.src = res
  1036. // })
  1037. // } else {
  1038. // image.src = toDataURL //this.get('el').toDataURL() //toDataURL()
  1039. // }
  1040. image.onload = function () {
  1041. // this.set('loading', false);
  1042. _this.historyList.push(image);
  1043. _this.historyList = _this.historyList.slice(-maxHistoryLength);
  1044. };
  1045. };
  1046. this.drawByImage = function (url) {
  1047. var ctx = _this.get('context');
  1048. var width = _this.get('width');
  1049. var height = _this.get('height');
  1050. ctx.clearRect(0, 0, width, height);
  1051. try {
  1052. ctx.drawImage(url, 0, 0, width, height);
  1053. ctx.draw && ctx.draw(true);
  1054. } catch (e) {
  1055. _this.historyList.length = 0;
  1056. }
  1057. };
  1058. this.isEmpty = function () {
  1059. var _this$get3 = _this.get('options'),
  1060. maxHistoryLength = _this$get3.maxHistoryLength;
  1061. return maxHistoryLength > 0 ? _this.historyList.length === 0 : _this._isEmpty;
  1062. };
  1063. this.clear = function () {
  1064. var ctx = _this.get('context');
  1065. ctx.clearRect(0, 0, _this.get('width'), _this.get('height'));
  1066. ctx.draw && ctx.draw();
  1067. _this._isEmpty = true; // this.drawBgColor();
  1068. _this.historyList.length = 0;
  1069. };
  1070. this.undo = function () {
  1071. if (_this.get('options').maxHistoryLength === 0) _this.clear();
  1072. if (!_this.get('createImage') || !_this.historyList.length) return;
  1073. var pngURL = _this.historyList.splice(-1)[0];
  1074. _this.drawByImage(pngURL);
  1075. if (_this.historyList.length === 0) {
  1076. _this.clear();
  1077. }
  1078. };
  1079. this.canvas = canvas;
  1080. this.canvas.set('pen', options);
  1081. this.init();
  1082. }
  1083. _createClass(Pen, [{
  1084. key: "getOption",
  1085. value: function getOption() {}
  1086. }, {
  1087. key: "setOption",
  1088. value: function setOption() {
  1089. var v = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1090. var cloneOptions = _objectSpread2({}, v);
  1091. var maxLineWidth = cloneOptions.maxLineWidth; // 如果线条最大宽度不是默认值 则设置为penSize
  1092. if (maxLineWidth && v.penSize && maxLineWidth == options.maxLineWidth) {
  1093. var penSize = Math.max(maxLineWidth, v.penSize);
  1094. cloneOptions.maxLineWidth = penSize;
  1095. }
  1096. this.canvas.set('pen', Object.assign({}, options, cloneOptions));
  1097. }
  1098. }, {
  1099. key: "get",
  1100. value: function get(name) {
  1101. if (name == 'options') {
  1102. return this.canvas.get('pen');
  1103. } else {
  1104. return this.canvas.get(name);
  1105. }
  1106. } // set(name: string, value: any) {
  1107. // return this.canvas.set(name, value)
  1108. // }
  1109. }, {
  1110. key: "init",
  1111. value: function init() {
  1112. var _this2 = this;
  1113. var ctx = this.get('context');
  1114. ctx.lineCap = 'round'; // this.drawBackground()
  1115. this.canvas.on('touchstart', function (e) {
  1116. return _this2.onDrawStart(e);
  1117. });
  1118. this.canvas.on('touchmove', function (e) {
  1119. return _this2.onDrawMove(e);
  1120. });
  1121. this.canvas.on('touchend', function (e) {
  1122. return _this2.onDrawEnd(e);
  1123. });
  1124. }
  1125. }, {
  1126. key: "drawBackground",
  1127. value: function drawBackground() {
  1128. var ctx = this.get('context');
  1129. var width = this.get('width');
  1130. var height = this.get('height');
  1131. var _this$get4 = this.get('options'),
  1132. backgroundColor = _this$get4.backgroundColor,
  1133. backgroundImage = _this$get4.backgroundImage;
  1134. if (backgroundColor) {
  1135. ctx.fillStyle = backgroundColor;
  1136. ctx.fillRect(0, 0, width, height);
  1137. ctx.draw && ctx.draw(true);
  1138. }
  1139. if (backgroundImage) {
  1140. this.drawByImage(backgroundImage);
  1141. }
  1142. }
  1143. }, {
  1144. key: "remove",
  1145. value: function remove() {
  1146. var _this3 = this;
  1147. this.canvas.off('touchstart', function (e) {
  1148. return _this3.onDrawStart(e);
  1149. });
  1150. this.canvas.off('touchmove', function (e) {
  1151. return _this3.onDrawMove(e);
  1152. });
  1153. this.canvas.off('touchend', function (e) {
  1154. return _this3.onDrawEnd(e);
  1155. });
  1156. }
  1157. }, {
  1158. key: "disableScroll",
  1159. value: function disableScroll(e) {
  1160. if (e.preventDefault && this.get('options').disableScroll) {
  1161. e.preventDefault();
  1162. }
  1163. }
  1164. }, {
  1165. key: "onDrawStart",
  1166. value: function onDrawStart(e) {
  1167. this.disableScroll(e);
  1168. var points = e.points;
  1169. if (!this.active) return;
  1170. this.canAddHistory = true;
  1171. var ctx = this.get('context');
  1172. ctx.strokeStyle = this.get('options').penColor;
  1173. var _points$ = points[0],
  1174. x = _points$.x,
  1175. y = _points$.y;
  1176. this.initPoint(x, y);
  1177. }
  1178. }, {
  1179. key: "onDrawMove",
  1180. value: function onDrawMove(e) {
  1181. this.disableScroll(e);
  1182. var points = e.points;
  1183. if (!this.active) return;
  1184. var _points$2 = points[0],
  1185. x = _points$2.x,
  1186. y = _points$2.y;
  1187. this.initPoint(x, y);
  1188. this.onDraw();
  1189. }
  1190. }, {
  1191. key: "onDrawEnd",
  1192. value: function onDrawEnd(_ref) {
  1193. var points = _ref.points;
  1194. if (!this.active) return;
  1195. this.canAddHistory = true;
  1196. this.points = [];
  1197. }
  1198. }, {
  1199. key: "onDraw",
  1200. value: function onDraw() {
  1201. var _this4 = this;
  1202. var ctx = this.get('context');
  1203. if (this.points.length < 2) return;
  1204. this.addHistory();
  1205. ctx.lineWidth = this.get('options').penSize || 2;
  1206. var point = this.points.slice(-1)[0];
  1207. var prePoint = this.points.slice(-2, -1)[0];
  1208. var onDraw = function onDraw() {
  1209. _this4._isEmpty = false;
  1210. if (_this4.get('options').openSmooth) {
  1211. _this4.drawSmoothLine(prePoint, point);
  1212. } else {
  1213. _this4.drawNoSmoothLine(prePoint, point);
  1214. }
  1215. };
  1216. if (typeof this.get('el').requestAnimationFrame === 'function') {
  1217. this.get('el').requestAnimationFrame(function () {
  1218. return onDraw();
  1219. });
  1220. } else {
  1221. onDraw();
  1222. }
  1223. }
  1224. }, {
  1225. key: "getMaxLineWidth",
  1226. value: function getMaxLineWidth() {
  1227. var _this$get5 = this.get('options'),
  1228. penSize = _this$get5.penSize,
  1229. maxLineWidth = _this$get5.maxLineWidth;
  1230. return Math.min(penSize, maxLineWidth);
  1231. }
  1232. }, {
  1233. key: "initPoint",
  1234. value: function initPoint(x, y) {
  1235. var point = {
  1236. x: x,
  1237. y: y,
  1238. t: Date.now()
  1239. };
  1240. var prePoint = this.points.slice(-1)[0];
  1241. if (prePoint && (prePoint.t === point.t || prePoint.x === x && prePoint.y === y)) {
  1242. return;
  1243. }
  1244. if (this.get('options').openSmooth && prePoint) {
  1245. var prePoint2 = this.points.slice(-2, -1)[0];
  1246. point.distance = Math.sqrt(Math.pow(point.x - prePoint.x, 2) + Math.pow(point.y - prePoint.y, 2));
  1247. point.speed = point.distance / (point.t - prePoint.t || 0.1);
  1248. point.lineWidth = this.getLineWidth(point.speed);
  1249. if (prePoint2 && prePoint2.lineWidth && prePoint.lineWidth) {
  1250. var rate = (point.lineWidth - prePoint.lineWidth) / prePoint.lineWidth;
  1251. var maxRate = this.get('options').maxWidthDiffRate / 100;
  1252. maxRate = maxRate > 1 ? 1 : maxRate < 0.01 ? 0.01 : maxRate;
  1253. if (Math.abs(rate) > maxRate) {
  1254. var per = rate > 0 ? maxRate : -maxRate;
  1255. point.lineWidth = prePoint.lineWidth * (1 + per);
  1256. }
  1257. }
  1258. }
  1259. this.points.push(point);
  1260. this.points = this.points.slice(-3);
  1261. }
  1262. }]);
  1263. return Pen;
  1264. }();
  1265. var Signature = /*#__PURE__*/function () {
  1266. // options: Options = penDefaultOptions
  1267. function Signature(config) {
  1268. _classCallCheck(this, Signature);
  1269. this.canvas = void 0;
  1270. this._ee = void 0;
  1271. this.pen = void 0;
  1272. var canvas = createCanvas(config);
  1273. canvas.set('parent', this);
  1274. this.canvas = canvas;
  1275. this._ee = new EventEmit(); // Object.assign(penDefaultOptions, options)
  1276. // this.canvas.set('pen', options)
  1277. this.pen = new Pen(canvas);
  1278. this.init();
  1279. }
  1280. _createClass(Signature, [{
  1281. key: "init",
  1282. value: function init() {
  1283. this.pen.active = true;
  1284. } // setOption(options: Options = {}) {
  1285. // // this.canvas.set('options', Object.assign({}, this.options, options))
  1286. // }
  1287. }, {
  1288. key: "destroy",
  1289. value: function destroy() {
  1290. this.canvas.destroy();
  1291. }
  1292. }, {
  1293. key: "clear",
  1294. value: function clear() {
  1295. this.pen.clear();
  1296. }
  1297. }, {
  1298. key: "undo",
  1299. value: function undo() {
  1300. this.pen.undo();
  1301. }
  1302. }, {
  1303. key: "save",
  1304. value: function save() {// this.pen.save();
  1305. }
  1306. }, {
  1307. key: "isEmpty",
  1308. value: function isEmpty() {
  1309. return this.pen.isEmpty();
  1310. }
  1311. }, {
  1312. key: "on",
  1313. value: function on(type, listener) {
  1314. this._ee.on(type, listener);
  1315. }
  1316. }, {
  1317. key: "emit",
  1318. value: function emit(type, listener) {
  1319. this._ee.emit(type, listener);
  1320. }
  1321. }, {
  1322. key: "off",
  1323. value: function off(type, listener) {
  1324. this._ee.off(type, listener);
  1325. }
  1326. }]);
  1327. return Signature;
  1328. }();
  1329. exports.Signature = Signature;
  1330. exports.default = Signature;
  1331. Object.defineProperty(exports, '__esModule', { value: true });
  1332. })));