@syncfusion/ej2-inputs 19.3.57 → 19.4.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -1
  3. package/common.d.ts +4 -0
  4. package/common.js +4 -0
  5. package/dist/ej2-inputs.umd.min.js +2 -2
  6. package/dist/ej2-inputs.umd.min.js.map +1 -1
  7. package/dist/es6/ej2-inputs.es2015.js +1117 -8
  8. package/dist/es6/ej2-inputs.es2015.js.map +1 -1
  9. package/dist/es6/ej2-inputs.es5.js +1152 -8
  10. package/dist/es6/ej2-inputs.es5.js.map +1 -1
  11. package/dist/global/ej2-inputs.min.js +2 -2
  12. package/dist/global/ej2-inputs.min.js.map +1 -1
  13. package/dist/global/index.d.ts +1 -1
  14. package/package.json +9 -9
  15. package/signature.d.ts +4 -0
  16. package/signature.js +4 -0
  17. package/src/common/index.d.ts +4 -0
  18. package/src/common/index.js +4 -0
  19. package/src/common/signature-base.d.ts +320 -0
  20. package/src/common/signature-base.js +946 -0
  21. package/src/index.d.ts +2 -0
  22. package/src/index.js +2 -0
  23. package/src/input/input.js +10 -6
  24. package/src/numerictextbox/numerictextbox.js +5 -0
  25. package/src/signature/index.d.ts +5 -0
  26. package/src/signature/index.js +4 -0
  27. package/src/signature/signature-model.d.ts +131 -0
  28. package/src/signature/signature.d.ts +167 -0
  29. package/src/signature/signature.js +171 -0
  30. package/src/slider/slider.d.ts +1 -0
  31. package/src/slider/slider.js +16 -1
  32. package/styles/bootstrap-dark.css +43 -16
  33. package/styles/bootstrap-dark.scss +1 -0
  34. package/styles/bootstrap.css +43 -16
  35. package/styles/bootstrap.scss +1 -0
  36. package/styles/bootstrap4.css +43 -16
  37. package/styles/bootstrap4.scss +1 -0
  38. package/styles/bootstrap5-dark.css +46 -41
  39. package/styles/bootstrap5-dark.scss +1 -0
  40. package/styles/bootstrap5.css +46 -41
  41. package/styles/bootstrap5.scss +1 -0
  42. package/styles/color-picker/_fabric-dark-definition.scss +1 -1
  43. package/styles/color-picker/_fluent-definition.scss +134 -0
  44. package/styles/color-picker/_layout.scss +5 -5
  45. package/styles/color-picker/_theme.scss +16 -15
  46. package/styles/color-picker/bootstrap-dark.css +20 -0
  47. package/styles/color-picker/bootstrap.css +20 -0
  48. package/styles/color-picker/bootstrap4.css +20 -0
  49. package/styles/color-picker/bootstrap5-dark.css +22 -20
  50. package/styles/color-picker/bootstrap5.css +22 -20
  51. package/styles/color-picker/fabric-dark.css +23 -3
  52. package/styles/color-picker/fabric.css +20 -0
  53. package/styles/color-picker/highcontrast-light.css +20 -0
  54. package/styles/color-picker/highcontrast.css +20 -0
  55. package/styles/color-picker/icons/_fluent.scss +10 -0
  56. package/styles/color-picker/material-dark.css +20 -0
  57. package/styles/color-picker/material.css +20 -0
  58. package/styles/color-picker/tailwind-dark.css +20 -0
  59. package/styles/color-picker/tailwind.css +20 -0
  60. package/styles/fabric-dark.css +46 -19
  61. package/styles/fabric-dark.scss +1 -0
  62. package/styles/fabric.css +43 -16
  63. package/styles/fabric.scss +1 -0
  64. package/styles/highcontrast-light.css +43 -16
  65. package/styles/highcontrast-light.scss +1 -0
  66. package/styles/highcontrast.css +43 -16
  67. package/styles/highcontrast.scss +1 -0
  68. package/styles/input/_fluent-definition.scss +321 -0
  69. package/styles/input/_layout.scss +138 -37
  70. package/styles/input/_theme.scss +42 -24
  71. package/styles/input/bootstrap-dark.css +13 -16
  72. package/styles/input/bootstrap.css +13 -16
  73. package/styles/input/bootstrap4.css +13 -16
  74. package/styles/input/bootstrap5-dark.css +13 -16
  75. package/styles/input/bootstrap5.css +13 -16
  76. package/styles/input/fabric-dark.css +13 -16
  77. package/styles/input/fabric.css +13 -16
  78. package/styles/input/highcontrast-light.css +13 -16
  79. package/styles/input/highcontrast.css +13 -16
  80. package/styles/input/icons/_fluent.scss +17 -0
  81. package/styles/input/material-dark.css +13 -16
  82. package/styles/input/material.css +13 -16
  83. package/styles/input/tailwind-dark.css +13 -16
  84. package/styles/input/tailwind.css +13 -16
  85. package/styles/maskedtextbox/_fluent-definition.scss +7 -0
  86. package/styles/maskedtextbox/_theme.scss +2 -2
  87. package/styles/material-dark.css +43 -16
  88. package/styles/material-dark.scss +1 -0
  89. package/styles/material.css +43 -16
  90. package/styles/material.scss +1 -0
  91. package/styles/numerictextbox/_fluent-definition.scss +5 -0
  92. package/styles/numerictextbox/_theme.scss +18 -0
  93. package/styles/numerictextbox/icons/_fluent.scss +12 -0
  94. package/styles/signature/_all.scss +2 -0
  95. package/styles/signature/_bootstrap-dark-definition.scss +3 -0
  96. package/styles/signature/_bootstrap-definition.scss +3 -0
  97. package/styles/signature/_bootstrap4-definition.scss +3 -0
  98. package/styles/signature/_bootstrap5-dark-definition.scss +1 -0
  99. package/styles/signature/_bootstrap5-definition.scss +3 -0
  100. package/styles/signature/_fabric-dark-definition.scss +3 -0
  101. package/styles/signature/_fabric-definition.scss +3 -0
  102. package/styles/signature/_fluent-definition.scss +3 -0
  103. package/styles/signature/_highcontrast-definition.scss +3 -0
  104. package/styles/signature/_highcontrast-light-definition.scss +3 -0
  105. package/styles/signature/_layout.scss +5 -0
  106. package/styles/signature/_material-dark-definition.scss +3 -0
  107. package/styles/signature/_material-definition.scss +3 -0
  108. package/styles/signature/_tailwind-dark-definition.scss +1 -0
  109. package/styles/signature/_tailwind-definition.scss +3 -0
  110. package/styles/signature/_theme.scss +7 -0
  111. package/styles/signature/bootstrap-dark.css +9 -0
  112. package/styles/signature/bootstrap-dark.scss +3 -0
  113. package/styles/signature/bootstrap.css +9 -0
  114. package/styles/signature/bootstrap.scss +3 -0
  115. package/styles/signature/bootstrap4.css +9 -0
  116. package/styles/signature/bootstrap4.scss +3 -0
  117. package/styles/signature/bootstrap5-dark.css +9 -0
  118. package/styles/signature/bootstrap5-dark.scss +3 -0
  119. package/styles/signature/bootstrap5.css +9 -0
  120. package/styles/signature/bootstrap5.scss +3 -0
  121. package/styles/signature/fabric-dark.css +9 -0
  122. package/styles/signature/fabric-dark.scss +3 -0
  123. package/styles/signature/fabric.css +9 -0
  124. package/styles/signature/fabric.scss +3 -0
  125. package/styles/signature/highcontrast-light.css +9 -0
  126. package/styles/signature/highcontrast-light.scss +3 -0
  127. package/styles/signature/highcontrast.css +9 -0
  128. package/styles/signature/highcontrast.scss +3 -0
  129. package/styles/signature/material-dark.css +10 -0
  130. package/styles/signature/material-dark.scss +3 -0
  131. package/styles/signature/material.css +10 -0
  132. package/styles/signature/material.scss +3 -0
  133. package/styles/signature/tailwind-dark.css +10 -0
  134. package/styles/signature/tailwind-dark.scss +3 -0
  135. package/styles/signature/tailwind.css +10 -0
  136. package/styles/signature/tailwind.scss +3 -0
  137. package/styles/slider/_bootstrap5-definition.scss +2 -2
  138. package/styles/slider/_fluent-definition.scss +94 -0
  139. package/styles/slider/_layout.scss +7 -2
  140. package/styles/slider/_tailwind-definition.scss +2 -2
  141. package/styles/slider/bootstrap5-dark.css +1 -5
  142. package/styles/slider/bootstrap5.css +1 -5
  143. package/styles/slider/tailwind-dark.css +1 -5
  144. package/styles/slider/tailwind.css +1 -5
  145. package/styles/tailwind-dark.css +45 -21
  146. package/styles/tailwind-dark.scss +1 -0
  147. package/styles/tailwind.css +45 -21
  148. package/styles/tailwind.scss +1 -0
  149. package/styles/textbox/_fluent-definition.scss +0 -0
  150. package/styles/uploader/_fluent-definition.scss +234 -0
  151. package/styles/uploader/_layout.scss +99 -8
  152. package/styles/uploader/_theme.scss +5 -2
  153. package/styles/uploader/icons/_fluent.scss +34 -0
@@ -188,7 +188,7 @@ var Input;
188
188
  if (args.floatLabelType === 'Auto') {
189
189
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
190
190
  args.element.addEventListener('input', (event) => {
191
- updateLabelState(args.element.value, floatLabelElement);
191
+ updateLabelState(args.element.value, floatLabelElement, args.element);
192
192
  });
193
193
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
194
194
  args.element.addEventListener('blur', (event) => {
@@ -237,7 +237,7 @@ var Input;
237
237
  addClass([button], CLASSNAMES.CLEARICONHIDE);
238
238
  }
239
239
  }
240
- function updateLabelState(value, label) {
240
+ function updateLabelState(value, label, element = null) {
241
241
  if (value) {
242
242
  addClass([label], CLASSNAMES.LABELTOP);
243
243
  if (label.classList.contains(CLASSNAMES.LABELBOTTOM)) {
@@ -245,10 +245,13 @@ var Input;
245
245
  }
246
246
  }
247
247
  else {
248
- if (label.classList.contains(CLASSNAMES.LABELTOP)) {
249
- removeClass([label], CLASSNAMES.LABELTOP);
248
+ const isNotFocused = element != null ? element !== document.activeElement : true;
249
+ if (isNotFocused) {
250
+ if (label.classList.contains(CLASSNAMES.LABELTOP)) {
251
+ removeClass([label], CLASSNAMES.LABELTOP);
252
+ }
253
+ addClass([label], CLASSNAMES.LABELBOTTOM);
250
254
  }
251
- addClass([label], CLASSNAMES.LABELBOTTOM);
252
255
  }
253
256
  }
254
257
  function getParentNode(element) {
@@ -317,7 +320,7 @@ var Input;
317
320
  const parent = getParentNode(element);
318
321
  if (parent.classList.contains(CLASSNAMES.FLOATINPUT) && floatLabelType === 'Auto') {
319
322
  const label = getParentNode(element).getElementsByClassName('e-float-text')[0];
320
- updateLabelState(element.value, label);
323
+ updateLabelState(element.value, label, element);
321
324
  }
322
325
  }
323
326
  /**
@@ -1408,6 +1411,10 @@ let NumericTextBox = class NumericTextBox extends Component {
1408
1411
  }
1409
1412
  this.element.setSelectionRange(this.element.selectionStart, this.element.selectionStart);
1410
1413
  }
1414
+ if (this.element.value[this.element.selectionStart - 1] === decimalSeparator && this.decimals === 0 && this.validateDecimalOnType) {
1415
+ this.element.value = this.element.value.substring(0, prevPos) +
1416
+ this.element.value.substring(currentPos, this.element.value.length);
1417
+ }
1411
1418
  }
1412
1419
  this.prevVal = this.element.value;
1413
1420
  }
@@ -1774,6 +1781,7 @@ let NumericTextBox = class NumericTextBox extends Component {
1774
1781
  }
1775
1782
  }
1776
1783
  mouseUpOnSpinner(event) {
1784
+ this.prevValue = this.value;
1777
1785
  if (this.isPrevFocused) {
1778
1786
  this.element.focus();
1779
1787
  if (!Browser.isDevice) {
@@ -4338,9 +4346,11 @@ let Slider = class Slider extends Component {
4338
4346
  this.sliderBarClick(e);
4339
4347
  if (e.currentTarget === this.firstHandle) {
4340
4348
  this.firstHandle.classList.add(classNames.sliderHandleFocused);
4349
+ this.firstHandle.classList.add(classNames.sliderTabHandle);
4341
4350
  }
4342
4351
  else {
4343
4352
  this.secondHandle.classList.add(classNames.sliderHandleFocused);
4353
+ this.secondHandle.classList.add(classNames.sliderTabHandle);
4344
4354
  }
4345
4355
  EventHandler.add(document, 'mousemove touchmove', this.sliderBarMove, this);
4346
4356
  EventHandler.add(document, 'mouseup touchend', this.sliderBarUp, this);
@@ -4665,7 +4675,7 @@ let Slider = class Slider extends Component {
4665
4675
  this.initializeTooltipProps();
4666
4676
  }
4667
4677
  initializeTooltipProps() {
4668
- let tooltipShowOn = this.isMaterialTooltip ? 'Always' : (this.tooltip.showOn === 'Auto' ? 'Hover' : this.tooltip.showOn);
4678
+ let tooltipShowOn = (this.tooltip.showOn === 'Auto' ? 'Hover' : this.tooltip.showOn);
4669
4679
  this.setProperties({ tooltip: { showOn: tooltipShowOn } }, true);
4670
4680
  this.tooltipObj.position = this.tooltipPlacement();
4671
4681
  this.tooltipCollision(this.tooltipObj.position);
@@ -4751,6 +4761,11 @@ let Slider = class Slider extends Component {
4751
4761
  this.getHandle().classList.add('e-large-thumb-size');
4752
4762
  }
4753
4763
  }
4764
+ focusHandle() {
4765
+ if (!this.getHandle().classList.contains(classNames.sliderTabHandle)) {
4766
+ this.getHandle().classList.add(classNames.sliderTabHandle);
4767
+ }
4768
+ }
4754
4769
  repeatHandlerUp(e) {
4755
4770
  this.changeEvent('changed', e);
4756
4771
  this.closeTooltip();
@@ -5141,6 +5156,7 @@ let Slider = class Slider extends Component {
5141
5156
  }
5142
5157
  this.tooltipToggle(this.getHandle());
5143
5158
  this.getHandle().focus();
5159
+ this.focusHandle();
5144
5160
  if (args.currentTarget.classList.contains(classNames.firstButton)) {
5145
5161
  EventHandler.add(this.firstBtn, 'mouseup touchend', this.buttonUp, this);
5146
5162
  }
@@ -6081,6 +6097,7 @@ let Slider = class Slider extends Component {
6081
6097
  event.preventDefault();
6082
6098
  this.focusSliderElement();
6083
6099
  this.sliderBarClick(event);
6100
+ this.focusHandle();
6084
6101
  }
6085
6102
  wireEvents() {
6086
6103
  this.onresize = this.reposition.bind(this);
@@ -6164,6 +6181,12 @@ let Slider = class Slider extends Component {
6164
6181
  }
6165
6182
  else {
6166
6183
  this.sliderContainer.classList.remove(classNames.sliderHover);
6184
+ const curTarget = event.currentTarget;
6185
+ if (this.tooltip.isVisible && this.tooltip.showOn !== 'Always' && this.tooltipObj && this.isMaterialTooltip &&
6186
+ !curTarget.classList.contains(classNames.sliderHandleFocused) &&
6187
+ !curTarget.classList.contains(classNames.sliderTabHandle)) {
6188
+ this.closeMaterialTooltip();
6189
+ }
6167
6190
  }
6168
6191
  }
6169
6192
  }
@@ -13403,9 +13426,1095 @@ TextBox = __decorate$6([
13403
13426
  * Uploader modules
13404
13427
  */
13405
13428
 
13429
+ class SignatureBase extends Component {
13430
+ constructor() {
13431
+ super(...arguments);
13432
+ /* minDistance(distance between the two point) was calaculated for smoothness.*/
13433
+ this.minDistance = 5;
13434
+ this.previous = 0;
13435
+ /* interval handles for the smoothness in the mouse move event.*/
13436
+ this.interval = 30;
13437
+ this.timeout = null;
13438
+ this.isSignatureEmpty = true;
13439
+ this.backgroundLoaded = null;
13440
+ this.clearArray = [];
13441
+ this.isBlazor = false;
13442
+ }
13443
+ /**
13444
+ * To Initialize the component rendering
13445
+ *
13446
+ * @private
13447
+ * @param {HTMLCanvasElement} element - Specifies the canvas element.
13448
+ * @param {parameter} parameter - Specifies only for the blazor parameter.
13449
+ * @param {BlazorDotnetObject} dotnetRef - Specifies for blazor client to server communication.
13450
+ * @returns {void}
13451
+ */
13452
+ initialize(element, parameter, dotnetRef) {
13453
+ this.element = element;
13454
+ this.canvasContext = this.element.getContext('2d');
13455
+ this.canvasContext.canvas.tabIndex = 0;
13456
+ if (parameter) {
13457
+ this.setBlazorParameter(parameter);
13458
+ this.dotnetRef = dotnetRef;
13459
+ }
13460
+ this.setHTMLProperties();
13461
+ if (isNullOrUndefined(this.signatureValue)) {
13462
+ this.updateSnapCollection(true);
13463
+ }
13464
+ this.wireEvents();
13465
+ this.isSignatureEmpty = true;
13466
+ if (!this.isBlazor) {
13467
+ this.trigger('created', null);
13468
+ }
13469
+ }
13470
+ setBlazorParameter(parameter) {
13471
+ this.isBlazor = true;
13472
+ this.backgroundColor = parameter.backgroundColor;
13473
+ this.backgroundImage = parameter.backgroundImage;
13474
+ this.disabled = parameter.disabled;
13475
+ this.isReadOnly = parameter.isReadOnly;
13476
+ this.maxStrokeWidth = parameter.maxStrokeWidth || 2;
13477
+ this.minStrokeWidth = parameter.minStrokeWidth || 0.5;
13478
+ this.velocity = parameter.velocity || 0.7;
13479
+ this.strokeColor = parameter.strokeColor || '#000000';
13480
+ this.saveWithBackground = parameter.saveWithBackground;
13481
+ this.interval = 30;
13482
+ this.previous = 0;
13483
+ this.minDistance = 5;
13484
+ this.signatureValue = parameter.signatureValue;
13485
+ if (this.signatureValue) {
13486
+ this.loadPersistedSignature();
13487
+ }
13488
+ }
13489
+ wireEvents() {
13490
+ if (isNullOrUndefined(this.pointColl) && !this.isReadOnly && !this.disabled) {
13491
+ EventHandler.add(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler, this);
13492
+ EventHandler.add(this.canvasContext.canvas, 'keydown', this.keyboardHandler, this);
13493
+ window.addEventListener('resize', this.resizeHandler.bind(this));
13494
+ }
13495
+ else if (this.pointColl) {
13496
+ EventHandler.add(this.canvasContext.canvas, 'mousemove touchmove', this.mouseMoveHandler, this);
13497
+ EventHandler.add(this.canvasContext.canvas, 'mouseup touchend', this.mouseUpHandler, this);
13498
+ EventHandler.add(document, 'mouseup', this.mouseUpHandler, this);
13499
+ }
13500
+ }
13501
+ unwireEvents(type) {
13502
+ if (type === 'mouseup' || type === 'touchend') {
13503
+ EventHandler.remove(this.canvasContext.canvas, 'mousemove touchmove', this.mouseMoveHandler);
13504
+ EventHandler.remove(this.canvasContext.canvas, 'mouseup touchend', this.mouseUpHandler);
13505
+ EventHandler.remove(document, 'mouseup', this.mouseUpHandler);
13506
+ }
13507
+ else {
13508
+ EventHandler.remove(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler);
13509
+ EventHandler.remove(this.canvasContext.canvas, 'mousemove touchmove', this.mouseMoveHandler);
13510
+ EventHandler.remove(this.canvasContext.canvas, 'mouseup touchend', this.mouseUpHandler);
13511
+ EventHandler.remove(document, 'mouseup', this.mouseUpHandler);
13512
+ EventHandler.remove(this.canvasContext.canvas, 'keydown', this.keyboardHandler);
13513
+ window.removeEventListener('resize', this.resizeHandler);
13514
+ }
13515
+ }
13516
+ setHTMLProperties() {
13517
+ if (this.element.height === 150) {
13518
+ this.element.height = this.element.offsetHeight;
13519
+ }
13520
+ if (this.element.width === 300) {
13521
+ this.element.width = this.element.offsetWidth;
13522
+ }
13523
+ this.canvasContext.scale(1, 1);
13524
+ this.canvasContext.fillStyle = this.strokeColor;
13525
+ if (this.backgroundImage) {
13526
+ this.canvasContext.canvas.style.backgroundImage = 'url(' + this.backgroundImage + ')';
13527
+ }
13528
+ else if (this.backgroundColor) {
13529
+ this.canvasContext.canvas.style.backgroundColor = this.backgroundColor;
13530
+ }
13531
+ }
13532
+ mouseDownHandler(e) {
13533
+ if (e.buttons === 1 || e.buttons === 2 || e.type === 'touchstart') {
13534
+ if (e.type === 'touchstart') {
13535
+ e.preventDefault();
13536
+ e.stopPropagation();
13537
+ }
13538
+ this.beginStroke(e);
13539
+ this.wireEvents();
13540
+ }
13541
+ }
13542
+ mouseMoveHandler(e) {
13543
+ if (e.buttons === 1 || e.buttons === 2 || e.type === 'touchmove') {
13544
+ if (e.type === 'touchmove') {
13545
+ e.preventDefault();
13546
+ e.stopPropagation();
13547
+ }
13548
+ if (this.interval) {
13549
+ this.updateStrokeWithThrottle(e);
13550
+ }
13551
+ else {
13552
+ this.updateStroke(e);
13553
+ }
13554
+ }
13555
+ }
13556
+ mouseUpHandler(e) {
13557
+ const args = { actionName: 'strokeUpdate' };
13558
+ if (e.type === 'touchstart') {
13559
+ e.preventDefault();
13560
+ e.stopPropagation();
13561
+ }
13562
+ this.endDraw();
13563
+ this.updateSnapCollection();
13564
+ this.unwireEvents(e.type);
13565
+ if (!this.isBlazor) {
13566
+ this.trigger('change', args);
13567
+ }
13568
+ else {
13569
+ this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'mouseUp');
13570
+ }
13571
+ this.signatureValue = this.snapColl[this.incStep];
13572
+ }
13573
+ keyboardHandler(e) {
13574
+ const args = { fileName: 'Signature', type: 'Png', cancel: false };
13575
+ switch (e.key) {
13576
+ case 'Delete':
13577
+ this.clear();
13578
+ break;
13579
+ case (e.ctrlKey && 's'):
13580
+ if (!this.isBlazor) {
13581
+ this.trigger('beforeSave', args, (observableSaveArgs) => {
13582
+ if (!args.cancel) {
13583
+ this.save(observableSaveArgs.type, observableSaveArgs.fileName);
13584
+ }
13585
+ });
13586
+ }
13587
+ else {
13588
+ this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'beforeSave');
13589
+ }
13590
+ e.preventDefault();
13591
+ e.stopImmediatePropagation();
13592
+ break;
13593
+ case (e.ctrlKey && 'z'):
13594
+ this.undo();
13595
+ break;
13596
+ case (e.ctrlKey && 'y'):
13597
+ this.redo();
13598
+ break;
13599
+ }
13600
+ }
13601
+ resizeHandler() {
13602
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
13603
+ const proxy = this;
13604
+ this.canvasContext.canvas.width = this.element.offsetWidth;
13605
+ this.canvasContext.canvas.height = this.element.offsetHeight;
13606
+ this.canvasContext.scale(1, 1);
13607
+ const restoreImg = new Image();
13608
+ restoreImg.src = this.snapColl[this.incStep];
13609
+ restoreImg.onload = () => {
13610
+ proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height);
13611
+ proxy.canvasContext.drawImage(restoreImg, 0, 0, proxy.element.width, proxy.element.height);
13612
+ };
13613
+ }
13614
+ beginStroke(e) {
13615
+ this.refresh();
13616
+ this.updateStroke(e);
13617
+ }
13618
+ updateStroke(e) {
13619
+ const point = this.createPoint(e);
13620
+ this.addPoint(point);
13621
+ }
13622
+ updateStrokeWithThrottle(args) {
13623
+ const now = Date.now();
13624
+ const remaining = this.interval - (now - this.previous);
13625
+ this.storedArgs = args;
13626
+ if (remaining <= 0 || remaining > this.interval) {
13627
+ if (this.timeout) {
13628
+ clearTimeout(this.timeout);
13629
+ this.timeout = null;
13630
+ }
13631
+ this.previous = now;
13632
+ this.updateStroke(this.storedArgs);
13633
+ if (!this.timeout) {
13634
+ this.storedArgs = null;
13635
+ }
13636
+ }
13637
+ else if (!this.timeout) {
13638
+ this.timeout = window.setTimeout(this.delay.bind(this), remaining);
13639
+ }
13640
+ }
13641
+ delay() {
13642
+ this.previous = Date.now();
13643
+ this.timeout = null;
13644
+ this.updateStroke(this.storedArgs);
13645
+ if (!this.timeout) {
13646
+ this.storedArgs = null;
13647
+ }
13648
+ }
13649
+ createPoint(e) {
13650
+ const rect = this.canvasContext.canvas.getBoundingClientRect();
13651
+ if (e.type === 'mousedown' || e.type === 'mousemove') {
13652
+ return this.point(e.clientX - rect.left, e.clientY - rect.top, new Date().getTime());
13653
+ }
13654
+ else {
13655
+ return this.point(e.touches[0].clientX - rect.left, e.touches[0].clientY - rect.top, new Date().getTime());
13656
+ }
13657
+ }
13658
+ /* Returns the current point corrdinates(x, y) and time.*/
13659
+ point(pointX, pointY, time) {
13660
+ this.pointX = pointX;
13661
+ this.pointY = pointY;
13662
+ this.time = time || new Date().getTime();
13663
+ return { x: this.pointX, y: this.pointY, time: this.time };
13664
+ }
13665
+ addPoint(point) {
13666
+ const points = this.pointColl;
13667
+ let controlPoint1;
13668
+ let controlPoint2;
13669
+ const lastPoint = points.length > 0 && points[points.length - 1];
13670
+ const isLastPointTooClose = lastPoint ? this.distanceTo(lastPoint) <= this.minDistance : false;
13671
+ if (!lastPoint || !(lastPoint && isLastPointTooClose)) {
13672
+ points.push(point);
13673
+ if (points.length > 2) {
13674
+ if (points.length === 3) {
13675
+ points.unshift(points[0]);
13676
+ }
13677
+ controlPoint1 = (this.calculateCurveControlPoints(points[0], points[1], points[2])).controlPoint2;
13678
+ controlPoint2 = (this.calculateCurveControlPoints(points[1], points[2], points[3])).controlPoint1;
13679
+ this.startPoint = points[1];
13680
+ this.controlPoint1 = controlPoint1;
13681
+ this.controlPoint2 = controlPoint2;
13682
+ this.endPoint = points[2];
13683
+ this.startDraw();
13684
+ points.shift();
13685
+ }
13686
+ }
13687
+ }
13688
+ startDraw() {
13689
+ let velocity;
13690
+ velocity = this.pointVelocityCalc(this.startPoint);
13691
+ velocity = this.velocity * velocity + (1 - this.velocity) * this.lastVelocity;
13692
+ const newWidth = Math.max(this.maxStrokeWidth / (velocity + 1), this.minStrokeWidth);
13693
+ this.curveDraw(this.lastWidth, newWidth);
13694
+ this.lastVelocity = velocity;
13695
+ this.lastWidth = newWidth;
13696
+ }
13697
+ endDraw() {
13698
+ const canDrawCurve = this.pointColl.length > 2;
13699
+ const point = this.pointColl[0];
13700
+ if (!canDrawCurve && point) {
13701
+ this.strokeDraw(point);
13702
+ }
13703
+ }
13704
+ /* Calculate the Bezier (x, y) coordinate of the curve. */
13705
+ curveDraw(startWidth, endWidth) {
13706
+ const context = this.canvasContext;
13707
+ let width;
13708
+ let i;
13709
+ let t1;
13710
+ let t2;
13711
+ let t3;
13712
+ let u1;
13713
+ let u2;
13714
+ let u3;
13715
+ let x;
13716
+ let y;
13717
+ const widthValue = endWidth - startWidth;
13718
+ const bezierLength = this.bezierLengthCalc();
13719
+ const drawSteps = Math.ceil(bezierLength) * 2;
13720
+ context.beginPath();
13721
+ for (i = 0; i < drawSteps; i++) {
13722
+ t1 = i / drawSteps;
13723
+ t2 = t1 * t1;
13724
+ t3 = t2 * t1;
13725
+ u1 = 1 - t1;
13726
+ u2 = u1 * u1;
13727
+ u3 = u2 * u1;
13728
+ x = u3 * this.startPoint.x;
13729
+ x += 3 * u2 * t1 * this.controlPoint1.x;
13730
+ x += 3 * u1 * t2 * this.controlPoint2.x;
13731
+ x += t3 * this.endPoint.x;
13732
+ y = u3 * this.startPoint.y;
13733
+ y += 3 * u2 * t1 * this.controlPoint1.y;
13734
+ y += 3 * u1 * t2 * this.controlPoint2.y;
13735
+ y += t3 * this.endPoint.y;
13736
+ width = Math.min(startWidth + t3 * widthValue, this.maxStrokeWidth);
13737
+ this.arcDraw(x, y, width);
13738
+ }
13739
+ context.closePath();
13740
+ context.fill();
13741
+ this.isSignatureEmpty = false;
13742
+ }
13743
+ strokeDraw(point) {
13744
+ const context = this.canvasContext;
13745
+ const pointSize = (this.minStrokeWidth + this.maxStrokeWidth) / 2;
13746
+ context.beginPath();
13747
+ this.arcDraw(point.x, point.y, pointSize);
13748
+ context.closePath();
13749
+ context.fill();
13750
+ this.isSignatureEmpty = false;
13751
+ }
13752
+ arcDraw(x, y, size) {
13753
+ const context = this.canvasContext;
13754
+ context.moveTo(x, y);
13755
+ context.arc(x, y, size, 0, 2 * Math.PI, false);
13756
+ }
13757
+ /* Utility functions for Bezier algorithm*/
13758
+ calculateCurveControlPoints(p1, p2, p3) {
13759
+ const dx1 = p1.x - p2.x;
13760
+ const dy1 = p1.y - p2.y;
13761
+ const dx2 = p2.x - p3.x;
13762
+ const dy2 = p2.y - p3.y;
13763
+ const m1 = { x: (p1.x + p2.x) / 2.0, y: (p1.y + p2.y) / 2.0 };
13764
+ const m2 = { x: (p2.x + p3.x) / 2.0, y: (p2.y + p3.y) / 2.0 };
13765
+ const l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
13766
+ const l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
13767
+ const dxm = (m1.x - m2.x);
13768
+ const dym = (m1.y - m2.y);
13769
+ const k = l2 / (l1 + l2);
13770
+ const cm = { x: m2.x + dxm * k, y: m2.y + dym * k };
13771
+ const tx = p2.x - cm.x;
13772
+ const ty = p2.y - cm.y;
13773
+ return {
13774
+ controlPoint1: this.point(m1.x + tx, m1.y + ty, 0),
13775
+ controlPoint2: this.point(m2.x + tx, m2.y + ty, 0)
13776
+ };
13777
+ }
13778
+ /* Returns approximated bezier length of the curuve.*/
13779
+ bezierLengthCalc() {
13780
+ const steps = 10;
13781
+ let length = 0;
13782
+ let i;
13783
+ let t;
13784
+ let pointx1;
13785
+ let pointy1;
13786
+ let pointx2;
13787
+ let pointy2;
13788
+ let pointx3;
13789
+ let pointy3;
13790
+ for (i = 0; i <= steps; i++) {
13791
+ t = i / steps;
13792
+ pointx1 = this.bezierPointCalc(t, this.startPoint.x, this.controlPoint1.x, this.controlPoint2.x, this.endPoint.x);
13793
+ pointy1 = this.bezierPointCalc(t, this.startPoint.y, this.controlPoint1.y, this.controlPoint2.y, this.endPoint.y);
13794
+ if (i > 0) {
13795
+ pointx3 = pointx1 - pointx2;
13796
+ pointy3 = pointy1 - pointy2;
13797
+ length += Math.sqrt(pointx3 * pointx3 + pointy3 * pointy3);
13798
+ }
13799
+ pointx2 = pointx1;
13800
+ pointy2 = pointy1;
13801
+ }
13802
+ return length;
13803
+ }
13804
+ /* Calculate parametric value of x or y given t and the
13805
+ four point(startpoint, controlpoint1, controlpoint2, endpoint) coordinates of a cubic bezier curve.*/
13806
+ bezierPointCalc(t, startpoint, cp1, cp2, endpoint) {
13807
+ return startpoint * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * cp1 * (1.0 - t) * (1.0 - t) * t + 3.0 *
13808
+ cp2 * (1.0 - t) * t * t + endpoint * t * t * t;
13809
+ }
13810
+ /* Velocity between the current point and last point.*/
13811
+ pointVelocityCalc(startPoint) {
13812
+ return (this.time !== startPoint.time) ? this.distanceTo(startPoint) / (this.time - startPoint.time) : 0;
13813
+ }
13814
+ /* Distance between the current point and last point.*/
13815
+ distanceTo(start) {
13816
+ return Math.sqrt(Math.pow(this.pointX - start.x, 2) + Math.pow(this.pointY - start.y, 2));
13817
+ }
13818
+ isRead(isRead) {
13819
+ if (isRead) {
13820
+ EventHandler.remove(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler);
13821
+ }
13822
+ else if (!this.disabled) {
13823
+ EventHandler.add(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler, this);
13824
+ }
13825
+ }
13826
+ enableOrDisable(isDisable) {
13827
+ this.disabled = isDisable;
13828
+ if (isDisable) {
13829
+ this.reDraw('0.5');
13830
+ this.isRead(true);
13831
+ }
13832
+ else {
13833
+ this.reDraw('1');
13834
+ this.isRead(false);
13835
+ }
13836
+ }
13837
+ reDraw(opacity) {
13838
+ const data = this.canvasContext.getImageData(0, 0, this.element.width, this.element.height);
13839
+ this.canvasContext.clearRect(0, 0, this.element.width, this.element.height);
13840
+ this.element.style.opacity = opacity;
13841
+ this.canvasContext.putImageData(data, 0, 0);
13842
+ }
13843
+ updateSnapCollection(isClear) {
13844
+ if (isNullOrUndefined(this.incStep)) {
13845
+ this.incStep = -1;
13846
+ this.incStep++;
13847
+ this.snapColl = [];
13848
+ this.clearArray = [];
13849
+ }
13850
+ else {
13851
+ this.incStep++;
13852
+ }
13853
+ if (this.incStep < this.snapColl.length) {
13854
+ this.snapColl.length = this.incStep;
13855
+ }
13856
+ if (this.incStep > 0) {
13857
+ const canvasNew = this.createElement('canvas', { className: 'e-' + this.getModuleName() + '-wrapper' });
13858
+ const canvasContextNew = canvasNew.getContext('2d');
13859
+ canvasNew.width = this.canvasContext.canvas.width;
13860
+ canvasNew.height = this.canvasContext.canvas.height;
13861
+ canvasContextNew.drawImage(this.canvasContext.canvas, 0, 0, canvasNew.width, canvasNew.height);
13862
+ this.snapColl.push(canvasNew.toDataURL());
13863
+ }
13864
+ else {
13865
+ this.snapColl.push(this.canvasContext.canvas.toDataURL());
13866
+ }
13867
+ if (isClear) {
13868
+ this.clearArray.push(this.incStep);
13869
+ }
13870
+ }
13871
+ setBackgroundImage(imageSrc) {
13872
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
13873
+ const proxy = this;
13874
+ const imageObj = new Image();
13875
+ imageObj.crossOrigin = 'anonymous';
13876
+ imageObj.src = imageSrc;
13877
+ imageObj.onload = () => {
13878
+ proxy.canvasContext.globalCompositeOperation = 'source-over';
13879
+ proxy.canvasContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height);
13880
+ proxy.updateSnapCollection();
13881
+ proxy.saveBackground(true);
13882
+ };
13883
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
13884
+ }
13885
+ setBackgroundColor(color) {
13886
+ const canvasEle = this.canvasContext;
13887
+ canvasEle.strokeStyle = color;
13888
+ let i;
13889
+ let j;
13890
+ for (i = 1; i <= canvasEle.canvas.width; i++) {
13891
+ for (j = 1; j <= canvasEle.canvas.height; j++) {
13892
+ canvasEle.strokeRect(0, 0, i, j);
13893
+ }
13894
+ }
13895
+ this.updateSnapCollection();
13896
+ }
13897
+ loadPersistedSignature() {
13898
+ if (isNullOrUndefined(this.signatureValue)) {
13899
+ return;
13900
+ }
13901
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
13902
+ const proxy = this;
13903
+ const lastImage = new Image();
13904
+ lastImage.src = this.signatureValue;
13905
+ lastImage.onload = () => {
13906
+ proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height);
13907
+ proxy.canvasContext.drawImage(lastImage, 0, 0);
13908
+ proxy.updateSnapCollection();
13909
+ };
13910
+ this.isSignatureEmpty = false;
13911
+ }
13912
+ /**
13913
+ * To get the signature as Blob.
13914
+ *
13915
+ * @param {string} url - specify the url/base 64 string to get blob of the signature.
13916
+ * @returns {Blob}.
13917
+ */
13918
+ getBlob(url) {
13919
+ const arr = url.split(',');
13920
+ const type = arr[0].match(/:(.*?);/)[1];
13921
+ const bstr = atob(arr[1]);
13922
+ let n = bstr.length;
13923
+ const u8arr = new Uint8Array(n);
13924
+ while (n--) {
13925
+ u8arr[n] = bstr.charCodeAt(n);
13926
+ }
13927
+ return new Blob([u8arr], { type: type });
13928
+ }
13929
+ download(blob, fileName) {
13930
+ const blobUrl = URL.createObjectURL(blob);
13931
+ const a = document.createElement('a');
13932
+ a.href = blobUrl;
13933
+ a.target = '_parent';
13934
+ a.download = fileName;
13935
+ (document.body || document.documentElement).appendChild(a);
13936
+ a.click();
13937
+ a.parentNode.removeChild(a);
13938
+ }
13939
+ /**
13940
+ * To refresh the signature.
13941
+ *
13942
+ * @private
13943
+ * @returns {void}.
13944
+ */
13945
+ refresh() {
13946
+ this.pointColl = [];
13947
+ this.lastVelocity = 0;
13948
+ this.lastWidth = (this.minStrokeWidth + this.maxStrokeWidth) / 2;
13949
+ }
13950
+ /**
13951
+ * Erases all the signature strokes signed by user.
13952
+ *
13953
+ * @returns {void}.
13954
+ */
13955
+ clear() {
13956
+ const args = { actionName: 'clear' };
13957
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
13958
+ this.refresh();
13959
+ this.updateSnapCollection(true);
13960
+ this.isSignatureEmpty = true;
13961
+ if (!this.isBlazor) {
13962
+ this.trigger('change', args);
13963
+ }
13964
+ else {
13965
+ this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Clear');
13966
+ }
13967
+ }
13968
+ /**
13969
+ * Undo the last user action.
13970
+ *
13971
+ * @returns {void}.
13972
+ */
13973
+ undo() {
13974
+ const args = { actionName: 'undo' };
13975
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
13976
+ const proxy = this;
13977
+ if (this.incStep > 0) {
13978
+ this.incStep--;
13979
+ const undoImg = new Image();
13980
+ undoImg.src = this.snapColl[this.incStep];
13981
+ undoImg.onload = () => {
13982
+ proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height);
13983
+ proxy.canvasContext.drawImage(undoImg, 0, 0, proxy.element.width, proxy.element.height);
13984
+ };
13985
+ }
13986
+ this.isClear();
13987
+ if (!this.isBlazor) {
13988
+ this.trigger('change', args);
13989
+ }
13990
+ else {
13991
+ this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Undo');
13992
+ }
13993
+ }
13994
+ /**
13995
+ * Redo the last user action.
13996
+ *
13997
+ * @returns {void}.
13998
+ */
13999
+ redo() {
14000
+ const args = { actionName: 'redo' };
14001
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
14002
+ const proxy = this;
14003
+ if (this.incStep < this.snapColl.length - 1) {
14004
+ this.incStep++;
14005
+ const redoImg = new Image();
14006
+ redoImg.src = this.snapColl[this.incStep];
14007
+ redoImg.onload = () => {
14008
+ proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height);
14009
+ proxy.canvasContext.drawImage(redoImg, 0, 0, proxy.element.width, proxy.element.height);
14010
+ };
14011
+ }
14012
+ this.isClear();
14013
+ if (!this.isBlazor) {
14014
+ this.trigger('change', args);
14015
+ }
14016
+ else {
14017
+ this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Redo');
14018
+ }
14019
+ }
14020
+ isClear() {
14021
+ if (this.clearArray) {
14022
+ let empty = false;
14023
+ for (let i = 0; i < this.clearArray.length; i++) {
14024
+ if (this.clearArray[i] === this.incStep) {
14025
+ this.isSignatureEmpty = true;
14026
+ empty = true;
14027
+ }
14028
+ }
14029
+ if (!empty) {
14030
+ this.isSignatureEmpty = false;
14031
+ }
14032
+ }
14033
+ }
14034
+ /**
14035
+ * To check whether the signature is empty or not.
14036
+ *
14037
+ * @returns {boolean}.
14038
+ */
14039
+ isEmpty() {
14040
+ return this.isSignatureEmpty;
14041
+ }
14042
+ /**
14043
+ * To check whether the undo collection is empty or not.
14044
+ *
14045
+ * @returns {boolean}.
14046
+ */
14047
+ canUndo() {
14048
+ return this.incStep > 0;
14049
+ }
14050
+ /**
14051
+ * To check whether the redo collection is empty or not.
14052
+ *
14053
+ * @returns {boolean}.
14054
+ */
14055
+ canRedo() {
14056
+ return this.incStep < this.snapColl.length - 1;
14057
+ }
14058
+ /**
14059
+ * To draw the signature based on the given text, with the font family and font size.
14060
+ *
14061
+ * @param {string} text - specify text to be drawn as signature.
14062
+ * @param {string} fontFamily - specify font family of a signature.
14063
+ * @param {number} fontSize - specify font size of a signature.
14064
+ *
14065
+ * @returns {void}.
14066
+ */
14067
+ draw(text, fontFamily, fontSize) {
14068
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
14069
+ fontFamily = fontFamily || 'Arial';
14070
+ fontSize = fontSize || 30;
14071
+ this.canvasContext.font = fontSize + 'px ' + fontFamily;
14072
+ this.canvasContext.textAlign = 'center';
14073
+ this.canvasContext.textBaseline = 'middle';
14074
+ this.canvasContext.fillText(text, this.element.width / 2, this.element.height / 2);
14075
+ this.updateSnapCollection();
14076
+ this.isSignatureEmpty = false;
14077
+ }
14078
+ /**
14079
+ * To load the signature with the given base 64 string, height and width.
14080
+ *
14081
+ * @param {string} signature - specify the url/base 64 string to be drawn as signature.
14082
+ * @param {number} width - specify the width of the loaded signature image.
14083
+ * @param {number} height - specify the height of the loaded signature image.
14084
+ * @returns {void}.
14085
+ */
14086
+ load(signature, width, height) {
14087
+ height = height || this.element.height;
14088
+ width = width || this.element.width;
14089
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
14090
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
14091
+ const proxy = this;
14092
+ const bitmapImage = new Image();
14093
+ bitmapImage.src = signature;
14094
+ bitmapImage.onload = () => {
14095
+ Promise.all([
14096
+ createImageBitmap(bitmapImage, 0, 0, width, height)
14097
+ ]).then((results) => {
14098
+ const tempCanvas = document.createElement('canvas');
14099
+ tempCanvas.width = width;
14100
+ tempCanvas.height = height;
14101
+ tempCanvas.getContext('2d').drawImage(results[0], 0, 0);
14102
+ proxy.canvasContext.drawImage(tempCanvas, 0, 0, width, height, 0, 0, proxy.element.width, proxy.element.height);
14103
+ proxy.updateSnapCollection();
14104
+ });
14105
+ };
14106
+ this.isSignatureEmpty = false;
14107
+ }
14108
+ saveBackground(savebg) {
14109
+ let imageSrc;
14110
+ if (savebg && this.backgroundImage) {
14111
+ imageSrc = this.snapColl[this.incStep - 1];
14112
+ }
14113
+ else {
14114
+ imageSrc = this.snapColl[this.incStep];
14115
+ }
14116
+ if (!savebg) {
14117
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
14118
+ if (this.backgroundImage) {
14119
+ this.setBackgroundImage(this.backgroundImage);
14120
+ }
14121
+ else if (this.backgroundColor) {
14122
+ this.setBackgroundColor(this.backgroundColor);
14123
+ savebg = true;
14124
+ }
14125
+ }
14126
+ if (savebg) {
14127
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
14128
+ const proxy = this;
14129
+ const imageObj = new Image();
14130
+ imageObj.crossOrigin = 'anonymous';
14131
+ imageObj.src = imageSrc;
14132
+ imageObj.onload = () => {
14133
+ proxy.backgroundLoaded = true;
14134
+ proxy.canvasContext.globalCompositeOperation = 'source-over';
14135
+ proxy.canvasContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height);
14136
+ proxy.save(proxy.fileType, proxy.fileName);
14137
+ };
14138
+ }
14139
+ }
14140
+ /**
14141
+ * To save the signature with the given file type and file name.
14142
+ *
14143
+ * @param {SignatureFileType} type - specify type of the file to be saved a signature.
14144
+ * @param {string} fileName - specify name of the file to be saved a signature.
14145
+ *
14146
+ * @returns {void}.
14147
+ */
14148
+ save(type, fileName) {
14149
+ if (this.saveWithBackground && this.backgroundLoaded == null && (this.backgroundImage || this.backgroundColor)) {
14150
+ this.backgroundLoaded = false;
14151
+ this.fileType = type;
14152
+ this.fileName = fileName;
14153
+ this.saveBackground(false);
14154
+ }
14155
+ else if (type === 'Svg') {
14156
+ fileName = fileName || 'Signature';
14157
+ this.toSVG(fileName);
14158
+ }
14159
+ else if (type === 'Jpeg') {
14160
+ fileName = fileName || 'Signature';
14161
+ if (!this.saveWithBackground || this.saveWithBackground && !(this.backgroundImage || this.backgroundColor)) {
14162
+ this.toJPEG(fileName);
14163
+ }
14164
+ else {
14165
+ const dataURL = this.canvasContext.canvas.toDataURL('image/jpeg');
14166
+ this.download(this.getBlob(dataURL), fileName + '.' + 'jpeg');
14167
+ }
14168
+ }
14169
+ else {
14170
+ fileName = fileName || 'Signature';
14171
+ const dataURL = this.canvasContext.canvas.toDataURL('image/png');
14172
+ this.download(this.getBlob(dataURL), fileName + '.' + 'png');
14173
+ }
14174
+ if (this.saveWithBackground && this.backgroundLoaded) {
14175
+ this.resetSnap();
14176
+ }
14177
+ }
14178
+ resetSnap() {
14179
+ this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height);
14180
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
14181
+ const proxy = this;
14182
+ const restoreObj = new Image();
14183
+ restoreObj.src = this.snapColl[this.incStep - 1];
14184
+ restoreObj.onload = () => {
14185
+ proxy.canvasContext.drawImage(restoreObj, 0, 0, proxy.element.width, proxy.element.height);
14186
+ proxy.updateSnapCollection();
14187
+ };
14188
+ this.backgroundLoaded = null;
14189
+ this.snapColl.pop();
14190
+ this.incStep--;
14191
+ this.snapColl.pop();
14192
+ this.incStep--;
14193
+ }
14194
+ toJPEG(fileName) {
14195
+ const imageSrc = this.snapColl[this.incStep];
14196
+ this.setBackgroundColor('#ffffff');
14197
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
14198
+ const proxy = this;
14199
+ const imageObj = new Image();
14200
+ imageObj.crossOrigin = 'anonymous';
14201
+ imageObj.src = imageSrc;
14202
+ imageObj.onload = () => {
14203
+ proxy.canvasContext.globalCompositeOperation = 'source-over';
14204
+ proxy.canvasContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height);
14205
+ const dataURL = proxy.canvasContext.canvas.toDataURL('image/jpeg');
14206
+ proxy.download(proxy.getBlob(dataURL), fileName + '.' + 'jpeg');
14207
+ proxy.canvasContext.clearRect(0, 0, proxy.canvasContext.canvas.width, proxy.canvasContext.canvas.height);
14208
+ this.resizeHandler();
14209
+ };
14210
+ this.snapColl.pop();
14211
+ this.incStep--;
14212
+ }
14213
+ toSVG(fileName) {
14214
+ const dataUrl = this.canvasContext.canvas.toDataURL();
14215
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
14216
+ svg.setAttribute('width', this.canvasContext.canvas.width.toString());
14217
+ svg.setAttribute('height', this.canvasContext.canvas.height.toString());
14218
+ const XLinkNS = 'http://www.w3.org/1999/xlink';
14219
+ const img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
14220
+ img.setAttributeNS(null, 'height', this.canvasContext.canvas.height.toString());
14221
+ img.setAttributeNS(null, 'width', this.canvasContext.canvas.width.toString());
14222
+ img.setAttributeNS(XLinkNS, 'xlink:href', dataUrl);
14223
+ svg.appendChild(img);
14224
+ const prefix = 'data:image/svg+xml;base64,';
14225
+ const header = '<svg' + ' xmlns="http://www.w3.org/2000/svg"' + ' xmlns:xlink="http://www.w3.org/1999/xlink"'
14226
+ + ` width="${this.canvasContext.canvas.width}"` + ` height="${this.canvasContext.canvas.height}"` + '>';
14227
+ const footer = '</svg>';
14228
+ const body = svg.innerHTML;
14229
+ const data = header + body + footer;
14230
+ const svgDataUrl = prefix + btoa(data);
14231
+ if (fileName == null) {
14232
+ return svgDataUrl;
14233
+ }
14234
+ else {
14235
+ this.download(this.getBlob(svgDataUrl), fileName + '.' + 'svg');
14236
+ return null;
14237
+ }
14238
+ }
14239
+ /**
14240
+ * To save the signature as Blob.
14241
+ *
14242
+ * @returns {Blob}.
14243
+ */
14244
+ saveAsBlob() {
14245
+ return this.getBlob(this.canvasContext.canvas.toDataURL('image/png'));
14246
+ }
14247
+ /**
14248
+ * To get the signature as Base 64.
14249
+ *
14250
+ * @private
14251
+ * @param {SignatureFileType} type - Specifies the type of the image format.
14252
+ * @returns {string}.
14253
+ */
14254
+ getSignature(type) {
14255
+ if (type === 'Jpeg') {
14256
+ const imgData = this.canvasContext.getImageData(0, 0, this.element.width, this.element.height);
14257
+ const data = imgData.data;
14258
+ for (let i = 0; i < data.length; i += 4) {
14259
+ if (data[i + 3] < 255) {
14260
+ data[i] = 255 - data[i];
14261
+ data[i + 1] = 255 - data[i + 1];
14262
+ data[i + 2] = 255 - data[i + 2];
14263
+ data[i + 3] = 255 - data[i + 3];
14264
+ }
14265
+ }
14266
+ this.canvasContext.putImageData(imgData, 0, 0);
14267
+ const dataURL = this.canvasContext.canvas.toDataURL('image/jpeg');
14268
+ this.resizeHandler();
14269
+ return dataURL;
14270
+ }
14271
+ else if (type === 'Svg') {
14272
+ return this.toSVG(null);
14273
+ }
14274
+ else {
14275
+ return this.canvasContext.canvas.toDataURL('image/png');
14276
+ }
14277
+ }
14278
+ /**
14279
+ * Get component name.
14280
+ *
14281
+ * @returns {string} - Module Name
14282
+ * @private
14283
+ */
14284
+ getModuleName() {
14285
+ return 'signature';
14286
+ }
14287
+ /**
14288
+ * To get the properties to be maintained in the persisted state.
14289
+ *
14290
+ * @returns {string} - Persist data
14291
+ */
14292
+ getPersistData() {
14293
+ this.signatureValue = this.snapColl[this.incStep];
14294
+ return this.addOnPersist(['signatureValue']);
14295
+ }
14296
+ /**
14297
+ * Removes the component from the DOM and detaches all its related event handlers.
14298
+ * Also it maintains the initial input element from the DOM.
14299
+ *
14300
+ * @method destroy
14301
+ * @returns {void}
14302
+ */
14303
+ destroy() {
14304
+ this.unwireEvents(null);
14305
+ removeClass([this.element], 'e-' + this.getModuleName());
14306
+ this.element.removeAttribute('tabindex');
14307
+ this.pointColl = null;
14308
+ super.destroy();
14309
+ }
14310
+ /**
14311
+ * Modified onPropertyChanged method for both blazor and EJ2 signature component.
14312
+ *
14313
+ * @private
14314
+ * @param {string} key - Specifies the property, which changed.
14315
+ * @param {string} value - Specifies the property value changed.
14316
+ * @returns {void}
14317
+ */
14318
+ propertyChanged(key, value) {
14319
+ const canvasNew = this.canvasContext;
14320
+ switch (key) {
14321
+ case 'backgroundColor':
14322
+ canvasNew.canvas.style.backgroundColor = value;
14323
+ this.backgroundColor = value;
14324
+ break;
14325
+ case 'backgroundImage':
14326
+ canvasNew.canvas.style.backgroundImage = 'url(' + value + ')';
14327
+ this.backgroundImage = value;
14328
+ break;
14329
+ case 'strokeColor':
14330
+ canvasNew.fillStyle = value;
14331
+ this.strokeColor = value;
14332
+ break;
14333
+ case 'saveWithBackground':
14334
+ this.saveWithBackground = value;
14335
+ break;
14336
+ case 'maxStrokeWidth':
14337
+ this.maxStrokeWidth = value;
14338
+ break;
14339
+ case 'minStrokeWidth':
14340
+ this.minStrokeWidth = value;
14341
+ break;
14342
+ case 'velocity':
14343
+ this.velocity = value;
14344
+ break;
14345
+ case 'isReadOnly':
14346
+ this.isRead(value);
14347
+ break;
14348
+ case 'disabled':
14349
+ this.enableOrDisable(value);
14350
+ break;
14351
+ }
14352
+ }
14353
+ }
14354
+
14355
+ var __decorate$7 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
14356
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14357
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
14358
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14359
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14360
+ };
14361
+ /**
14362
+ * The Signature component allows user to draw smooth signatures as vector outline of strokes using variable width bezier curve interpolation.
14363
+ * It allows to save signature as image.
14364
+ * You can use your finger, pen, or mouse on a tablet, touchscreen, etc., to draw your own signature on this Signature component.
14365
+ * Signature component is a user interface to draw the Signature or Text.
14366
+ * It provides supports for various Background color, Stroke color and Background Image.
14367
+ * ```html
14368
+ * <canvas id="signature"></canvas>
14369
+ * ```
14370
+ * ```typescript
14371
+ * <script>
14372
+ * let signatureObj: Signature = new Signature(null , "#signature");
14373
+ * </script>
14374
+ * ```
14375
+ */
14376
+ let Signature = class Signature extends SignatureBase {
14377
+ /**
14378
+ * Constructor for creating the widget.
14379
+ *
14380
+ * @param {SignatureModel} options - Specifies the Signature model.
14381
+ * @param {string | HTMLCanvasElement} element - Specifies the element.
14382
+ * @private
14383
+ */
14384
+ constructor(options, element) {
14385
+ super(options, element);
14386
+ }
14387
+ preRender() {
14388
+ // pre render code snippets
14389
+ }
14390
+ /**
14391
+ * To Initialize the component rendering
14392
+ *
14393
+ * @private
14394
+ * @returns {void}
14395
+ */
14396
+ render() {
14397
+ this.initialize();
14398
+ }
14399
+ initialize() {
14400
+ addClass([this.element], 'e-' + this.getModuleName());
14401
+ super.initialize(this.element);
14402
+ if (this.enablePersistence) {
14403
+ this.loadPersistedSignature();
14404
+ }
14405
+ }
14406
+ /**
14407
+ * To get component name.
14408
+ *
14409
+ * @returns {string} - Module Name
14410
+ * @private
14411
+ */
14412
+ getModuleName() {
14413
+ return 'signature';
14414
+ }
14415
+ /**
14416
+ * To get the properties to be maintained in the persisted state.
14417
+ *
14418
+ * @returns {string} - Persist data
14419
+ */
14420
+ getPersistData() {
14421
+ return this.addOnPersist(['signatureValue']);
14422
+ }
14423
+ /**
14424
+ * Called internally if any of the property value changed.
14425
+ *
14426
+ * @param {SignatureModel} newProp - Specifies new properties
14427
+ * @param {SignatureModel} oldProp - Specifies old properties
14428
+ * @returns {void}
14429
+ * @private
14430
+ */
14431
+ onPropertyChanged(newProp, oldProp) {
14432
+ for (const prop of Object.keys(newProp)) {
14433
+ switch (prop) {
14434
+ case 'backgroundColor':
14435
+ super.propertyChanged(prop, newProp.backgroundColor);
14436
+ break;
14437
+ case 'backgroundImage':
14438
+ super.propertyChanged(prop, newProp.backgroundImage);
14439
+ break;
14440
+ case 'strokeColor':
14441
+ if (newProp.strokeColor !== oldProp.strokeColor) {
14442
+ super.propertyChanged(prop, newProp.strokeColor);
14443
+ }
14444
+ break;
14445
+ case 'saveWithBackground':
14446
+ super.propertyChanged(prop, newProp.saveWithBackground);
14447
+ break;
14448
+ case 'isReadOnly':
14449
+ super.propertyChanged(prop, newProp.isReadOnly);
14450
+ break;
14451
+ case 'disabled':
14452
+ super.propertyChanged(prop, newProp.disabled);
14453
+ break;
14454
+ }
14455
+ }
14456
+ }
14457
+ };
14458
+ __decorate$7([
14459
+ Property('')
14460
+ ], Signature.prototype, "backgroundColor", void 0);
14461
+ __decorate$7([
14462
+ Property('')
14463
+ ], Signature.prototype, "backgroundImage", void 0);
14464
+ __decorate$7([
14465
+ Property(false)
14466
+ ], Signature.prototype, "disabled", void 0);
14467
+ __decorate$7([
14468
+ Property(false)
14469
+ ], Signature.prototype, "isReadOnly", void 0);
14470
+ __decorate$7([
14471
+ Property(true)
14472
+ ], Signature.prototype, "saveWithBackground", void 0);
14473
+ __decorate$7([
14474
+ Property('#000000')
14475
+ ], Signature.prototype, "strokeColor", void 0);
14476
+ __decorate$7([
14477
+ Property(0.5)
14478
+ ], Signature.prototype, "minStrokeWidth", void 0);
14479
+ __decorate$7([
14480
+ Property(2)
14481
+ ], Signature.prototype, "maxStrokeWidth", void 0);
14482
+ __decorate$7([
14483
+ Property(0.7)
14484
+ ], Signature.prototype, "velocity", void 0);
14485
+ __decorate$7([
14486
+ Property('en-US')
14487
+ ], Signature.prototype, "locale", void 0);
14488
+ __decorate$7([
14489
+ Property(false)
14490
+ ], Signature.prototype, "enableRtl", void 0);
14491
+ __decorate$7([
14492
+ Property(false)
14493
+ ], Signature.prototype, "enablePersistence", void 0);
14494
+ __decorate$7([
14495
+ Event()
14496
+ ], Signature.prototype, "beforeSave", void 0);
14497
+ __decorate$7([
14498
+ Event()
14499
+ ], Signature.prototype, "change", void 0);
14500
+ __decorate$7([
14501
+ Event()
14502
+ ], Signature.prototype, "created", void 0);
14503
+ Signature = __decorate$7([
14504
+ NotifyPropertyChanges
14505
+ ], Signature);
14506
+
14507
+ /**
14508
+ * Signature modules
14509
+ */
14510
+
14511
+ /**
14512
+ * Signature base modules
14513
+ */
14514
+
13406
14515
  /**
13407
14516
  * NumericTextBox all modules
13408
14517
  */
13409
14518
 
13410
- export { NumericTextBox, regularExpressions, createMask, applyMask, wireEvents, unwireEvents, bindClearEvent, unstrippedValue, strippedValue, maskInputMouseDownHandler, maskInputMouseUpHandler, maskInputFocusHandler, triggerFocus, maskInputBlurHandler, maskInputDropHandler, mobileRemoveFunction, setMaskValue, setElementValue, maskInput, getVal, getMaskedVal, MaskUndo, MaskedTextBox, Input, TicksData, ColorRangeData, LimitData, TooltipData, Slider, regex, ErrorOption, FormValidator, FilesProp, ButtonsProps, AsyncSettings, Uploader, ColorPicker, TextBox };
14519
+ export { NumericTextBox, regularExpressions, createMask, applyMask, wireEvents, unwireEvents, bindClearEvent, unstrippedValue, strippedValue, maskInputMouseDownHandler, maskInputMouseUpHandler, maskInputFocusHandler, triggerFocus, maskInputBlurHandler, maskInputDropHandler, mobileRemoveFunction, setMaskValue, setElementValue, maskInput, getVal, getMaskedVal, MaskUndo, MaskedTextBox, Input, TicksData, ColorRangeData, LimitData, TooltipData, Slider, regex, ErrorOption, FormValidator, FilesProp, ButtonsProps, AsyncSettings, Uploader, ColorPicker, TextBox, Signature, SignatureBase };
13411
14520
  //# sourceMappingURL=ej2-inputs.es2015.js.map