@syncfusion/ej2-image-editor 29.2.5 → 30.1.38

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 (95) hide show
  1. package/.eslintrc.json +2 -0
  2. package/dist/ej2-image-editor.umd.min.js +2 -2
  3. package/dist/ej2-image-editor.umd.min.js.map +1 -1
  4. package/dist/es6/ej2-image-editor.es2015.js +898 -227
  5. package/dist/es6/ej2-image-editor.es2015.js.map +1 -1
  6. package/dist/es6/ej2-image-editor.es5.js +920 -237
  7. package/dist/es6/ej2-image-editor.es5.js.map +1 -1
  8. package/dist/global/ej2-image-editor.min.js +2 -2
  9. package/dist/global/ej2-image-editor.min.js.map +1 -1
  10. package/dist/global/index.d.ts +1 -1
  11. package/package.json +15 -47
  12. package/src/image-editor/action/crop.js +1 -1
  13. package/src/image-editor/action/draw.d.ts +1 -0
  14. package/src/image-editor/action/draw.js +103 -31
  15. package/src/image-editor/action/export.js +3 -0
  16. package/src/image-editor/action/selection.d.ts +1 -0
  17. package/src/image-editor/action/selection.js +43 -5
  18. package/src/image-editor/action/shape.d.ts +1 -0
  19. package/src/image-editor/action/shape.js +334 -49
  20. package/src/image-editor/action/transform.js +50 -43
  21. package/src/image-editor/action/undo-redo.d.ts +2 -0
  22. package/src/image-editor/action/undo-redo.js +22 -1
  23. package/src/image-editor/base/enum.d.ts +3 -1
  24. package/src/image-editor/base/enum.js +2 -0
  25. package/src/image-editor/base/image-editor.d.ts +13 -2
  26. package/src/image-editor/base/image-editor.js +242 -27
  27. package/src/image-editor/base/interface.d.ts +17 -1
  28. package/src/image-editor/renderer/toolbar.d.ts +2 -0
  29. package/src/image-editor/renderer/toolbar.js +121 -80
  30. package/styles/bds-lite.css +4 -0
  31. package/styles/bds.css +8 -0
  32. package/styles/bootstrap-dark-lite.css +4 -0
  33. package/styles/bootstrap-dark.css +4 -0
  34. package/styles/bootstrap-lite.css +4 -0
  35. package/styles/bootstrap.css +4 -0
  36. package/styles/bootstrap4-lite.css +4 -0
  37. package/styles/bootstrap4.css +4 -0
  38. package/styles/bootstrap5-dark-lite.css +4 -0
  39. package/styles/bootstrap5-dark.css +4 -0
  40. package/styles/bootstrap5-lite.css +4 -0
  41. package/styles/bootstrap5.3-lite.css +4 -0
  42. package/styles/bootstrap5.3.css +4 -0
  43. package/styles/bootstrap5.css +4 -0
  44. package/styles/fabric-dark-lite.css +4 -0
  45. package/styles/fabric-dark.css +19 -0
  46. package/styles/fabric-lite.css +4 -0
  47. package/styles/fabric.css +19 -0
  48. package/styles/fluent-dark-lite.css +4 -0
  49. package/styles/fluent-dark.css +13 -0
  50. package/styles/fluent-lite.css +4 -0
  51. package/styles/fluent.css +13 -0
  52. package/styles/fluent2-lite.css +8 -0
  53. package/styles/fluent2.css +12 -0
  54. package/styles/highcontrast-light-lite.css +4 -0
  55. package/styles/highcontrast-light.css +4 -0
  56. package/styles/highcontrast-lite.css +9 -1
  57. package/styles/highcontrast.css +14 -1
  58. package/styles/image-editor/_bigger.scss +56 -0
  59. package/styles/image-editor/_highcontrast-definition.scss +1 -1
  60. package/styles/image-editor/_layout.scss +39 -0
  61. package/styles/image-editor/bds.css +8 -0
  62. package/styles/image-editor/bootstrap-dark.css +4 -0
  63. package/styles/image-editor/bootstrap.css +4 -0
  64. package/styles/image-editor/bootstrap4.css +4 -0
  65. package/styles/image-editor/bootstrap5-dark.css +4 -0
  66. package/styles/image-editor/bootstrap5.3.css +4 -0
  67. package/styles/image-editor/bootstrap5.css +4 -0
  68. package/styles/image-editor/fabric-dark.css +19 -0
  69. package/styles/image-editor/fabric.css +19 -0
  70. package/styles/image-editor/fluent-dark.css +13 -0
  71. package/styles/image-editor/fluent.css +13 -0
  72. package/styles/image-editor/fluent2.css +12 -0
  73. package/styles/image-editor/highcontrast-light.css +4 -0
  74. package/styles/image-editor/highcontrast.css +14 -1
  75. package/styles/image-editor/material-dark.css +4 -0
  76. package/styles/image-editor/material.css +8 -0
  77. package/styles/image-editor/material3-dark.css +24 -1
  78. package/styles/image-editor/material3.css +24 -1
  79. package/styles/image-editor/tailwind-dark.css +8 -0
  80. package/styles/image-editor/tailwind.css +8 -0
  81. package/styles/image-editor/tailwind3.css +4 -0
  82. package/styles/material-dark-lite.css +4 -0
  83. package/styles/material-dark.css +4 -0
  84. package/styles/material-lite.css +4 -0
  85. package/styles/material.css +8 -0
  86. package/styles/material3-dark-lite.css +15 -0
  87. package/styles/material3-dark.css +24 -1
  88. package/styles/material3-lite.css +15 -0
  89. package/styles/material3.css +24 -1
  90. package/styles/tailwind-dark-lite.css +4 -0
  91. package/styles/tailwind-dark.css +8 -0
  92. package/styles/tailwind-lite.css +4 -0
  93. package/styles/tailwind.css +8 -0
  94. package/styles/tailwind3-lite.css +4 -0
  95. package/styles/tailwind3.css +4 -0
@@ -171,7 +171,7 @@ class Crop {
171
171
  srcTop: (actPoint.startY * ratio.height) - (img.destTop * ratio.height),
172
172
  srcWidth: (actPoint.width * ratio.width), srcHeight: (actPoint.height * ratio.height),
173
173
  destLeft: (parent.lowerCanvas.clientWidth - maxDimension.width) / 2,
174
- destTop: (parent.lowerCanvas.clientHeight - maxDimension.height + 1) / 2,
174
+ destTop: (parent.lowerCanvas.clientHeight - maxDimension.height) / 2,
175
175
  destWidth: maxDimension.width, destHeight: maxDimension.height };
176
176
  const temp = this.lowerContext.filter;
177
177
  parent.notify('draw', { prop: 'drawImage', onPropertyChange: false });
@@ -943,7 +943,7 @@ class Draw {
943
943
  this.isShapeTextInserted = false;
944
944
  this.isRotateZoom = false; // To restore zoomed image on selection crop selection
945
945
  this.tempStrokeSettings = { strokeColor: '#fff', fillColor: '', strokeWidth: null, outlineColor: '', radius: null, outlineWidth: null }; // restore stroke settings on cancel
946
- this.tempTextSettings = { text: 'Enter Text', fontFamily: '', fontSize: null, fontRatio: null, bold: false, italic: false, underline: false }; // restore text settings on cancel
946
+ this.tempTextSettings = { text: 'Enter Text', fontFamily: '', fontSize: null, fontRatio: null, bold: false, italic: false, underline: false, strikethrough: false }; // restore text settings on cancel
947
947
  this.tempAdjValue = ''; // for temp internal slider value
948
948
  this.tempFilter = ''; // restore filter style on cancel
949
949
  this.tempUndoRedoStep = 0;
@@ -1289,7 +1289,7 @@ class Draw {
1289
1289
  this.tempAdjValue = '';
1290
1290
  this.tempStrokeSettings = { strokeColor: '#fff', fillColor: '', strokeWidth: null, radius: null, outlineColor: '', outlineWidth: null };
1291
1291
  this.tempTextSettings =
1292
- { text: 'Enter Text', fontFamily: this.parent.fontFamily.default, fontSize: null, fontRatio: null, bold: false, italic: false, underline: false };
1292
+ { text: 'Enter Text', fontFamily: this.parent.fontFamily.default, fontSize: null, fontRatio: null, bold: false, italic: false, underline: false, strikethrough: false };
1293
1293
  this.tempUndoRedoStep = this.tempFreehandCounter = this.tempCurrFhdIndex = 0;
1294
1294
  this.tempZoomFactor = null;
1295
1295
  this.isCancelAction = false;
@@ -2886,7 +2886,7 @@ class Draw {
2886
2886
  const actObj = parent.activeObj;
2887
2887
  const { startX, startY, width, height } = actObj.activePoint;
2888
2888
  const rows = actObj.keyHistory.split('\n');
2889
- const { fontFamily, bold, italic } = actObj.textSettings;
2889
+ const { fontFamily, bold, italic, underline, strikethrough } = actObj.textSettings;
2890
2890
  let { fontSize } = actObj.textSettings;
2891
2891
  const lHeight = fontSize + fontSize * 0.25;
2892
2892
  const lineHeight = ((lHeight * rows.length) - (fontSize * rows.length)) / rows.length;
@@ -2900,18 +2900,18 @@ class Draw {
2900
2900
  canvasDraw.fillStyle = tempFill;
2901
2901
  for (let i = 0; i < rows.length; i++) {
2902
2902
  const text = rows[i];
2903
- const yPoint = ((i + 1) * fontSize * 0.85) + (i * lineHeight);
2903
+ const yPoint = ((i + 1) * fontSize * 0.9) + (i * lineHeight);
2904
2904
  if (parent.transform.degree === -360) {
2905
2905
  parent.transform.degree = 0;
2906
2906
  }
2907
2907
  if (parent.transform.degree === 0 || parent.transform.degree === 180) {
2908
2908
  if (fontSize > height) {
2909
- fontSize = actObj.textSettings.fontSize = height - (height * 0.1);
2909
+ fontSize = actObj.textSettings.fontSize = height / 1.18;
2910
2910
  }
2911
2911
  }
2912
2912
  else {
2913
2913
  if (fontSize > width) {
2914
- fontSize = actObj.textSettings.fontSize = width - (width * 0.1);
2914
+ fontSize = actObj.textSettings.fontSize = width / 1.18;
2915
2915
  }
2916
2916
  }
2917
2917
  canvasDraw.strokeStyle = actObj.strokeSettings.outlineColor;
@@ -2958,6 +2958,14 @@ class Draw {
2958
2958
  else {
2959
2959
  canvasDraw.strokeText(text, startX + fontSize * 0.1, startY + yPoint);
2960
2960
  canvasDraw.fillText(text, startX + fontSize * 0.1, startY + yPoint);
2961
+ if (underline) {
2962
+ const yOffset = yPoint + fontSize * 0.1;
2963
+ this.drawTextDecoration(canvasDraw, text, startX, startY, yOffset, fontSize, 0.1);
2964
+ }
2965
+ if (strikethrough) {
2966
+ const yOffset = yPoint - lineHeight - fontSize * 0.025;
2967
+ this.drawTextDecoration(canvasDraw, text, startX, startY, yOffset, fontSize, 0.1);
2968
+ }
2961
2969
  }
2962
2970
  canvasDraw.lineWidth = tempWidth;
2963
2971
  }
@@ -2967,6 +2975,18 @@ class Draw {
2967
2975
  this.drawOuterSelection(canvasDraw);
2968
2976
  }
2969
2977
  }
2978
+ drawTextDecoration(canvasDraw, text, startX, startY, yOffset, fontSize, horizontalPadding = 0.1) {
2979
+ const tempWidth = canvasDraw.lineWidth;
2980
+ const textWidth = canvasDraw.measureText(text).width;
2981
+ canvasDraw.lineWidth = fontSize * 0.1;
2982
+ canvasDraw.beginPath();
2983
+ canvasDraw.moveTo(startX + fontSize * horizontalPadding, startY + yOffset);
2984
+ canvasDraw.lineTo(startX + textWidth + fontSize * horizontalPadding, startY + yOffset);
2985
+ canvasDraw.strokeStyle = canvasDraw.fillStyle;
2986
+ canvasDraw.stroke();
2987
+ canvasDraw.lineWidth = tempWidth;
2988
+ canvasDraw.strokeStyle = this.parent.activeObj.strokeSettings.outlineColor;
2989
+ }
2970
2990
  updateActPoint(degree, canvasDraw) {
2971
2991
  const parent = this.parent;
2972
2992
  const actObj = parent.activeObj;
@@ -3213,6 +3233,14 @@ class Draw {
3213
3233
  yPoint + (i > 0 ? fontSize * 0.25 : -fontSize * 0.35));
3214
3234
  canvasDraw.fillText(text, startX + fontSize * 0.15, startY +
3215
3235
  yPoint + (i > 0 ? fontSize * 0.25 : -fontSize * 0.35));
3236
+ if (actObj.textSettings.underline) {
3237
+ const yOffset = yPoint + (i > 0 ? fontSize * 0.35 : -fontSize * 0.25);
3238
+ this.drawTextDecoration(canvasDraw, text, startX, startY, yOffset, fontSize, 0.15);
3239
+ }
3240
+ if (actObj.textSettings.strikethrough) {
3241
+ const yOffset = yPoint - lineHeight + (i > 0 ? -fontSize * 0.04 : -fontSize * 0.64);
3242
+ this.drawTextDecoration(canvasDraw, text, startX, startY, yOffset, fontSize, 0.1);
3243
+ }
3216
3244
  }
3217
3245
  }
3218
3246
  clearOuterCanvas(context) {
@@ -3262,7 +3290,7 @@ class Draw {
3262
3290
  }
3263
3291
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - maxDimension.width) / 2;
3264
3292
  if (degree === 0) {
3265
- parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height + 1) / 2;
3293
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height) / 2;
3266
3294
  }
3267
3295
  else {
3268
3296
  parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height) / 2;
@@ -3447,6 +3475,7 @@ class Draw {
3447
3475
  const parent = this.parent;
3448
3476
  // eslint-disable-next-line @typescript-eslint/no-this-alias
3449
3477
  const proxy = this;
3478
+ parent.imageLoaded = false;
3450
3479
  parent.baseImg.src = src;
3451
3480
  parent.baseImg.onload = () => {
3452
3481
  parent.imgSrc = src;
@@ -3491,6 +3520,10 @@ class Draw {
3491
3520
  const action = { action: 'file-open', actionEventArgs: fileOpened };
3492
3521
  parent.triggerEditCompleteEvent(action);
3493
3522
  }
3523
+ if (this.fileType === 'Bmp') {
3524
+ this.fileType = FileType.Png;
3525
+ }
3526
+ parent.imageLoaded = true;
3494
3527
  };
3495
3528
  parent.baseImg.onerror = () => {
3496
3529
  hideSpinner(parent.element);
@@ -3505,9 +3538,20 @@ class Draw {
3505
3538
  }
3506
3539
  updateBaseImgCanvas() {
3507
3540
  const parent = this.parent;
3508
- parent.baseImgCanvas.width = parent.baseImg.width;
3509
- parent.baseImgCanvas.height = parent.baseImg.height;
3510
- parent.baseImgCanvas.getContext('2d').drawImage(parent.baseImg, 0, 0);
3541
+ if (!parent.aspectRatioBaseDimension && parent.imageSettings.width && parent.imageSettings.height) {
3542
+ const widthRatio = parent.baseImg.width / parent.imageSettings.width;
3543
+ const heightRatio = parent.baseImg.height / parent.imageSettings.height;
3544
+ let ratio = (widthRatio + heightRatio) / 2;
3545
+ ratio = ratio < 1 ? 1 : ratio;
3546
+ parent.baseImgCanvas.width = parent.imageSettings.width * ratio;
3547
+ parent.baseImgCanvas.height = parent.imageSettings.height * ratio;
3548
+ parent.baseImgCanvas.getContext('2d').drawImage(parent.baseImg, 0, 0, parent.baseImgCanvas.width, parent.baseImgCanvas.height);
3549
+ }
3550
+ else {
3551
+ parent.baseImgCanvas.width = parent.baseImg.width;
3552
+ parent.baseImgCanvas.height = parent.baseImg.height;
3553
+ parent.baseImgCanvas.getContext('2d').drawImage(parent.baseImg, 0, 0);
3554
+ }
3511
3555
  }
3512
3556
  updateCanvas(isCropped, isSameDimension) {
3513
3557
  const parent = this.parent;
@@ -3534,7 +3578,7 @@ class Draw {
3534
3578
  value: { width: parent.img.srcWidth, height: parent.img.srcHeight, obj: obj, isImgShape: null } });
3535
3579
  const maxDimension = obj;
3536
3580
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - maxDimension.width) / 2;
3537
- parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height + 1) / 2;
3581
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height) / 2;
3538
3582
  this.drawImgToCanvas(maxDimension);
3539
3583
  this.origDim.width = parent.img.destWidth;
3540
3584
  this.origDim.height = parent.img.destHeight;
@@ -3871,7 +3915,7 @@ class Draw {
3871
3915
  }
3872
3916
  parent.notify('toolbar', { prop: 'destroy-qa-toolbar', onPropertyChange: false });
3873
3917
  this.tempTextSettings = { text: 'Enter Text', fontFamily: parent.fontFamily.default, fontSize: null, fontRatio: null, bold: false,
3874
- italic: false, underline: false };
3918
+ italic: false, underline: false, strikethrough: false };
3875
3919
  parent.objColl = extend([], this.tempObjColl, [], true);
3876
3920
  parent.pointColl = extend([], this.tempPointColl, [], true);
3877
3921
  this.renderImage();
@@ -4357,7 +4401,7 @@ class Draw {
4357
4401
  const parent = this.parent;
4358
4402
  if (parent.transform.degree % 90 === 0 && parent.transform.degree % 180 !== 0) {
4359
4403
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - parent.img.destHeight) / 2;
4360
- parent.img.destTop = (parent.lowerCanvas.clientHeight - parent.img.destWidth + 1) / 2;
4404
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - parent.img.destWidth) / 2;
4361
4405
  const temp = parent.img.destWidth;
4362
4406
  parent.img.destWidth = parent.img.destHeight;
4363
4407
  parent.img.destHeight = temp;
@@ -4365,7 +4409,7 @@ class Draw {
4365
4409
  else {
4366
4410
  if (isNullOrUndefined(isPreventDimension)) {
4367
4411
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - parent.img.destWidth) / 2;
4368
- parent.img.destTop = (parent.lowerCanvas.clientHeight - parent.img.destHeight + 1) / 2;
4412
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - parent.img.destHeight) / 2;
4369
4413
  }
4370
4414
  }
4371
4415
  }
@@ -4823,7 +4867,7 @@ class Draw {
4823
4867
  this.fileType = 'Jpeg';
4824
4868
  fileType = 'jpeg';
4825
4869
  }
4826
- if (fileType !== 'jpeg' && fileType !== 'png' && fileType !== 'svg' && fileType !== 'webp') {
4870
+ if (fileType !== 'jpeg' && fileType !== 'png' && fileType !== 'svg' && fileType !== 'webp' && fileType !== 'bmp') {
4827
4871
  this.fileType = null;
4828
4872
  }
4829
4873
  }
@@ -4856,9 +4900,9 @@ class Draw {
4856
4900
  return __awaiter(this, void 0, void 0, function* () {
4857
4901
  let response;
4858
4902
  try {
4859
- response = yield fetch(imageUrl, { method: 'HEAD' });
4860
- const contentLength = parseInt(response.headers.get('content-length') || '0', 10);
4861
- const imageSizeMB = contentLength;
4903
+ const isBlob = imageUrl.indexOf('blob:') === 0;
4904
+ response = yield fetch(imageUrl, { method: isBlob ? 'GET' : 'HEAD' });
4905
+ const imageSizeMB = isBlob ? (yield response.blob()).size : parseInt(response.headers.get('content-length') || '0', 10);
4862
4906
  callback(imageSizeMB);
4863
4907
  }
4864
4908
  catch (ex) {
@@ -5060,6 +5104,8 @@ class Draw {
5060
5104
  this.errorLoading();
5061
5105
  return;
5062
5106
  }
5107
+ parent.imageSettings = { width: null, height: null };
5108
+ parent.aspectRatioBaseDimension = null;
5063
5109
  showSpinner(parent.element);
5064
5110
  parent.element.style.opacity = '0.5';
5065
5111
  this.inputElem = inputElement;
@@ -5192,7 +5238,7 @@ class Draw {
5192
5238
  }
5193
5239
  const panX = (parent.lowerCanvas.clientWidth / 2) - (currObj.activePoint.startX +
5194
5240
  (currObj.activePoint.width / 2));
5195
- const panY = ((parent.lowerCanvas.clientHeight + 1) / 2) - (currObj.activePoint.startY +
5241
+ const panY = ((parent.lowerCanvas.clientHeight) / 2) - (currObj.activePoint.startY +
5196
5242
  (currObj.activePoint.height / 2));
5197
5243
  if (isNullOrUndefined(parent.activeObj.shape)) {
5198
5244
  parent.activeObj = extend({}, activeObj, {}, true);
@@ -5966,8 +6012,20 @@ class Draw {
5966
6012
  const point = [];
5967
6013
  const parent = this.parent;
5968
6014
  const degree = parent.transform.degree;
5969
- const width = parent.baseImg.width;
5970
- const height = parent.baseImg.height;
6015
+ let width;
6016
+ let height;
6017
+ if (!parent.aspectRatioBaseDimension && parent.imageSettings.width && parent.imageSettings.height) {
6018
+ const widthRatio = parent.baseImg.width / parent.imageSettings.width;
6019
+ const heightRatio = parent.baseImg.height / parent.imageSettings.height;
6020
+ let ratio = (widthRatio + heightRatio) / 2;
6021
+ ratio = ratio < 1 ? 1 : ratio;
6022
+ width = parent.imageSettings.width * ratio;
6023
+ height = parent.imageSettings.height * ratio;
6024
+ }
6025
+ else {
6026
+ width = parent.baseImg.width;
6027
+ height = parent.baseImg.height;
6028
+ }
5971
6029
  const obj = { dim: null, width: height, height: width, angle: parent.transform.straighten };
5972
6030
  obj['dim'] = parent.getRotatedCanvasDim(obj['width'], obj['height'], obj['angle']);
5973
6031
  const baseImgCanvasWidth = degree % 90 === 0 && degree % 180 !== 0 ? obj['dim']['width'] : parent.baseImgCanvas.width;
@@ -6239,6 +6297,9 @@ class Draw {
6239
6297
  }
6240
6298
  canvasDraw.imageSmoothingEnabled = false;
6241
6299
  canvasDraw.drawImage(offscreenCanvas, 0, 0, offscreenCanvas.width, offscreenCanvas.height, startX, startY, width, height);
6300
+ if (this.parent.imageSmoothingEnabled) {
6301
+ canvasDraw.imageSmoothingEnabled = true;
6302
+ }
6242
6303
  }
6243
6304
  obj.redactImage = this.parent.createElement('canvas');
6244
6305
  obj.redactImage.width = offscreenCanvas.width;
@@ -6292,6 +6353,9 @@ class Export {
6292
6353
  case 'drawAnnotation':
6293
6354
  this.drawAnnotation(args.value['context'], args.value['ratio']);
6294
6355
  break;
6356
+ case 'downScaleImgCanvas':
6357
+ this.downScaleImgCanvas(args.value['canvas'], args.value['width'], args.value['height']);
6358
+ break;
6295
6359
  }
6296
6360
  }
6297
6361
  getModuleName() {
@@ -8899,6 +8963,7 @@ class Selection {
8899
8963
  this.isMouseUp = false;
8900
8964
  this.mouseWheel = 0;
8901
8965
  this.isTransformedShape = false;
8966
+ this.mouseClickPoint = { x: 0, y: 0 };
8902
8967
  this.parent = parent;
8903
8968
  this.addEventListener();
8904
8969
  }
@@ -9069,7 +9134,8 @@ class Selection {
9069
9134
  parent.activeObj.textSettings.fontSize = 11;
9070
9135
  parent.activeObj.keyHistory = 'Enter Text';
9071
9136
  parent.notify('shape', { prop: 'initializeTextShape', onPropertyChange: false,
9072
- value: { text: null, fontFamily: null, fontSize: null, bold: null, italic: null, strokeColor: null } });
9137
+ value: { text: null, fontFamily: null, fontSize: null, bold: null, italic: null,
9138
+ underline: null, strikethrough: null, strokeColor: null } });
9073
9139
  }
9074
9140
  else if (args.value['shape'] === 'path') {
9075
9141
  parent.activeObj.pointColl = [];
@@ -9282,6 +9348,7 @@ class Selection {
9282
9348
  this.isSliderActive = false;
9283
9349
  this.arrowShape = [ArrowheadType.None, ArrowheadType.SolidArrow];
9284
9350
  this.isMouseDown = this.isMouseUp = this.isTransformedShape = false;
9351
+ this.mouseClickPoint = { x: 0, y: 0 };
9285
9352
  }
9286
9353
  performTabAction() {
9287
9354
  const parent = this.parent;
@@ -10457,6 +10524,9 @@ class Selection {
10457
10524
  endY = destTop + destHeight;
10458
10525
  }
10459
10526
  }
10527
+ if (actPoint.width < 0 && actPoint.height < 0 && this.isCropSelection) {
10528
+ isLimiting = true;
10529
+ }
10460
10530
  if (parent.transform.straighten !== 0) {
10461
10531
  const obj = { isIntersect: null, arr: null };
10462
10532
  parent.notify('draw', { prop: 'updateImgCanvasPoints', onPropertyChange: false });
@@ -11200,7 +11270,7 @@ class Selection {
11200
11270
  scale = Math.max(width, height);
11201
11271
  const newScale = this.getScaleRatio(scale);
11202
11272
  actPoint.endX += newScale.x;
11203
- actPoint.endY += newScale.x;
11273
+ actPoint.endY += newScale.y;
11204
11274
  if (actPoint.endX > (destLeft + destWidth) ||
11205
11275
  actPoint.endY > (destTop + destHeight)) {
11206
11276
  actPoint.endX -= newScale.x;
@@ -11315,7 +11385,7 @@ class Selection {
11315
11385
  const width = this.upperContext.measureText(parent.activeObj.textSettings.text).width +
11316
11386
  parent.activeObj.textSettings.fontSize * 0.5;
11317
11387
  actPoint.endX = actPoint.startX + width;
11318
- actPoint.endY = actPoint.startY + parent.activeObj.textSettings.fontSize;
11388
+ actPoint.endY = actPoint.startY + (parent.activeObj.textSettings.fontSize * 1.18);
11319
11389
  actPoint.width = actPoint.endX - actPoint.startX;
11320
11390
  actPoint.height = actPoint.endY - actPoint.startY;
11321
11391
  tempActiveObj = extend({}, parent.activeObj, null, true);
@@ -12118,6 +12188,7 @@ class Selection {
12118
12188
  let activePoint = parent.activeObj.activePoint;
12119
12189
  const x = imageEditorClickEventArgs.point.x;
12120
12190
  const y = imageEditorClickEventArgs.point.y;
12191
+ this.mouseClickPoint = { x: x, y: y };
12121
12192
  const cursor = parent.activeObj.shape && parent.activeObj.shape === 'text' ?
12122
12193
  parent.cursor : 'default';
12123
12194
  const tempCursor = parent.upperCanvas.style.cursor;
@@ -12168,7 +12239,7 @@ class Selection {
12168
12239
  value: { isTextBox: null } });
12169
12240
  const width = this.upperContext.measureText(parent.activeObj.textSettings.text).width + parent.activeObj.textSettings.fontSize * 0.5;
12170
12241
  activePoint.endX = activePoint.startX + width;
12171
- activePoint.endY = activePoint.startY + parent.activeObj.textSettings.fontSize;
12242
+ activePoint.endY = activePoint.startY + (parent.activeObj.textSettings.fontSize * 1.18);
12172
12243
  activePoint.width = activePoint.endX - activePoint.startX;
12173
12244
  activePoint.height = activePoint.endY - activePoint.startY;
12174
12245
  }
@@ -12597,6 +12668,12 @@ class Selection {
12597
12668
  const bbox = parent.lowerCanvas.getBoundingClientRect();
12598
12669
  x -= bbox.left;
12599
12670
  y -= bbox.top;
12671
+ if (parent.drawingShape === 'text' && this.mouseDownPoint && this.mouseDownPoint.x === x && this.mouseDownPoint.y === y) {
12672
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false });
12673
+ if (!parent.activeObj.keyHistory) {
12674
+ parent.activeObj.keyHistory = 'Enter Text';
12675
+ }
12676
+ }
12600
12677
  let activeObjShape;
12601
12678
  const currentDrawingShape = this.currentDrawingShape;
12602
12679
  let dummyClick = false;
@@ -12774,6 +12851,12 @@ class Selection {
12774
12851
  }
12775
12852
  }
12776
12853
  if (!isCropSelection) {
12854
+ let isDummyClick = false;
12855
+ if (Math.round(x) === Math.round(this.mouseClickPoint.x) && Math.round(y) ===
12856
+ Math.round(this.mouseClickPoint.y)) {
12857
+ isDummyClick = true;
12858
+ parent.notify('undo-redo', { prop: 'preventApplyEditComplete', value: { bool: true } });
12859
+ }
12777
12860
  this.adjustActObjForLineArrow();
12778
12861
  if (parent.isShapeDrawing) {
12779
12862
  const temp = this.currentDrawingShape;
@@ -12783,6 +12866,9 @@ class Selection {
12783
12866
  else {
12784
12867
  parent.notify('undo-redo', { prop: 'updateUndoRedoStack', onPropertyChange: false });
12785
12868
  }
12869
+ if (isDummyClick) {
12870
+ parent.notify('undo-redo', { prop: 'preventApplyEditComplete', value: { bool: false } });
12871
+ }
12786
12872
  }
12787
12873
  }
12788
12874
  }
@@ -12846,6 +12932,7 @@ class Selection {
12846
12932
  parent.notify('freehand-draw', { prop: 'resetSelPoints', onPropertyChange: false });
12847
12933
  }
12848
12934
  this.isMouseUp = false;
12935
+ this.mouseClickPoint = { x: 0, y: 0 };
12849
12936
  }
12850
12937
  adjustActObjForLineArrow(obj) {
12851
12938
  let isAdjusted = false;
@@ -13127,7 +13214,8 @@ class Selection {
13127
13214
  (obj.textSettings && Math.round(obj.textSettings.fontRatio) !== Math.round(this.tempActiveObj.textSettings.fontRatio)) ||
13128
13215
  (obj.textSettings && obj.textSettings.bold !== this.tempActiveObj.textSettings.bold) ||
13129
13216
  (obj.textSettings && obj.textSettings.italic !== this.tempActiveObj.textSettings.italic) ||
13130
- (obj.textSettings && obj.textSettings.underline !== this.tempActiveObj.textSettings.underline)) {
13217
+ (obj.textSettings && obj.textSettings.underline !== this.tempActiveObj.textSettings.underline) ||
13218
+ (obj.textSettings && obj.textSettings.strikethrough !== this.tempActiveObj.textSettings.strikethrough)) {
13131
13219
  isApply = true;
13132
13220
  }
13133
13221
  if (this.isInitialTextEdited && !isApply) {
@@ -14171,6 +14259,17 @@ class Selection {
14171
14259
  else {
14172
14260
  parent.activeObj.textSettings.italic = false;
14173
14261
  }
14262
+ parent.activeObj.textSettings.underline = parent.activeObj.textSettings.strikethrough = false;
14263
+ if (parent.textArea.style.textDecoration === 'underline line-through') {
14264
+ parent.activeObj.textSettings.underline = true;
14265
+ parent.activeObj.textSettings.strikethrough = true;
14266
+ }
14267
+ else if (parent.textArea.style.textDecoration === 'underline') {
14268
+ parent.activeObj.textSettings.underline = true;
14269
+ }
14270
+ else if (parent.textArea.style.textDecoration === 'line-through') {
14271
+ parent.activeObj.textSettings.strikethrough = true;
14272
+ }
14174
14273
  parent.activeObj.textSettings.fontSize = (parseFloat(parent.textArea.style.fontSize));
14175
14274
  }
14176
14275
  rgbToHex(r, g, b, a) {
@@ -14322,6 +14421,9 @@ class Selection {
14322
14421
  if (parent.activeObj.textSettings.underline) {
14323
14422
  fontStyle.push('underline');
14324
14423
  }
14424
+ if (parent.activeObj.textSettings.strikethrough) {
14425
+ fontStyle.push('strikethrough');
14426
+ }
14325
14427
  }
14326
14428
  const { startX, startY, endX, endY, width, height } = parent.activeObj.activePoint;
14327
14429
  const { keyHistory, currIndex, shape, textSettings, strokeSettings, rotatedAngle, imageElement, opacity } = parent.activeObj;
@@ -14509,7 +14611,7 @@ class Selection {
14509
14611
  /* eslint-disable no-constant-condition */
14510
14612
  class Shape {
14511
14613
  constructor(parent) {
14512
- this.textSettings = { text: 'Enter Text', fontFamily: '', fontSize: null, fontRatio: null, bold: false, italic: false, underline: false };
14614
+ this.textSettings = { text: 'Enter Text', fontFamily: '', fontSize: null, fontRatio: null, bold: false, italic: false, underline: false, strikethrough: false };
14513
14615
  this.strokeSettings = { strokeColor: '#fff', fillColor: '', strokeWidth: null, radius: null, outlineColor: '', outlineWidth: null };
14514
14616
  this.keyHistory = ''; // text history
14515
14617
  this.preventFrameAnnotation = false;
@@ -14552,7 +14654,7 @@ class Shape {
14552
14654
  this.drawRectangle(args.value['x'], args.value['y'], args.value['width'], args.value['height'], args.value['strokeWidth'], args.value['strokeColor'], args.value['fillColor'], args.value['degree'], args.value['isSelected'], args.value['radius']);
14553
14655
  break;
14554
14656
  case 'drawText':
14555
- this.drawText(args.value['x'], args.value['y'], args.value['text'], args.value['fontFamily'], args.value['fontSize'], args.value['bold'], args.value['italic'], args.value['color'], args.value['isSelected'], args.value['degree'], args.value['fillColor'], args.value['outlineColor'], args.value['outlineWidth'], args.value['transformCollection']);
14657
+ this.drawText(args.value['x'], args.value['y'], args.value['text'], args.value['fontFamily'], args.value['fontSize'], args.value['bold'], args.value['italic'], args.value['color'], args.value['isSelected'], args.value['degree'], args.value['fillColor'], args.value['outlineColor'], args.value['outlineWidth'], args.value['transformCollection'], args.value['underline'], args.value['strikethrough']);
14556
14658
  break;
14557
14659
  case 'redrawActObj':
14558
14660
  this.redrawActObj(args.value['x'], args.value['y'], args.value['isMouseDown']);
@@ -14716,7 +14818,7 @@ class Shape {
14716
14818
  this.alignTextAreaIntoCanvas();
14717
14819
  break;
14718
14820
  case 'initializeTextShape':
14719
- this.initializeTextShape(args.value['text'], args.value['fontFamily'], args.value['fontSize'], args.value['bold'], args.value['italic'], args.value['strokeColor'], args.value['fillColor'], args.value['outlineColor'], args.value['outlineWidth']);
14821
+ this.initializeTextShape(args.value['text'], args.value['fontFamily'], args.value['fontSize'], args.value['bold'], args.value['italic'], args.value['underline'], args.value['strikethrough'], args.value['strokeColor'], args.value['fillColor'], args.value['outlineColor'], args.value['outlineWidth']);
14720
14822
  break;
14721
14823
  case 'stopPathDrawing':
14722
14824
  this.stopPathDrawing(args.value['e'], args.value['isApply']);
@@ -14811,7 +14913,7 @@ class Shape {
14811
14913
  }
14812
14914
  reset() {
14813
14915
  this.textSettings =
14814
- { text: 'Enter Text', fontFamily: this.parent.fontFamily.default, fontSize: null, fontRatio: null, bold: false, italic: false, underline: false };
14916
+ { text: 'Enter Text', fontFamily: this.parent.fontFamily.default, fontSize: null, fontRatio: null, bold: false, italic: false, underline: false, strikethrough: false };
14815
14917
  this.strokeSettings = { strokeColor: '#fff', fillColor: '', strokeWidth: null, radius: null, outlineColor: '', outlineWidth: null };
14816
14918
  this.preventFrameAnnotation = false;
14817
14919
  }
@@ -14851,8 +14953,8 @@ class Shape {
14851
14953
  const start = x && y ? { x: x, y: y } : null;
14852
14954
  this.drawShape('redact', null, null, null, start, width, height, null, null, null, null, null, null, null, type, value);
14853
14955
  }
14854
- drawText(x, y, text, fontFamily, fontSize, bold, italic, color, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection) {
14855
- this.drawShapeText(text, fontFamily, fontSize, bold, italic, color, x, y, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection);
14956
+ drawText(x, y, text, fontFamily, fontSize, bold, italic, color, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection, underline, strikethrough) {
14957
+ this.drawShapeText(text, fontFamily, fontSize, bold, italic, color, x, y, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection, underline, strikethrough);
14856
14958
  }
14857
14959
  initializeShape(type) {
14858
14960
  const parent = this.parent;
@@ -15038,7 +15140,7 @@ class Shape {
15038
15140
  value: { obj: selPointCollObj } });
15039
15141
  this.prevObj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true);
15040
15142
  }
15041
- drawShapeText(text, fontFamily, fontSize, bold, italic, strokeColor, x, y, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection) {
15143
+ drawShapeText(text, fontFamily, fontSize, bold, italic, strokeColor, x, y, isSelected, degree, fillColor, outlineColor, outlineWidth, transformCollection, underline, strikethrough) {
15042
15144
  const parent = this.parent;
15043
15145
  if (!parent.disabled && parent.isImageLoaded) {
15044
15146
  if (parent.currObjType.shape === 'freehanddraw') {
@@ -15053,7 +15155,7 @@ class Shape {
15053
15155
  this.refreshActiveObj();
15054
15156
  parent.activeObj.shape = parent.currObjType.shape = 'text';
15055
15157
  parent.currObjType.isCustomCrop = false;
15056
- this.initializeTextShape(text, fontFamily, fontSize, bold, italic, strokeColor, fillColor, outlineColor, outlineWidth);
15158
+ this.initializeTextShape(text, fontFamily, fontSize, bold, italic, underline, strikethrough, strokeColor, fillColor, outlineColor, outlineWidth);
15057
15159
  parent.currObjType.isText = parent.currObjType.isInitialText = true;
15058
15160
  if (isNullOrUndefined(parent.activeObj.textSettings.fontSize)) {
15059
15161
  parent.getFontSizes();
@@ -15204,7 +15306,7 @@ class Shape {
15204
15306
  isApplyBtn: null, isCropping: null, isZooming: null, cType: null } });
15205
15307
  parent.notify('toolbar', { prop: 'update-toolbar-items', onPropertyChange: false });
15206
15308
  }
15207
- initializeTextShape(text, fontFamily, fontSize, bold, italic, strokeColor, fillColor, outlineColor, outlineWidth) {
15309
+ initializeTextShape(text, fontFamily, fontSize, bold, italic, underline, strikethrough, strokeColor, fillColor, outlineColor, outlineWidth) {
15208
15310
  const parent = this.parent;
15209
15311
  this.keyHistory = '';
15210
15312
  parent.upperCanvas.style.display = 'block';
@@ -15215,6 +15317,8 @@ class Shape {
15215
15317
  parent.activeObj.textSettings.fontSize = fontSize || parent.activeObj.textSettings.fontSize;
15216
15318
  parent.activeObj.textSettings.bold = bold || parent.activeObj.textSettings.bold;
15217
15319
  parent.activeObj.textSettings.italic = italic || parent.activeObj.textSettings.italic;
15320
+ parent.activeObj.textSettings.underline = underline || parent.activeObj.textSettings.underline;
15321
+ parent.activeObj.textSettings.strikethrough = strikethrough || parent.activeObj.textSettings.strikethrough;
15218
15322
  parent.activeObj.strokeSettings.outlineColor = outlineColor || parent.activeObj.strokeSettings.outlineColor;
15219
15323
  parent.activeObj.strokeSettings.outlineWidth = outlineWidth || parent.activeObj.strokeSettings.outlineWidth;
15220
15324
  }
@@ -15419,6 +15523,7 @@ class Shape {
15419
15523
  parent.activeObj.textSettings.bold = false;
15420
15524
  parent.activeObj.textSettings.italic = false;
15421
15525
  parent.activeObj.textSettings.underline = false;
15526
+ parent.activeObj.textSettings.strikethrough = false;
15422
15527
  for (let i = 0; i < shapeSettings.fontStyle.length; i++) {
15423
15528
  switch (shapeSettings.fontStyle[i]) {
15424
15529
  case 'bold':
@@ -15427,6 +15532,12 @@ class Shape {
15427
15532
  case 'italic':
15428
15533
  parent.activeObj.textSettings.italic = true;
15429
15534
  break;
15535
+ case 'underline':
15536
+ parent.activeObj.textSettings.underline = true;
15537
+ break;
15538
+ case 'strikethrough':
15539
+ parent.activeObj.textSettings.strikethrough = true;
15540
+ break;
15430
15541
  }
15431
15542
  }
15432
15543
  }
@@ -15445,7 +15556,7 @@ class Shape {
15445
15556
  this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
15446
15557
  this.updateFontStyles();
15447
15558
  const width = this.upperContext.measureText(this.keyHistory).width + fontSize * 0.5;
15448
- const height = fontSize;
15559
+ const height = fontSize * 1.18;
15449
15560
  this.upperContext.fillText(this.keyHistory, parent.activeObj.activePoint.startX, parent.activeObj.activePoint.startY + fontSize);
15450
15561
  this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
15451
15562
  parent.currObjType.isText = true;
@@ -15468,7 +15579,7 @@ class Shape {
15468
15579
  const text = (parent.textArea.style.display === 'block' || parent.textArea.style.display === 'inline-block') ?
15469
15580
  this.getMaxText(true) : this.getMaxText();
15470
15581
  const width = this.upperContext.measureText(text).width + fontSize * 0.5;
15471
- let height = rows.length * fontSize;
15582
+ let height = rows.length * fontSize * 1.18;
15472
15583
  if (rows.length > 1) {
15473
15584
  height += (fontSize * 0.50);
15474
15585
  }
@@ -15503,7 +15614,7 @@ class Shape {
15503
15614
  parent.textArea.value = '';
15504
15615
  this.updateFontStyles();
15505
15616
  let width = this.upperContext.measureText(parent.activeObj.keyHistory).width + fontSize * 0.5;
15506
- let height = fontSize;
15617
+ let height = fontSize * 1.18;
15507
15618
  const rows = parent.activeObj.keyHistory.split('\n');
15508
15619
  if (rows.length > 1) {
15509
15620
  height *= rows.length;
@@ -16258,6 +16369,9 @@ class Shape {
16258
16369
  }
16259
16370
  parent.textArea.style.fontWeight = actObj.textSettings.bold ? 'bold' : 'normal';
16260
16371
  parent.textArea.style.fontStyle = actObj.textSettings.italic ? 'italic' : 'normal';
16372
+ parent.textArea.style.textDecoration = (actObj.textSettings.underline && actObj.textSettings.strikethrough) ? 'underline line-through' :
16373
+ (actObj.textSettings.underline) ? 'underline' :
16374
+ (actObj.textSettings.strikethrough) ? 'line-through' : 'none';
16261
16375
  parent.textArea.style.border = '2px solid ' + parent.themeColl[parent.theme]['primaryColor'];
16262
16376
  parent.textArea.value = actObj.keyHistory;
16263
16377
  parent.textArea.style.overflow = 'hidden';
@@ -16804,7 +16918,7 @@ class Shape {
16804
16918
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
16805
16919
  const fileData = filesData;
16806
16920
  const fileExtension = fileData.name && fileData.name.split('.').pop().toLowerCase();
16807
- if (fileExtension && ['jpg', 'jpeg', 'png', 'svg', 'webp'].indexOf(fileExtension) === -1) {
16921
+ if (fileExtension && ['jpg', 'jpeg', 'png', 'svg', 'webp', 'bmp'].indexOf(fileExtension) === -1) {
16808
16922
  this.refreshActiveObj();
16809
16923
  return;
16810
16924
  }
@@ -17151,9 +17265,16 @@ class Shape {
17151
17265
  const obj = { shapeSettingsObj: {} };
17152
17266
  parent.notify('selection', { prop: 'updatePrevShapeSettings', onPropertyChange: false, value: { obj: obj } });
17153
17267
  const shapeSettings = obj['shapeSettingsObj'];
17268
+ let isObjPushed = false;
17269
+ const collLength = parent.objColl.length;
17154
17270
  this.pushActItemIntoObj();
17271
+ if (collLength !== parent.objColl.length) {
17272
+ isObjPushed = true;
17273
+ }
17155
17274
  const objColl = extend([], parent.objColl, [], true);
17156
- parent.objColl.pop();
17275
+ if (isObjPushed) {
17276
+ parent.objColl.pop();
17277
+ }
17157
17278
  if (parent.textArea.style.display === 'none') {
17158
17279
  this.updateFontRatio(parent.activeObj);
17159
17280
  }
@@ -17162,24 +17283,77 @@ class Shape {
17162
17283
  }
17163
17284
  switch (item) {
17164
17285
  case 'default':
17165
- this.updateFontStyle(item, objColl, 'normal', 'normal');
17286
+ this.updateFontStyle(item, objColl, 'normal', 'normal', false, false);
17166
17287
  break;
17167
17288
  case 'bold':
17168
- this.updateFontStyle(item, objColl, 'bold', 'normal');
17289
+ this.updateFontStyle(item, objColl, 'bold', 'normal', false, false);
17169
17290
  break;
17170
17291
  case 'italic':
17171
- this.updateFontStyle(item, objColl, 'normal', 'italic');
17292
+ this.updateFontStyle(item, objColl, 'normal', 'italic', false, false);
17172
17293
  break;
17173
17294
  case 'bolditalic':
17174
- this.updateFontStyle(item, objColl, 'bold', 'italic');
17295
+ this.updateFontStyle(item, objColl, 'bold', 'italic', false, false);
17296
+ break;
17297
+ case 'underline':
17298
+ this.updateFontStyle(item, objColl, 'normal', 'normal', true, false);
17299
+ break;
17300
+ case 'boldunderline':
17301
+ this.updateFontStyle(item, objColl, 'bold', 'normal', true, false);
17302
+ break;
17303
+ case 'italicunderline':
17304
+ this.updateFontStyle(item, objColl, 'normal', 'italic', true, false);
17305
+ break;
17306
+ case 'bolditalicunderline':
17307
+ this.updateFontStyle(item, objColl, 'bold', 'italic', true, false);
17308
+ break;
17309
+ case 'strikethrough':
17310
+ this.updateFontStyle(item, objColl, 'normal', 'normal', false, true);
17311
+ break;
17312
+ case 'boldstrikethrough':
17313
+ this.updateFontStyle(item, objColl, 'bold', 'normal', false, true);
17314
+ break;
17315
+ case 'italicstrikethrough':
17316
+ this.updateFontStyle(item, objColl, 'normal', 'italic', false, true);
17317
+ break;
17318
+ case 'underlinestrikethrough':
17319
+ this.updateFontStyle(item, objColl, 'normal', 'normal', true, true);
17320
+ break;
17321
+ case 'bolditalicstrikethrough':
17322
+ this.updateFontStyle(item, objColl, 'bold', 'italic', false, true);
17323
+ break;
17324
+ case 'boldunderlinestrikethrough':
17325
+ this.updateFontStyle(item, objColl, 'bold', 'normal', true, true);
17326
+ break;
17327
+ case 'italicunderlinestrikethrough':
17328
+ this.updateFontStyle(item, objColl, 'normal', 'italic', true, true);
17329
+ break;
17330
+ case 'bolditalicunderlinestrikethrough':
17331
+ this.updateFontStyle(item, objColl, 'bold', 'italic', true, true);
17175
17332
  break;
17176
17333
  }
17177
17334
  const shapeChangedArgs = { action: 'font-style', currentShapeSettings: extend({}, shapeSettings, {}, true) };
17178
- shapeChangedArgs.currentShapeSettings.fontStyle = [item];
17335
+ shapeChangedArgs.currentShapeSettings.fontStyle = this.getFontStyleArray(item);
17179
17336
  parent.trigger('shapeChange', shapeChangedArgs);
17180
17337
  parent.editCompleteArgs = shapeChangedArgs;
17181
17338
  }
17182
- updateFontStyle(item, objColl, fontWeight, fontStyle) {
17339
+ getFontStyleArray(item) {
17340
+ const styleArray = [];
17341
+ const lowerItem = item.toLowerCase();
17342
+ if (lowerItem.indexOf('bold') > -1) {
17343
+ styleArray.push('bold');
17344
+ }
17345
+ if (lowerItem.indexOf('italic') > -1) {
17346
+ styleArray.push('italic');
17347
+ }
17348
+ if (lowerItem.indexOf('underline') > -1) {
17349
+ styleArray.push('underline');
17350
+ }
17351
+ if (lowerItem.indexOf('strikethrough') > -1) {
17352
+ styleArray.push('strikethrough');
17353
+ }
17354
+ return styleArray;
17355
+ }
17356
+ updateFontStyle(item, objColl, fontWeight, fontStyle, underline, strikethrough) {
17183
17357
  const parent = this.parent;
17184
17358
  const style = parent.textArea.style;
17185
17359
  if (style.display === 'block' || style.display === 'inline-block') {
@@ -17195,9 +17369,43 @@ class Shape {
17195
17369
  else {
17196
17370
  style.fontStyle = 'normal';
17197
17371
  }
17198
- const value = (style.fontWeight === 'normal' && style.fontStyle === 'normal' ? 'default' :
17199
- (style.fontWeight === 'bold' && style.fontStyle === 'normal' ? 'bold' :
17200
- (style.fontWeight === 'normal' && style.fontStyle === 'italic' ? 'italic' : 'bolditalic')));
17372
+ if (underline && strikethrough) {
17373
+ style.textDecoration = 'underline line-through';
17374
+ }
17375
+ else if (strikethrough) {
17376
+ style.textDecoration = 'line-through';
17377
+ }
17378
+ else if (underline) {
17379
+ style.textDecoration = 'underline';
17380
+ }
17381
+ else {
17382
+ style.textDecoration = 'none';
17383
+ }
17384
+ const key = [
17385
+ style.fontWeight === 'bold' ? 'bold' : '',
17386
+ style.fontStyle === 'italic' ? 'italic' : '',
17387
+ typeof style.textDecoration === 'string' && style.textDecoration.indexOf('underline') > -1 ? 'underline' : '',
17388
+ typeof style.textDecoration === 'string' && style.textDecoration.indexOf('line-through') > -1 ? 'strikethrough' : ''
17389
+ ].filter(Boolean).join('');
17390
+ const valueMap = {
17391
+ '': 'default',
17392
+ bold: 'bold',
17393
+ italic: 'italic',
17394
+ underline: 'underline',
17395
+ strikethrough: 'strikethrough',
17396
+ bolditalic: 'bolditalic',
17397
+ boldunderline: 'boldunderline',
17398
+ boldstrikethrough: 'boldstrikethrough',
17399
+ italicunderline: 'italicunderline',
17400
+ italicstrikethrough: 'italicstrikethrough',
17401
+ underlinestrikethrough: 'underlinestrikethrough',
17402
+ bolditalicunderline: 'bolditalicunderline',
17403
+ bolditalicstrikethrough: 'bolditalicstrikethrough',
17404
+ boldunderlinestrikethrough: 'boldunderlinestrikethrough',
17405
+ italicunderlinestrikethrough: 'italicunderlinestrikethrough',
17406
+ bolditalicunderlinestrikethrough: 'bolditalicunderlinestrikethrough'
17407
+ };
17408
+ const value = key in valueMap ? valueMap[key] : 'default';
17201
17409
  const width = this.getTextAreaWidth(value);
17202
17410
  style.width = width + 'px';
17203
17411
  this.updateObjColl(item, objColl);
@@ -17205,6 +17413,8 @@ class Shape {
17205
17413
  else {
17206
17414
  this.textSettings.bold = parent.activeObj.textSettings.bold = fontWeight === 'normal' ? false : true;
17207
17415
  this.textSettings.italic = parent.activeObj.textSettings.italic = fontStyle === 'normal' ? false : true;
17416
+ this.textSettings.underline = parent.activeObj.textSettings.underline = underline ? true : false;
17417
+ this.textSettings.strikethrough = parent.activeObj.textSettings.strikethrough = strikethrough ? true : false;
17208
17418
  if (parent.activeObj.activePoint.width !== 0 || parent.activeObj.activePoint.height !== 0) {
17209
17419
  this.redrawText();
17210
17420
  }
@@ -17298,24 +17508,107 @@ class Shape {
17298
17508
  parent.notify('freehand-draw', { prop: 'getSelPointColl', onPropertyChange: false,
17299
17509
  value: { obj: selPointCollObj } });
17300
17510
  prevObj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true);
17301
- const tempBold = parent.activeObj.textSettings.bold;
17302
- const tempItalic = parent.activeObj.textSettings.italic;
17511
+ const textSettings = parent.activeObj.textSettings;
17512
+ const tempBold = textSettings.bold;
17513
+ const tempItalic = textSettings.italic;
17514
+ const tempUnderline = textSettings.underline;
17515
+ const tempStrikethrough = textSettings.strikethrough;
17303
17516
  switch (item) {
17304
17517
  case 'default':
17305
- parent.activeObj.textSettings.bold = false;
17306
- parent.activeObj.textSettings.italic = false;
17518
+ textSettings.bold = false;
17519
+ textSettings.italic = false;
17520
+ textSettings.underline = false;
17521
+ textSettings.strikethrough = false;
17307
17522
  break;
17308
17523
  case 'bold':
17309
- parent.activeObj.textSettings.bold = true;
17310
- parent.activeObj.textSettings.italic = false;
17524
+ textSettings.bold = true;
17525
+ textSettings.italic = false;
17526
+ textSettings.underline = false;
17527
+ textSettings.strikethrough = false;
17311
17528
  break;
17312
17529
  case 'italic':
17313
- parent.activeObj.textSettings.bold = false;
17314
- parent.activeObj.textSettings.italic = true;
17530
+ textSettings.bold = false;
17531
+ textSettings.italic = true;
17532
+ textSettings.underline = false;
17533
+ textSettings.strikethrough = false;
17315
17534
  break;
17316
17535
  case 'bolditalic':
17317
- parent.activeObj.textSettings.bold = true;
17318
- parent.activeObj.textSettings.italic = true;
17536
+ textSettings.bold = true;
17537
+ textSettings.italic = true;
17538
+ textSettings.underline = false;
17539
+ textSettings.strikethrough = false;
17540
+ break;
17541
+ case 'underline':
17542
+ textSettings.bold = false;
17543
+ textSettings.italic = false;
17544
+ textSettings.underline = true;
17545
+ textSettings.strikethrough = false;
17546
+ break;
17547
+ case 'boldunderline':
17548
+ textSettings.bold = true;
17549
+ textSettings.italic = false;
17550
+ textSettings.underline = true;
17551
+ textSettings.strikethrough = false;
17552
+ break;
17553
+ case 'italicunderline':
17554
+ textSettings.bold = false;
17555
+ textSettings.italic = true;
17556
+ textSettings.underline = true;
17557
+ textSettings.strikethrough = false;
17558
+ break;
17559
+ case 'bolditalicunderline':
17560
+ textSettings.bold = true;
17561
+ textSettings.italic = true;
17562
+ textSettings.underline = true;
17563
+ textSettings.strikethrough = false;
17564
+ break;
17565
+ case 'strikethrough':
17566
+ textSettings.bold = false;
17567
+ textSettings.italic = false;
17568
+ textSettings.underline = false;
17569
+ textSettings.strikethrough = true;
17570
+ break;
17571
+ case 'boldstrikethrough':
17572
+ textSettings.bold = true;
17573
+ textSettings.italic = false;
17574
+ textSettings.underline = false;
17575
+ textSettings.strikethrough = true;
17576
+ break;
17577
+ case 'italicstrikethrough':
17578
+ textSettings.bold = false;
17579
+ textSettings.italic = true;
17580
+ textSettings.underline = false;
17581
+ textSettings.strikethrough = true;
17582
+ break;
17583
+ case 'underlinestrikethrough':
17584
+ textSettings.bold = false;
17585
+ textSettings.italic = false;
17586
+ textSettings.underline = true;
17587
+ textSettings.strikethrough = true;
17588
+ break;
17589
+ case 'bolditalicstrikethrough':
17590
+ textSettings.bold = true;
17591
+ textSettings.italic = true;
17592
+ textSettings.underline = false;
17593
+ textSettings.strikethrough = true;
17594
+ break;
17595
+ case 'boldunderlinestrikethrough':
17596
+ textSettings.bold = true;
17597
+ textSettings.italic = false;
17598
+ textSettings.underline = true;
17599
+ textSettings.strikethrough = true;
17600
+ break;
17601
+ case 'italicunderlinestrikethrough':
17602
+ textSettings.bold = false;
17603
+ textSettings.italic = true;
17604
+ textSettings.underline = true;
17605
+ textSettings.strikethrough = true;
17606
+ break;
17607
+ case 'bolditalicunderlinestrikethrough':
17608
+ textSettings.bold = true;
17609
+ textSettings.italic = true;
17610
+ textSettings.underline = true;
17611
+ textSettings.strikethrough = true;
17319
17612
  break;
17320
17613
  }
17321
17614
  parent.objColl.push(parent.activeObj);
@@ -17325,8 +17618,10 @@ class Shape {
17325
17618
  previousCropObj: prevCropObj, previousText: null,
17326
17619
  currentText: null, previousFilter: null, isCircleCrop: null } });
17327
17620
  parent.objColl.pop();
17328
- parent.activeObj.textSettings.bold = tempBold;
17329
- parent.activeObj.textSettings.italic = tempItalic;
17621
+ textSettings.bold = tempBold;
17622
+ textSettings.italic = tempItalic;
17623
+ textSettings.underline = tempUnderline;
17624
+ textSettings.strikethrough = tempStrikethrough;
17330
17625
  }
17331
17626
  pushActItemIntoObj() {
17332
17627
  const parent = this.parent;
@@ -17519,24 +17814,107 @@ class Shape {
17519
17814
  }
17520
17815
  getTextAreaWidth(item) {
17521
17816
  const parent = this.parent;
17522
- const tempBold = parent.activeObj.textSettings.bold;
17523
- const tempItalic = parent.activeObj.textSettings.italic;
17817
+ const textSettings = parent.activeObj.textSettings;
17818
+ const tempBold = textSettings.bold;
17819
+ const tempItalic = textSettings.italic;
17820
+ const tempUnderline = textSettings.underline;
17821
+ const tempStrikethrough = textSettings.strikethrough;
17524
17822
  switch (item) {
17525
17823
  case 'default':
17526
- parent.activeObj.textSettings.bold = false;
17527
- parent.activeObj.textSettings.italic = false;
17824
+ textSettings.bold = false;
17825
+ textSettings.italic = false;
17826
+ textSettings.underline = false;
17827
+ textSettings.strikethrough = false;
17528
17828
  break;
17529
17829
  case 'bold':
17530
- parent.activeObj.textSettings.bold = true;
17531
- parent.activeObj.textSettings.italic = false;
17830
+ textSettings.bold = true;
17831
+ textSettings.italic = false;
17832
+ textSettings.underline = false;
17833
+ textSettings.strikethrough = false;
17532
17834
  break;
17533
17835
  case 'italic':
17534
- parent.activeObj.textSettings.bold = false;
17535
- parent.activeObj.textSettings.italic = true;
17836
+ textSettings.bold = false;
17837
+ textSettings.italic = true;
17838
+ textSettings.underline = false;
17839
+ textSettings.strikethrough = false;
17536
17840
  break;
17537
17841
  case 'bolditalic':
17538
- parent.activeObj.textSettings.bold = true;
17539
- parent.activeObj.textSettings.italic = true;
17842
+ textSettings.bold = true;
17843
+ textSettings.italic = true;
17844
+ textSettings.underline = false;
17845
+ textSettings.strikethrough = false;
17846
+ break;
17847
+ case 'underline':
17848
+ textSettings.bold = false;
17849
+ textSettings.italic = false;
17850
+ textSettings.underline = true;
17851
+ textSettings.strikethrough = false;
17852
+ break;
17853
+ case 'boldunderline':
17854
+ textSettings.bold = true;
17855
+ textSettings.italic = false;
17856
+ textSettings.underline = true;
17857
+ textSettings.strikethrough = false;
17858
+ break;
17859
+ case 'italicunderline':
17860
+ textSettings.bold = false;
17861
+ textSettings.italic = true;
17862
+ textSettings.underline = true;
17863
+ textSettings.strikethrough = false;
17864
+ break;
17865
+ case 'bolditalicunderline':
17866
+ textSettings.bold = true;
17867
+ textSettings.italic = true;
17868
+ textSettings.underline = true;
17869
+ textSettings.strikethrough = false;
17870
+ break;
17871
+ case 'strikethrough':
17872
+ textSettings.bold = false;
17873
+ textSettings.italic = false;
17874
+ textSettings.underline = false;
17875
+ textSettings.strikethrough = true;
17876
+ break;
17877
+ case 'boldstrikethrough':
17878
+ textSettings.bold = true;
17879
+ textSettings.italic = false;
17880
+ textSettings.underline = false;
17881
+ textSettings.strikethrough = true;
17882
+ break;
17883
+ case 'italicstrikethrough':
17884
+ textSettings.bold = false;
17885
+ textSettings.italic = true;
17886
+ textSettings.underline = false;
17887
+ textSettings.strikethrough = true;
17888
+ break;
17889
+ case 'underlinestrikethrough':
17890
+ textSettings.bold = false;
17891
+ textSettings.italic = false;
17892
+ textSettings.underline = true;
17893
+ textSettings.strikethrough = true;
17894
+ break;
17895
+ case 'bolditalicstrikethrough':
17896
+ textSettings.bold = true;
17897
+ textSettings.italic = true;
17898
+ textSettings.underline = false;
17899
+ textSettings.strikethrough = true;
17900
+ break;
17901
+ case 'boldunderlinestrikethrough':
17902
+ textSettings.bold = true;
17903
+ textSettings.italic = false;
17904
+ textSettings.underline = true;
17905
+ textSettings.strikethrough = true;
17906
+ break;
17907
+ case 'italicunderlinestrikethrough':
17908
+ textSettings.bold = false;
17909
+ textSettings.italic = true;
17910
+ textSettings.underline = true;
17911
+ textSettings.strikethrough = true;
17912
+ break;
17913
+ case 'bolditalicunderlinestrikethrough':
17914
+ textSettings.bold = true;
17915
+ textSettings.italic = true;
17916
+ textSettings.underline = true;
17917
+ textSettings.strikethrough = true;
17540
17918
  break;
17541
17919
  }
17542
17920
  const isTextArea = parent.textArea.style.display === 'none' ? false : true;
@@ -17544,14 +17922,16 @@ class Shape {
17544
17922
  let width;
17545
17923
  if (!isTextArea) {
17546
17924
  width = this.upperContext.measureText(parent.activeObj.keyHistory).width +
17547
- parent.activeObj.textSettings.fontSize * 0.5;
17925
+ textSettings.fontSize * 0.5;
17548
17926
  }
17549
17927
  else {
17550
17928
  width = this.upperContext.measureText(parent.textArea.value).width +
17551
- parent.activeObj.textSettings.fontSize * 0.5;
17929
+ textSettings.fontSize * 0.5;
17552
17930
  }
17553
- parent.activeObj.textSettings.bold = tempBold;
17554
- parent.activeObj.textSettings.italic = tempItalic;
17931
+ textSettings.bold = tempBold;
17932
+ textSettings.italic = tempItalic;
17933
+ textSettings.underline = tempUnderline;
17934
+ textSettings.strikethrough = tempStrikethrough;
17555
17935
  return width;
17556
17936
  }
17557
17937
  getRedactObjDetails(obj) {
@@ -17630,6 +18010,12 @@ class Shape {
17630
18010
  if (obj.textSettings.italic) {
17631
18011
  shapeDetails.fontStyle.push('italic');
17632
18012
  }
18013
+ if (obj.textSettings.underline) {
18014
+ shapeDetails.fontStyle.push('underline');
18015
+ }
18016
+ if (obj.textSettings.strikethrough) {
18017
+ shapeDetails.fontStyle.push('strikethrough');
18018
+ }
17633
18019
  shapeDetails.degree = obj.rotatedAngle * (180 / Math.PI);
17634
18020
  parent.notify('selection', { prop: 'updateTransColl', onPropertyChange: false, value: { obj: transformObj, object: obj } });
17635
18021
  shapeDetails.transformCollection = transformObj['coll'];
@@ -17929,6 +18315,7 @@ class Shape {
17929
18315
  this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
17930
18316
  parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false });
17931
18317
  parent.notify('toolbar', { prop: 'refresh-main-toolbar', onPropertyChange: false });
18318
+ parent.notify('undo-redo', { prop: 'updateCurrUrc', value: { type: 'ok' } });
17932
18319
  }
17933
18320
  }
17934
18321
  getMaxText(isTextBox, text, obj) {
@@ -19344,40 +19731,40 @@ class Transform {
19344
19731
  destWidth: parent.img.destWidth, destHeight: parent.img.destHeight };
19345
19732
  if (parent.activeObj.shape) {
19346
19733
  const maxDimension = this.setZoomDimension(-0.1, parent.activeObj);
19347
- if (!isNullOrUndefined(zoomOut)) {
19348
- const actPoint = parent.activeObj.activePoint;
19349
- if (parent.transform.straighten === 0) {
19350
- if (parent.img.destLeft > actPoint.startX || parent.img.destTop >
19351
- actPoint.startY || parent.img.destLeft + parent.img.destWidth <
19352
- actPoint.endX || parent.img.destTop + parent.img.destHeight < actPoint.endY
19353
- || zoomFactor === minZoomFactor) {
19354
- zoomOut.classList.add('e-disabled');
19355
- zoomOut.parentElement.classList.add('e-overlay');
19356
- isDisabled = true;
19357
- }
19358
- else {
19359
- zoomOut.classList.remove('e-disabled');
19360
- zoomOut.parentElement.classList.remove('e-overlay');
19361
- isDisabled = false;
19362
- }
19734
+ const actPoint = parent.activeObj.activePoint;
19735
+ if (parent.transform.straighten === 0) {
19736
+ if (parent.img.destLeft > actPoint.startX || parent.img.destTop >
19737
+ actPoint.startY || parent.img.destLeft + parent.img.destWidth <
19738
+ actPoint.endX || parent.img.destTop + parent.img.destHeight < actPoint.endY
19739
+ || zoomFactor === minZoomFactor) {
19740
+ isDisabled = true;
19363
19741
  }
19364
19742
  else {
19365
- parent.img.destWidth = maxDimension.width;
19366
- parent.img.destHeight = maxDimension.height;
19367
- const obj = { isIntersect: null };
19368
- parent.notify('draw', { prop: 'updateImgCanvasPoints', onPropertyChange: false });
19369
- parent.notify('draw', { prop: 'isLinesIntersect', onPropertyChange: false, value: { obj: obj } });
19370
- if (obj['isIntersect'] ||
19371
- zoomFactor === minZoomFactor) {
19372
- zoomOut.classList.add('e-disabled');
19373
- zoomOut.parentElement.classList.add('e-overlay');
19374
- isDisabled = true;
19375
- }
19376
- else {
19377
- zoomOut.classList.remove('e-disabled');
19378
- zoomOut.parentElement.classList.remove('e-overlay');
19379
- isDisabled = false;
19380
- }
19743
+ isDisabled = false;
19744
+ }
19745
+ }
19746
+ else {
19747
+ parent.img.destWidth = maxDimension.width;
19748
+ parent.img.destHeight = maxDimension.height;
19749
+ const obj = { isIntersect: null };
19750
+ parent.notify('draw', { prop: 'updateImgCanvasPoints', onPropertyChange: false });
19751
+ parent.notify('draw', { prop: 'isLinesIntersect', onPropertyChange: false, value: { obj: obj } });
19752
+ if (obj['isIntersect'] ||
19753
+ zoomFactor === minZoomFactor) {
19754
+ isDisabled = true;
19755
+ }
19756
+ else {
19757
+ isDisabled = false;
19758
+ }
19759
+ }
19760
+ if (zoomOut) {
19761
+ if (isDisabled) {
19762
+ zoomOut.classList.add('e-disabled');
19763
+ zoomOut.parentElement.classList.add('e-overlay');
19764
+ }
19765
+ else {
19766
+ zoomOut.classList.remove('e-disabled');
19767
+ zoomOut.parentElement.classList.remove('e-overlay');
19381
19768
  }
19382
19769
  }
19383
19770
  }
@@ -19413,7 +19800,7 @@ class Transform {
19413
19800
  maxDimension.width += (maxDimension.width * parent.transform.zoomFactor);
19414
19801
  maxDimension.height += (maxDimension.height * parent.transform.zoomFactor);
19415
19802
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - maxDimension.width) / 2;
19416
- parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height + 1) / 2;
19803
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height) / 2;
19417
19804
  }
19418
19805
  parent.notify('draw', { prop: 'draw-image-to-canvas', value: { dimension: maxDimension } });
19419
19806
  maxDimension.width = this.cropDimension.width;
@@ -20137,7 +20524,7 @@ class Transform {
20137
20524
  maxDimension.height += (maxDimension.height * parent.transform.defaultZoomFactor);
20138
20525
  }
20139
20526
  parent.img.destLeft = (parent.lowerCanvas.clientWidth - maxDimension.width) / 2;
20140
- parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height + 1) / 2;
20527
+ parent.img.destTop = (parent.lowerCanvas.clientHeight - maxDimension.height) / 2;
20141
20528
  if (parent.transform.degree === 0 && parent.transform.currFlipState === '') {
20142
20529
  if (parent.transform.defaultZoomFactor > 0) {
20143
20530
  parent.img.destLeft += parent.panPoint.totalPannedPoint.x;
@@ -20246,11 +20633,11 @@ class Transform {
20246
20633
  const object = { toolbarHeight: 0 };
20247
20634
  const parent = this.parent;
20248
20635
  parent.notify('toolbar', { prop: 'getToolbarHeight', value: { obj: object } });
20249
- let canvasMaxWidth = isImgShape ? parent.element.clientWidth / 3 :
20250
- parent.element.clientWidth;
20251
- let canvasMaxHeight = isImgShape ? (parent.element.clientHeight - object['toolbarHeight']) / 3 :
20252
- parent.element.clientHeight - (object['toolbarHeight']); // 1px border
20253
- canvasMaxHeight = Browser.isDevice ? canvasMaxHeight - (object['toolbarHeight']) : canvasMaxHeight; // 1px border
20636
+ const newWidth = parent.imageSettings.width ? parent.imageSettings.width : parent.element.clientWidth;
20637
+ const newHeight = parent.imageSettings.height ? parent.imageSettings.height : parent.element.clientHeight - (object['toolbarHeight']);
20638
+ let canvasMaxWidth = isImgShape ? parent.element.clientWidth / 3 : newWidth;
20639
+ let canvasMaxHeight = isImgShape ? (parent.element.clientHeight - object['toolbarHeight']) / 3 : newHeight;
20640
+ canvasMaxHeight = Browser.isDevice ? canvasMaxHeight - (object['toolbarHeight']) : canvasMaxHeight;
20254
20641
  if (Browser.isDevice && parent.isStraightening) {
20255
20642
  const cxtTbar = parent.element.querySelector('#' + parent.element.id + '_contextualToolbarArea');
20256
20643
  canvasMaxHeight -= cxtTbar ? cxtTbar.clientHeight : 0;
@@ -20258,7 +20645,8 @@ class Transform {
20258
20645
  if (!isImgShape && parent.element.clientHeight === 0) {
20259
20646
  canvasMaxHeight = 0;
20260
20647
  }
20261
- if (isNullOrUndefined(isImgShape)) {
20648
+ const isImageSettings = parent.imageSettings.width && parent.imageSettings.height ? true : false;
20649
+ if (isNullOrUndefined(isImgShape) && !(isImageSettings)) {
20262
20650
  if (canvasMaxWidth > 30) {
20263
20651
  canvasMaxWidth -= 30;
20264
20652
  }
@@ -20483,6 +20871,9 @@ class Transform {
20483
20871
  this.zoomAction(.0125, null, true, true);
20484
20872
  }
20485
20873
  }
20874
+ if (parent.isPublicMethod && parent.aspectWidth === width && parent.aspectHeight === height) {
20875
+ return;
20876
+ }
20486
20877
  this.resizeImg(activeObj, width, height);
20487
20878
  width = tempwidth;
20488
20879
  height = tempheight;
@@ -20528,9 +20919,12 @@ class Transform {
20528
20919
  value: { type: 'custom', startX: null, startY: null, width: null, height: null } });
20529
20920
  }
20530
20921
  if (isNullOrUndefined(parent.currSelectionPoint)) {
20531
- parent.notify('draw', { prop: 'select', onPropertyChange: false,
20532
- value: { type: 'custom', startX: parent.img.destLeft, startY: parent.img.destTop,
20533
- width: parent.img.destWidth, height: parent.img.destHeight } });
20922
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
20923
+ if (!parent.shapeColl.some((item) => item.rotatedAngle && item.rotatedAngle !== 0)) {
20924
+ parent.notify('draw', { prop: 'select', onPropertyChange: false,
20925
+ value: { type: 'custom', startX: parent.img.destLeft, startY: parent.img.destTop,
20926
+ width: parent.img.destWidth, height: parent.img.destHeight } });
20927
+ }
20534
20928
  }
20535
20929
  else {
20536
20930
  parent.notify('draw', { prop: 'select', onPropertyChange: false,
@@ -20711,6 +21105,8 @@ class UndoRedo {
20711
21105
  this.tempUndoRedoColl = [];
20712
21106
  this.tempUndoRedoStep = 0;
20713
21107
  this.isPreventing = false;
21108
+ this.preventEditComplete = false;
21109
+ this.preventApplyEditComplete = false;
20714
21110
  this.parent = parent;
20715
21111
  this.addEventListener();
20716
21112
  }
@@ -20792,6 +21188,12 @@ class UndoRedo {
20792
21188
  case 'reset':
20793
21189
  this.reset();
20794
21190
  break;
21191
+ case 'preventEditComplete':
21192
+ args.value['obj']['bool'] = this.preventEditComplete;
21193
+ break;
21194
+ case 'preventApplyEditComplete':
21195
+ this.preventApplyEditComplete = args.value['bool'];
21196
+ break;
20795
21197
  }
20796
21198
  }
20797
21199
  getModuleName() {
@@ -20806,6 +21208,7 @@ class UndoRedo {
20806
21208
  this.tempUndoRedoColl = [];
20807
21209
  this.tempUndoRedoStep = 0;
20808
21210
  this.isPreventing = false;
21211
+ this.preventEditComplete = this.preventApplyEditComplete = false;
20809
21212
  }
20810
21213
  refreshUrc(refreshToolbar) {
20811
21214
  const parent = this.parent;
@@ -21517,6 +21920,10 @@ class UndoRedo {
21517
21920
  textArea.style.color = obj.strokeSettings.strokeColor;
21518
21921
  textArea.style.fontWeight = obj.textSettings.bold ? 'bold' : 'normal';
21519
21922
  textArea.style.fontStyle = obj.textSettings.italic ? 'italic' : 'normal';
21923
+ textArea.style.textDecoration = (obj.textSettings.underline && obj.textSettings.strikethrough) ? 'underline line-through' :
21924
+ (obj.textSettings.underline) ? 'underline' :
21925
+ (obj.textSettings.strikethrough) ? 'line-through' :
21926
+ 'none';
21520
21927
  textArea.style.border = '2px solid ' + parent.themeColl[parent.theme]['primaryColor'];
21521
21928
  textArea.value = obj.keyHistory;
21522
21929
  parent.activeObj = extend({}, obj, {}, true);
@@ -21850,6 +22257,7 @@ class UndoRedo {
21850
22257
  const temp = parent.noPushUndo;
21851
22258
  parent.noPushUndo = false;
21852
22259
  parent.isUndoRedoStack = true;
22260
+ this.preventEditComplete = true;
21853
22261
  if (isPenDraw) {
21854
22262
  const tempTogglePen = parent.togglePen;
21855
22263
  const obj = { freehandDrawSelectedId: null };
@@ -21878,7 +22286,14 @@ class UndoRedo {
21878
22286
  parent.enableTextEditing();
21879
22287
  }
21880
22288
  }
21881
- parent.isUndoRedoStack = false;
22289
+ if (this.preventEditComplete) {
22290
+ parent.isUndoRedoStack = this.preventEditComplete = false;
22291
+ if (!this.preventApplyEditComplete) {
22292
+ this.triggerActionCompletedEvent('shape-customize');
22293
+ }
22294
+ this.triggerActionCompletedEvent('shape-select');
22295
+ }
22296
+ parent.isUndoRedoStack = this.preventEditComplete = false;
21882
22297
  }
21883
22298
  }
21884
22299
  }
@@ -22135,6 +22550,12 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22135
22550
  this.tempRedactBlur = 50;
22136
22551
  /** @hidden */
22137
22552
  this.tempRedactPixel = 40;
22553
+ /** @hidden */
22554
+ this.imageSettings = { width: null, height: null };
22555
+ /** @hidden */
22556
+ this.aspectRatioBaseDimension = false;
22557
+ /** @hidden */
22558
+ this.imageLoaded = false;
22138
22559
  this.tempToolbarHeight = 0;
22139
22560
  this.tempToolbar = [];
22140
22561
  ImageEditor_1.Inject(Crop, Draw, Selection, Transform, Export, ToolbarModule);
@@ -22236,11 +22657,13 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22236
22657
  break;
22237
22658
  case 'disabled':
22238
22659
  if (newProperties.disabled) {
22239
- this.element.classList.add('e-disabled');
22660
+ this.element.classList.add('e-disabled', 'e-overlay');
22661
+ this.element.style.opacity = '0.5';
22240
22662
  this.unwireEvent();
22241
22663
  }
22242
22664
  else {
22243
- this.element.classList.remove('e-disabled');
22665
+ this.element.classList.remove('e-disabled', 'e-overlay');
22666
+ this.element.style.opacity = '1';
22244
22667
  this.wireEvent();
22245
22668
  }
22246
22669
  break;
@@ -22358,7 +22781,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22358
22781
  if (newProperties.uploadSettings) {
22359
22782
  this.uploadSettings = newProperties.uploadSettings;
22360
22783
  if (!this.uploadSettings.allowedExtensions) {
22361
- this.uploadSettings.allowedExtensions = '.jpg, .jpeg, .png, .svg, .webp';
22784
+ this.uploadSettings.allowedExtensions = '.jpg, .jpeg, .png, .svg, .webp, .bmp';
22362
22785
  this.notify('draw', { prop: 'setNullExtension', value: { extension: true } });
22363
22786
  }
22364
22787
  else {
@@ -22407,6 +22830,10 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22407
22830
  this.element.innerHTML = '';
22408
22831
  }
22409
22832
  initialize() {
22833
+ if (this.disabled) {
22834
+ this.element.classList.add('e-disabled', 'e-overlay');
22835
+ this.element.style.opacity = '0.5';
22836
+ }
22410
22837
  if (this.toolbarTemplate) {
22411
22838
  this.element.appendChild(this.createElement('div', {
22412
22839
  id: this.element.id + '_toolbarArea', className: 'e-toolbar-area'
@@ -22418,7 +22845,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22418
22845
  this.notify('toolbar', { prop: 'create-contextual-toolbar', onPropertyChange: false });
22419
22846
  }
22420
22847
  if (!this.uploadSettings.allowedExtensions) {
22421
- this.setProperties({ uploadSettings: { allowedExtensions: '.jpg, .jpeg, .png, .svg, .webp' } }, true);
22848
+ this.setProperties({ uploadSettings: { allowedExtensions: '.jpg, .jpeg, .png, .svg, .webp, .bmp' } }, true);
22422
22849
  }
22423
22850
  else {
22424
22851
  this.notify('draw', { prop: 'setNullExtension', value: { extension: false } });
@@ -22618,7 +23045,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22618
23045
  * @returns {string[]}.
22619
23046
  */
22620
23047
  getExtensionArray() {
22621
- const validExtensions = ['jpeg', 'jpg', 'png', 'svg', 'webp'];
23048
+ const validExtensions = ['jpeg', 'jpg', 'png', 'svg', 'webp', 'bmp'];
22622
23049
  const split = this.uploadSettings.allowedExtensions.split(',');
22623
23050
  const extension = [];
22624
23051
  for (const ext of split) {
@@ -22668,6 +23095,9 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22668
23095
  case 'webp':
22669
23096
  words += ' WebP,';
22670
23097
  break;
23098
+ case 'bmp':
23099
+ words += ' BMP,';
23100
+ break;
22671
23101
  }
22672
23102
  if (i === extension.length - 1) {
22673
23103
  words = words.slice(0, -1);
@@ -22956,10 +23386,16 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22956
23386
  */
22957
23387
  flip(direction) {
22958
23388
  this.applyShapes();
22959
- this.updateImageTransformColl(direction.toLowerCase() + 'flip');
22960
- this.notify('transform', { prop: 'flip', value: { direction: direction } });
22961
- this.notify('draw', { prop: 'redrawDownScale' });
22962
- this.notify('undo-redo', { prop: 'updateCurrUrc', value: { type: 'ok' } });
23389
+ if (this.activeObj.shape && this.activeObj.shape.indexOf('crop') > -1) {
23390
+ this.transformSelect(direction.toLowerCase() + 'flip');
23391
+ }
23392
+ else {
23393
+ this.updateImageTransformColl(direction.toLowerCase() + 'flip');
23394
+ this.setRotateZoom();
23395
+ this.notify('transform', { prop: 'flip', value: { direction: direction } });
23396
+ this.notify('draw', { prop: 'redrawDownScale' });
23397
+ this.notify('undo-redo', { prop: 'updateCurrUrc', value: { type: 'ok' } });
23398
+ }
22963
23399
  const actionArgs = { action: 'flip', actionEventArgs: this.editCompleteArgs };
22964
23400
  this.triggerEditCompleteEvent(actionArgs);
22965
23401
  }
@@ -22998,7 +23434,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
22998
23434
  *
22999
23435
  * @param {string | ImageData } data - Specifies url of the image or image data.
23000
23436
  * @param {boolean} [resetChanges=true] - Optional. Determines whether to reset existing changes when opening the image. The default value is true, which resets all existing changes.
23001
- * @param {ImageSettings} imageSettings - Optional. Specifies the image setting that contains background color to apply when opening a transparent image. The default value of background color is an empty string (''), meaning no background color is applied by default when a transparent image is opened.
23437
+ * @param {ImageSettings} imageSettings - Optional. Specifies image settings to apply when loading an image.
23002
23438
  *
23003
23439
  * @remarks
23004
23440
  * The supported file types are JPG, JPEG, PNG, and SVG.
@@ -23008,14 +23444,85 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23008
23444
  open(data, resetChanges, imageSettings) {
23009
23445
  resetChanges = isNullOrUndefined(resetChanges) ? true : resetChanges;
23010
23446
  if (resetChanges) {
23011
- if (isNullOrUndefined(data)) {
23447
+ if (isNullOrUndefined(data) || this.disabled) {
23012
23448
  return;
23013
23449
  }
23014
23450
  const dropArea = document.getElementById(this.element.id + '_dropArea');
23015
23451
  if (dropArea) {
23016
23452
  dropArea.style.display = 'none';
23017
23453
  }
23018
- this.notify('draw', { prop: 'open', value: { data: data } });
23454
+ this.imageSettings = { width: null, height: null };
23455
+ this.aspectRatioBaseDimension = null;
23456
+ if (imageSettings && (imageSettings.width || imageSettings.height)) {
23457
+ const tempImageSettings = extend({}, imageSettings, {}, true);
23458
+ imageSettings = this.scaleToFit(imageSettings);
23459
+ this.aspectRatioBaseDimension = imageSettings.isAspectRatio;
23460
+ if (!imageSettings.isAspectRatio && imageSettings.width && imageSettings.height) {
23461
+ this.imageSettings.width = imageSettings.width;
23462
+ this.imageSettings.height = imageSettings.height;
23463
+ this.notify('draw', { prop: 'open', value: { data: data } });
23464
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23465
+ const intervalId = setInterval(() => {
23466
+ if (this.imageLoaded && this.baseImg.width && this.baseImg.height) {
23467
+ this.setInitialZoomLevel(tempImageSettings);
23468
+ clearInterval(intervalId);
23469
+ }
23470
+ }, 1);
23471
+ }
23472
+ else if (imageSettings.width || imageSettings.height) {
23473
+ this.notify('draw', { prop: 'open', value: { data: data } });
23474
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23475
+ const intervalId = setInterval(() => {
23476
+ if (this.imageLoaded && this.baseImg.width && this.baseImg.height) {
23477
+ this.imageSettings.width = imageSettings.width;
23478
+ this.imageSettings.height = imageSettings.height;
23479
+ const originalWidth = this.baseImg.width;
23480
+ const originalHeight = this.baseImg.height;
23481
+ let maxValue = '';
23482
+ let aspectRatioValue;
23483
+ let value;
23484
+ let newValue;
23485
+ if (imageSettings.width && imageSettings.height) {
23486
+ maxValue = imageSettings.width > imageSettings.height ? 'width' : 'height';
23487
+ }
23488
+ if (maxValue === 'width' || (imageSettings.width && maxValue !== 'height')) {
23489
+ aspectRatioValue = imageSettings.width;
23490
+ value = aspectRatioValue / (originalWidth / originalHeight);
23491
+ newValue = value % 1 >= 0.5 || value % 1 <= -0.5 ? Math.round(value) : (value < 0) ? Math.ceil(value) : Math.floor(value);
23492
+ if (!imageSettings.height || newValue > imageSettings.height) {
23493
+ this.imageSettings.height = imageSettings.height = newValue;
23494
+ }
23495
+ else {
23496
+ aspectRatioValue = imageSettings.height;
23497
+ value = aspectRatioValue / (originalHeight / originalWidth);
23498
+ newValue = value % 1 >= 0.5 || value % 1 <= -0.5 ? Math.round(value) : (value < 0) ? Math.ceil(value) : Math.floor(value);
23499
+ this.imageSettings.width = imageSettings.width = newValue;
23500
+ }
23501
+ }
23502
+ else if (maxValue === 'height' || (imageSettings.height && maxValue !== 'width')) {
23503
+ aspectRatioValue = imageSettings.height;
23504
+ value = aspectRatioValue / (originalHeight / originalWidth);
23505
+ newValue = value % 1 >= 0.5 || value % 1 <= -0.5 ? Math.round(value) : (value < 0) ? Math.ceil(value) : Math.floor(value);
23506
+ if (!imageSettings.width || newValue > imageSettings.width) {
23507
+ this.imageSettings.width = imageSettings.width = newValue;
23508
+ }
23509
+ else {
23510
+ aspectRatioValue = imageSettings.width;
23511
+ value = aspectRatioValue / (originalWidth / originalHeight);
23512
+ newValue = value % 1 >= 0.5 || value % 1 <= -0.5 ? Math.round(value) : (value < 0) ? Math.ceil(value) : Math.floor(value);
23513
+ this.imageSettings.height = imageSettings.height = newValue;
23514
+ }
23515
+ }
23516
+ this.notify('draw', { prop: 'open', value: { data: data } });
23517
+ this.setInitialZoomLevel(tempImageSettings);
23518
+ clearInterval(intervalId);
23519
+ }
23520
+ }, 1);
23521
+ }
23522
+ }
23523
+ else {
23524
+ this.notify('draw', { prop: 'open', value: { data: data } });
23525
+ }
23019
23526
  }
23020
23527
  else {
23021
23528
  this.updateImage(data, imageSettings ? imageSettings.backgroundColor : null);
@@ -23169,11 +23676,18 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23169
23676
  rotate(degree) {
23170
23677
  const obj = { isRotate: false };
23171
23678
  this.applyShapes();
23172
- if (degree === 90 || degree === -90) {
23173
- this.updateImageTransformColl(degree === 90 ? 'rotateright' : 'rotateleft');
23679
+ if (this.activeObj.shape && this.activeObj.shape.indexOf('crop') > -1) {
23680
+ this.transformSelect(degree === 90 ? 'rotateright' : 'rotateleft');
23681
+ obj['isRotate'] = true;
23682
+ }
23683
+ else {
23684
+ if (degree === 90 || degree === -90) {
23685
+ this.updateImageTransformColl(degree === 90 ? 'rotateright' : 'rotateleft');
23686
+ }
23687
+ this.setRotateZoom();
23688
+ this.notify('transform', { prop: 'rotate', value: { degree: degree, obj: obj } });
23689
+ this.notify('draw', { prop: 'redrawDownScale' });
23174
23690
  }
23175
- this.notify('transform', { prop: 'rotate', value: { degree: degree, obj: obj } });
23176
- this.notify('draw', { prop: 'redrawDownScale' });
23177
23691
  const actionArgs = { action: 'rotate', actionEventArgs: this.editCompleteArgs };
23178
23692
  this.triggerEditCompleteEvent(actionArgs);
23179
23693
  return obj['isRotate'];
@@ -23191,7 +23705,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23191
23705
  * @returns {void}.
23192
23706
  */
23193
23707
  export(type, fileName, imageQuality) {
23194
- this.applyShapes();
23708
+ this.manageActiveAction();
23195
23709
  this.notify('export', { prop: 'export', onPropertyChange: false, value: { type: type, fileName: fileName, imgQuality: imageQuality } });
23196
23710
  }
23197
23711
  /**
@@ -23299,6 +23813,17 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23299
23813
  */
23300
23814
  zoom(zoomFactor, zoomPoint) {
23301
23815
  this.isZoomBtnClick = true;
23816
+ let prevZoom = this.transform.zoomFactor;
23817
+ if (prevZoom !== 0) {
23818
+ const zoomObj = { previousZoomValue: null };
23819
+ this.notify('transform', { prop: 'getPreviousZoomValue', value: { obj: zoomObj } });
23820
+ prevZoom = zoomObj.previousZoomValue;
23821
+ }
23822
+ if (zoomFactor !== 1 && prevZoom !== 0 && ((prevZoom < 1 && zoomFactor > 1) || (prevZoom > 1 && zoomFactor < 1))) {
23823
+ this.notify('transform', { prop: 'zoom', onPropertyChange: false,
23824
+ value: { zoomFactor: 1, zoomPoint }
23825
+ });
23826
+ }
23302
23827
  this.notify('transform', { prop: 'zoom', onPropertyChange: false,
23303
23828
  value: { zoomFactor: zoomFactor, zoomPoint: zoomPoint } });
23304
23829
  this.notify('draw', { prop: 'redrawDownScale' });
@@ -23461,10 +23986,12 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23461
23986
  * @param {string} strokeColor - Specifies the outline color of the text annotation.
23462
23987
  * @param {number} strokeWidth - Specifies the outline stroke width of the text annotation.
23463
23988
  * @param {TransformationCollection[]} transformCollection - Specifies the transform collection of the text annotation.
23989
+ * @param {boolean} underline - Specifies whether the text should be underlined.
23990
+ * @param {boolean} strikethrough - Specifies whether the text should have a strikethrough.
23464
23991
  * @returns {boolean}.
23465
23992
  *
23466
23993
  */
23467
- drawText(x, y, text, fontFamily, fontSize, bold, italic, color, isSelected, degree, fillColor, strokeColor, strokeWidth, transformCollection) {
23994
+ drawText(x, y, text, fontFamily, fontSize, bold, italic, color, isSelected, degree, fillColor, strokeColor, strokeWidth, transformCollection, underline, strikethrough) {
23468
23995
  let isText = false;
23469
23996
  const isPointsInRange = this.allowShape(x, y);
23470
23997
  if (!this.disabled && this.isImageLoaded && (isPointsInRange || (isNullOrUndefined(x) && isNullOrUndefined(y)))) {
@@ -23472,7 +23999,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23472
23999
  this.manageActiveAction();
23473
24000
  this.notify('shape', { prop: 'drawText', onPropertyChange: false, value: { x: x, y: y, text: text, fontFamily: fontFamily,
23474
24001
  fontSize: fontSize, bold: bold, italic: italic, color: color, isSelected: isSelected, degree: degree, fillColor: fillColor,
23475
- outlineColor: strokeColor, outlineWidth: strokeWidth, transformCollection: transformCollection } });
24002
+ outlineColor: strokeColor, outlineWidth: strokeWidth, transformCollection: transformCollection, underline: underline, strikethrough: strikethrough } });
23476
24003
  this.editCompleted();
23477
24004
  }
23478
24005
  return isText;
@@ -23497,14 +24024,27 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23497
24024
  let isImage = false;
23498
24025
  const isPointsInRange = this.allowShape(x, y);
23499
24026
  if (!this.disabled && this.isImageLoaded && (isPointsInRange || (isNullOrUndefined(x) && isNullOrUndefined(y)))) {
24027
+ if (typeof data === 'string') {
24028
+ try {
24029
+ const request = new XMLHttpRequest();
24030
+ const isBlob = data.indexOf('blob:') === 0;
24031
+ request.open(isBlob ? 'GET' : 'HEAD', data, false);
24032
+ request.send();
24033
+ isImage = request.status >= 200 && request.status < 300;
24034
+ }
24035
+ catch (error) {
24036
+ isImage = false;
24037
+ }
24038
+ }
24039
+ else if (data instanceof ImageData) {
24040
+ if (data.data instanceof Uint8ClampedArray && data.width > 0 && data.height > 0) {
24041
+ isImage = true;
24042
+ }
24043
+ }
23500
24044
  this.manageActiveAction();
23501
- const length = this.objColl.length;
23502
24045
  this.notify('shape', { prop: 'drawImage', onPropertyChange: false, value: { x: x, y: y, width: width, height: height,
23503
24046
  src: data, degree: degree, isAspectRatio: isAspectRatio, opacity: opacity, isSelected: isSelected } });
23504
24047
  this.editCompleted();
23505
- if (this.objColl.length > length) {
23506
- isImage = true;
23507
- }
23508
24048
  }
23509
24049
  return isImage;
23510
24050
  }
@@ -23629,6 +24169,8 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23629
24169
  this.applyShapes();
23630
24170
  this.notify('shape', { prop: 'deleteShape', onPropertyChange: false, value: { id: id, isShape: true } });
23631
24171
  this.editCompleted('shape-delete');
24172
+ this.notify('draw', { prop: 'clearOuterCanvas', onPropertyChange: false, value: { context: this.lowerContext } });
24173
+ this.notify('draw', { prop: 'clearOuterCanvas', onPropertyChange: false, value: { context: this.upperContext } });
23632
24174
  }
23633
24175
  /**
23634
24176
  * Get particular shapes details based on id of the shape which is drawn on an image editor.
@@ -23840,6 +24382,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23840
24382
  let isResized = false;
23841
24383
  if (((width.toString()).length <= 4 && (height.toString()).length <= 4) && (!this.isCircleCrop || isAspectRatio)) {
23842
24384
  this.manageActiveAction();
24385
+ this.isPublicMethod = true;
23843
24386
  this.notify('toolbar', { prop: 'resizeClick', value: { bool: false } });
23844
24387
  const destPoints = { startX: this.img.destLeft, startY: this.img.destTop, width: this.img.destWidth,
23845
24388
  height: this.img.destHeight };
@@ -23875,6 +24418,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
23875
24418
  else {
23876
24419
  this.notify('draw', { prop: 'performCancel', value: { isContextualToolbar: null } });
23877
24420
  }
24421
+ this.isPublicMethod = false;
23878
24422
  this.notify('draw', { prop: 'redrawDownScale' });
23879
24423
  }
23880
24424
  return isResized;
@@ -24378,6 +24922,69 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
24378
24922
  }
24379
24923
  }
24380
24924
  // Toolbar related codes
24925
+ scaleToFit(imageSettings) {
24926
+ const tempImageSettings = extend({}, imageSettings, {}, true);
24927
+ const viewPortWidth = this.lowerCanvas.clientWidth;
24928
+ const viewPortHeight = this.lowerCanvas.clientHeight;
24929
+ if (imageSettings.width && imageSettings.height && (imageSettings.width > viewPortWidth ||
24930
+ imageSettings.height > viewPortHeight)) {
24931
+ const widthScale = viewPortWidth / imageSettings.width;
24932
+ const heightScale = viewPortHeight / imageSettings.height;
24933
+ const scale = Math.min(widthScale, heightScale);
24934
+ tempImageSettings.width = Math.round(imageSettings.width * scale);
24935
+ tempImageSettings.height = Math.round(imageSettings.height * scale);
24936
+ }
24937
+ else if (imageSettings.width && imageSettings.width > viewPortWidth) {
24938
+ const scale = viewPortWidth / imageSettings.width;
24939
+ tempImageSettings.width = Math.round(imageSettings.width * scale);
24940
+ }
24941
+ else if (imageSettings.height && imageSettings.height > viewPortHeight) {
24942
+ const scale = viewPortHeight / imageSettings.height;
24943
+ tempImageSettings.height = Math.round(imageSettings.height * scale);
24944
+ }
24945
+ return tempImageSettings;
24946
+ }
24947
+ setInitialZoomLevel(oldImageSettings) {
24948
+ let zoomLevel = 1;
24949
+ let newWidth = this.img.destWidth;
24950
+ let newHeight = this.img.destHeight;
24951
+ const oldWidth = oldImageSettings.width;
24952
+ const oldHeight = oldImageSettings.height;
24953
+ const dimObj = { width: 0, height: 0 };
24954
+ this.notify('transform', { prop: 'calcMaxDimension', onPropertyChange: false,
24955
+ value: { width: this.img.srcWidth, height: this.img.srcHeight, obj: dimObj, isImgShape: null } });
24956
+ while ((newWidth && oldWidth && oldWidth > newWidth) || (newHeight && oldHeight && oldHeight > newHeight)) {
24957
+ newWidth = dimObj['width'] + (dimObj['width'] * 0.025 * zoomLevel);
24958
+ newHeight = dimObj['height'] + (dimObj['height'] * 0.025 * zoomLevel);
24959
+ if (Math.abs(newWidth) >= Math.abs(oldWidth) && Math.abs(newHeight) >= Math.abs(oldHeight)) {
24960
+ break;
24961
+ }
24962
+ zoomLevel++;
24963
+ }
24964
+ if (zoomLevel > 1) {
24965
+ this.isImageLoaded = true;
24966
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24967
+ const intervalId = setInterval(() => {
24968
+ if (this.imageLoaded) {
24969
+ for (let i = 1; i < zoomLevel; i++) {
24970
+ if (Math.round(i / 4) < this.zoomSettings.maxZoomFactor) {
24971
+ this.notify('transform', { prop: 'zoomAction', onPropertyChange: false,
24972
+ value: { zoomFactor: 0.025, zoomPoint: null, isResize: true } });
24973
+ }
24974
+ else {
24975
+ zoomLevel = i;
24976
+ break;
24977
+ }
24978
+ }
24979
+ this.setProperties({ zoomSettings: { zoomFactor: Math.round(zoomLevel / 4) } }, true);
24980
+ this.notify('transform', { prop: 'setPreviousZoomValue', onPropertyChange: false,
24981
+ value: { previousZoomValue: this.zoomSettings.zoomFactor } });
24982
+ this.notify('toolbar', { prop: 'enable-disable-btns' });
24983
+ clearInterval(intervalId);
24984
+ }
24985
+ }, 1);
24986
+ }
24987
+ }
24381
24988
  resetToolbar() {
24382
24989
  if (this.toolbarHeight !== this.tempToolbarHeight && !((isNullOrUndefined(this.toolbar) ||
24383
24990
  (this.toolbar && this.toolbar.length > 0)
@@ -24392,6 +24999,14 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
24392
24999
  this.update();
24393
25000
  }
24394
25001
  }
25002
+ setRotateZoom() {
25003
+ if (this.transform.zoomFactor > 0) {
25004
+ this.notify('draw', { prop: 'setRotateZoom', onPropertyChange: false, value: { isRotateZoom: true } });
25005
+ }
25006
+ else {
25007
+ this.notify('draw', { prop: 'setRotateZoom', onPropertyChange: false, value: { isRotateZoom: false } });
25008
+ }
25009
+ }
24395
25010
  getData(isMaskImage) {
24396
25011
  if (isMaskImage) {
24397
25012
  this.resetToolbar();
@@ -25028,6 +25643,11 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
25028
25643
  }
25029
25644
  }
25030
25645
  triggerEditCompleteEvent(args) {
25646
+ const obj = { bool: false };
25647
+ this.notify('undo-redo', { prop: 'preventEditComplete', value: { obj: obj } });
25648
+ if (obj['bool']) {
25649
+ return;
25650
+ }
25031
25651
  if (args.action === 'shape-insert' && args.actionEventArgs &&
25032
25652
  args.actionEventArgs.currentShapeSettings &&
25033
25653
  args.actionEventArgs.currentShapeSettings.type.toString() === 'Redact') {
@@ -26316,9 +26936,17 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
26316
26936
  this.notify('crop', { prop: 'calcRatio', onPropertyChange: false,
26317
26937
  value: { obj: obj, dimension: { width: ctx.canvas.width, height: ctx.canvas.height } } });
26318
26938
  }
26319
- let dimension;
26320
- // eslint-disable-next-line prefer-const
26321
- dimension = this.getRotatedCanvasDim(this.baseImg.width, this.baseImg.height, this.transform.straighten);
26939
+ let width = this.baseImg.width;
26940
+ let height = this.baseImg.height;
26941
+ if (!this.aspectRatioBaseDimension && this.imageSettings.width && this.imageSettings.height) {
26942
+ const widthRatio = this.baseImg.width / this.imageSettings.width;
26943
+ const heightRatio = this.baseImg.height / this.imageSettings.height;
26944
+ let ratio = (widthRatio + heightRatio) / 2;
26945
+ ratio = ratio < 1 ? 1 : ratio;
26946
+ width = this.imageSettings.width * ratio;
26947
+ height = this.imageSettings.height * ratio;
26948
+ }
26949
+ const dimension = this.getRotatedCanvasDim(width, height, this.transform.straighten);
26322
26950
  this.img.srcWidth = ctx.canvas.width = dimension.width;
26323
26951
  this.img.srcHeight = ctx.canvas.height = dimension.height;
26324
26952
  const x = ctx.canvas.width / 2;
@@ -26326,7 +26954,7 @@ let ImageEditor = ImageEditor_1 = class ImageEditor extends Component {
26326
26954
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
26327
26955
  ctx.translate(x, y);
26328
26956
  ctx.rotate(straighten * Math.PI / 180);
26329
- ctx.drawImage(this.baseImg, -this.baseImg.width / 2, -this.baseImg.height / 2, this.baseImg.width, this.baseImg.height);
26957
+ ctx.drawImage(this.baseImg, -width / 2, -height / 2, width, height);
26330
26958
  ctx.setTransform(1, 0, 0, 1, 0, 0);
26331
26959
  const obj = { width: 0, height: 0 };
26332
26960
  this.notify('crop', { prop: 'calcRatio', onPropertyChange: false, value: { obj: obj, dimension: { width: ctx.canvas.width, height: ctx.canvas.height } } });
@@ -26642,6 +27270,8 @@ var FileType;
26642
27270
  FileType["Svg"] = "Svg";
26643
27271
  /** The WebP file type. */
26644
27272
  FileType["WebP"] = "WebP";
27273
+ /** The BMP file type. */
27274
+ FileType["Bmp"] = "Bmp";
26645
27275
  })(FileType || (FileType = {}));
26646
27276
  /**
26647
27277
  * An enumeration representing the direction of an image editor operation.
@@ -27018,7 +27648,9 @@ class ToolbarModule {
27018
27648
  Path: 'Path',
27019
27649
  Bold: 'Bold',
27020
27650
  Italic: 'Italic',
27651
+ Underline: 'Underline',
27021
27652
  BoldItalic: 'Bold Italic',
27653
+ Strikethrough: 'Strikethrough',
27022
27654
  XSmall: 'X-Small',
27023
27655
  Small: 'Small',
27024
27656
  Medium: 'Medium',
@@ -27330,7 +27962,17 @@ class ToolbarModule {
27330
27962
  }
27331
27963
  reset() {
27332
27964
  const parent = this.parent;
27333
- this.toolbarHeight = 46;
27965
+ if (isNullOrUndefined(parent.toolbar) || (parent.toolbar && parent.toolbar.length > 0) || parent.toolbarTemplate) {
27966
+ if (parent.toolbarTemplate) {
27967
+ this.toolbarHeight = parent.element.querySelector('#' + parent.element.id + '_toolbarArea').clientHeight;
27968
+ }
27969
+ else {
27970
+ this.toolbarHeight = 46;
27971
+ }
27972
+ }
27973
+ else {
27974
+ this.toolbarHeight = 0;
27975
+ }
27334
27976
  parent.prevCurrSelectionPoint = null;
27335
27977
  this.zoomBtnHold = null;
27336
27978
  this.currToolbar = '';
@@ -29082,12 +29724,16 @@ class ToolbarModule {
29082
29724
  if (!Browser.isDevice) {
29083
29725
  const obj = { shape: null };
29084
29726
  parent.notify('selection', { prop: 'getCurrentDrawingShape', value: { obj: obj } });
29085
- if (obj['shape'] !== 'path') {
29727
+ if (obj['shape'] === 'path') {
29728
+ toolbarItems.push({ id: id + '_ok', prefixIcon: 'e-icons e-check', cssClass: 'top-icon e-tick',
29729
+ tooltipText: this.l10n.getConstant('OK'), align: 'Right', tabIndex: 0, disabled: true });
29730
+ }
29731
+ else {
29086
29732
  toolbarItems.push({ id: id + '_ok', prefixIcon: 'e-icons e-check', cssClass: 'top-icon e-tick',
29087
29733
  tooltipText: this.l10n.getConstant('OK'), align: 'Right', tabIndex: 0 });
29088
- toolbarItems.push({ id: id + '_cancel', prefixIcon: 'e-icons e-close', cssClass: 'top-icon e-save',
29089
- tooltipText: this.l10n.getConstant('Cancel'), align: 'Right' });
29090
29734
  }
29735
+ toolbarItems.push({ id: id + '_cancel', prefixIcon: 'e-icons e-close', cssClass: 'top-icon e-save',
29736
+ tooltipText: this.l10n.getConstant('Cancel'), align: 'Right' });
29091
29737
  }
29092
29738
  return toolbarItems;
29093
29739
  }
@@ -29735,6 +30381,14 @@ class ToolbarModule {
29735
30381
  toolbarItems.push({ id: id + '_italic', prefixIcon: 'e-icons e-italic', cssClass: 'top-icon e-italic',
29736
30382
  tooltipText: this.l10n.getConstant('Italic'), align: 'Center' });
29737
30383
  }
30384
+ if (items.indexOf('underline') > -1) {
30385
+ toolbarItems.push({ id: id + '_underline', prefixIcon: 'e-icons e-underline', cssClass: 'top-icon e-underline',
30386
+ tooltipText: this.l10n.getConstant('Underline'), align: 'Center' });
30387
+ }
30388
+ if (items.indexOf('strikethrough') > -1) {
30389
+ toolbarItems.push({ id: id + '_strikethrough', prefixIcon: 'e-icons e-strikethrough', cssClass: 'top-icon e-strikethrough',
30390
+ tooltipText: this.l10n.getConstant('Strikethrough'), align: 'Center' });
30391
+ }
29738
30392
  if (items.indexOf('strokeWidth') > -1) {
29739
30393
  toolbarItems.push({ id: id + '_strokeWidth', cssClass: 'top-icon e-size', tooltipText: this.l10n.getConstant('TextOutlineWidth'), align: 'Center',
29740
30394
  type: 'Input', template: '<button id="' + id + '_borderWidthBtn"></button>' });
@@ -30212,6 +30866,12 @@ class ToolbarModule {
30212
30866
  }
30213
30867
  if (Browser.isDevice) {
30214
30868
  this.initMainToolbar(false, true, true);
30869
+ const okBtn = document.getElementById(parent.element.id + '_ok');
30870
+ const drawingObject = { shape: '' };
30871
+ parent.notify('selection', { prop: 'getCurrentDrawingShape', onPropertyChange: false, value: { obj: drawingObject } });
30872
+ if (drawingObject['shape'] === 'path' && okBtn) {
30873
+ okBtn.classList.add('e-overlay');
30874
+ }
30215
30875
  }
30216
30876
  if (parent.activeObj.shape === 'line' || parent.activeObj.shape === 'path') {
30217
30877
  args.toolbarItems = ['strokeColor', 'strokeWidth', 'z-order', 'duplicate', 'remove'];
@@ -30243,7 +30903,7 @@ class ToolbarModule {
30243
30903
  if (Browser.isDevice) {
30244
30904
  this.initMainToolbar(false, true, true);
30245
30905
  }
30246
- args.toolbarItems = ['fontFamily', 'fontSize', 'fontColor', 'fillColor', 'strokeColor', 'strokeWidth', 'bold', 'italic', 'z-order', 'duplicate', 'remove', 'text'];
30906
+ args.toolbarItems = ['fontFamily', 'fontSize', 'fontColor', 'fillColor', 'strokeColor', 'strokeWidth', 'bold', 'italic', 'underline', 'strikethrough', 'z-order', 'duplicate', 'remove', 'text'];
30247
30907
  this.initTextToolbarItem(args.toolbarItems);
30248
30908
  break;
30249
30909
  case 'pen':
@@ -30379,8 +31039,13 @@ class ToolbarModule {
30379
31039
  parent.notify('transform', { prop: 'getPanMove', onPropertyChange: false,
30380
31040
  value: { obj: panMoveObj } });
30381
31041
  if (panMoveObj['panMove']) {
31042
+ const currentPannedPoint = extend({}, parent.panPoint.currentPannedPoint, {}, true);
31043
+ parent.panPoint.currentPannedPoint = { x: parent.panPoint.totalPannedClientPoint.x, y: parent.panPoint.totalPannedClientPoint.y };
31044
+ parent.panPoint.totalPannedClientPoint = { x: 0, y: 0 };
31045
+ parent.panPoint.totalPannedInternalPoint = { x: 0, y: 0 };
30382
31046
  parent.notify('transform', { prop: 'drawPannedImage', onPropertyChange: false,
30383
- value: { xDiff: null, yDiff: null } });
31047
+ value: { xDiff: parent.panPoint.currentPannedPoint.x, yDiff: parent.panPoint.currentPannedPoint.y } });
31048
+ parent.panPoint.currentPannedPoint = currentPannedPoint;
30384
31049
  }
30385
31050
  }
30386
31051
  updateKBDNavigation(type) {
@@ -32354,60 +33019,10 @@ class ToolbarModule {
32354
33019
  }
32355
33020
  break;
32356
33021
  case 'bold':
32357
- parent.notify('selection', { prop: 'setInitialTextEdit', value: { bool: false } });
32358
- if (parent.activeObj.textSettings.bold && parent.activeObj.textSettings.italic) {
32359
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32360
- value: { item: 'italic' } });
32361
- }
32362
- else if (parent.activeObj.textSettings.bold && !parent.activeObj.textSettings.italic) {
32363
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32364
- value: { item: 'default' } });
32365
- }
32366
- else if (!parent.activeObj.textSettings.bold && parent.activeObj.textSettings.italic) {
32367
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32368
- value: { item: 'bolditalic' } });
32369
- }
32370
- else if (!parent.activeObj.textSettings.bold && !parent.activeObj.textSettings.italic) {
32371
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32372
- value: { item: 'bold' } });
32373
- }
32374
- if (parent.element.querySelector('#' + id + '_bold').classList.contains('e-selected-btn')) {
32375
- parent.element.querySelector('#' + id + '_bold').classList.remove('e-selected-btn');
32376
- }
32377
- else {
32378
- parent.element.querySelector('#' + id + '_bold').classList.add('e-selected-btn');
32379
- }
32380
- if (parent.activeObj.activePoint.width !== 0 || parent.activeObj.activePoint.height !== 0) {
32381
- parent.notify('undo-redo', { prop: 'updateUndoRedoStack', onPropertyChange: false });
32382
- }
32383
- break;
32384
33022
  case 'italic':
32385
- parent.notify('selection', { prop: 'setInitialTextEdit', value: { bool: false } });
32386
- if (parent.activeObj.textSettings.bold && parent.activeObj.textSettings.italic) {
32387
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32388
- value: { item: 'bold' } });
32389
- }
32390
- else if (parent.activeObj.textSettings.bold && !parent.activeObj.textSettings.italic) {
32391
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32392
- value: { item: 'bolditalic' } });
32393
- }
32394
- else if (!parent.activeObj.textSettings.bold && parent.activeObj.textSettings.italic) {
32395
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32396
- value: { item: 'default' } });
32397
- }
32398
- else if (!parent.activeObj.textSettings.bold && !parent.activeObj.textSettings.italic) {
32399
- parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false,
32400
- value: { item: 'italic' } });
32401
- }
32402
- if (parent.element.querySelector('#' + id + '_italic').classList.contains('e-selected-btn')) {
32403
- parent.element.querySelector('#' + id + '_italic').classList.remove('e-selected-btn');
32404
- }
32405
- else {
32406
- parent.element.querySelector('#' + id + '_italic').classList.add('e-selected-btn');
32407
- }
32408
- if (parent.activeObj.activePoint.width !== 0 || parent.activeObj.activePoint.height !== 0) {
32409
- parent.notify('undo-redo', { prop: 'updateUndoRedoStack', onPropertyChange: false });
32410
- }
33023
+ case 'underline':
33024
+ case 'strikethrough':
33025
+ this.toggleStyle(id, type);
32411
33026
  break;
32412
33027
  case 'croptransform':
32413
33028
  this.performCropTransformClick();
@@ -32588,6 +33203,43 @@ class ToolbarModule {
32588
33203
  }
32589
33204
  }
32590
33205
  }
33206
+ getFontStyle(settings) {
33207
+ const parts = [];
33208
+ if (settings.bold) {
33209
+ parts.push('bold');
33210
+ }
33211
+ if (settings.italic) {
33212
+ parts.push('italic');
33213
+ }
33214
+ if (settings.underline) {
33215
+ parts.push('underline');
33216
+ }
33217
+ if (settings.strikethrough) {
33218
+ parts.push('strikethrough');
33219
+ }
33220
+ return parts.length === 0 ? 'default' : parts.join('');
33221
+ }
33222
+ toggleStyle(id, style) {
33223
+ const parent = this.parent;
33224
+ parent.notify('selection', { prop: 'setInitialTextEdit', value: { bool: false } });
33225
+ const settings = parent.activeObj.textSettings;
33226
+ settings[style] = !settings[style];
33227
+ const fontStyle = this.getFontStyle(settings);
33228
+ parent.notify('shape', { prop: 'applyFontStyle', onPropertyChange: false, value: { item: fontStyle } });
33229
+ const button = parent.element.querySelector(`#${id}_${style}`);
33230
+ if (button) {
33231
+ if (button.classList.contains('e-selected-btn')) {
33232
+ button.classList.remove('e-selected-btn');
33233
+ }
33234
+ else {
33235
+ button.classList.add('e-selected-btn');
33236
+ }
33237
+ }
33238
+ if (parent.activeObj.activePoint.width !== 0 ||
33239
+ parent.activeObj.activePoint.height !== 0) {
33240
+ parent.notify('undo-redo', { prop: 'updateUndoRedoStack', onPropertyChange: false });
33241
+ }
33242
+ }
32591
33243
  updateRedactType(value) {
32592
33244
  const parent = this.parent;
32593
33245
  parent.activeObj.redactType = value;
@@ -32606,7 +33258,7 @@ class ToolbarModule {
32606
33258
  if (parent.currObjType.isFiltered || parent.currObjType.isRedact) {
32607
33259
  parent.okBtn();
32608
33260
  }
32609
- if (frame && !frame.classList.contains('e-overlay')) {
33261
+ if (!frame || !frame.classList.contains('e-overlay')) {
32610
33262
  zoom = parent.transform.zoomFactor;
32611
33263
  parent.frameDestPoints = extend({}, parent.img, {}, true);
32612
33264
  if (isNullOrUndefined(parent.cxtTbarHeight)) {
@@ -32615,7 +33267,10 @@ class ToolbarModule {
32615
33267
  this.callFrameToolbar();
32616
33268
  parent.frameObj.type = 'mat';
32617
33269
  this.callFrameToolbar();
32618
- parent.cxtTbarHeight = parent.element.querySelector('#' + id + '_customizeWrapper').scrollHeight;
33270
+ const elem = parent.element.querySelector('#' + id + '_customizeWrapper');
33271
+ if (elem) {
33272
+ parent.cxtTbarHeight = elem.scrollHeight;
33273
+ }
32619
33274
  parent.frameObj = frameObj;
32620
33275
  parent.tempFrameObj = tempFrameObj;
32621
33276
  }
@@ -33178,6 +33833,8 @@ class ToolbarModule {
33178
33833
  const fontSizeElem = parent.element.querySelector('.e-text-font-size');
33179
33834
  const boldBtn = parent.element.querySelector('#' + id + '_bold');
33180
33835
  const italicBtn = parent.element.querySelector('#' + id + '_italic');
33836
+ const underlineBtn = parent.element.querySelector('#' + id + '_underline');
33837
+ const strikethroughBtn = parent.element.querySelector('#' + id + '_strikethrough');
33181
33838
  if (parent.activeObj.strokeSettings && parent.activeObj.textSettings) {
33182
33839
  if (isNullOrUndefined(parent.activeObj.strokeSettings.strokeWidth)) {
33183
33840
  parent.activeObj.strokeSettings.strokeWidth = 2;
@@ -33290,6 +33947,22 @@ class ToolbarModule {
33290
33947
  italicBtn.classList.remove('e-selected-btn');
33291
33948
  }
33292
33949
  }
33950
+ if (underlineBtn) {
33951
+ if (parent.activeObj.textSettings.underline) {
33952
+ underlineBtn.classList.add('e-selected-btn');
33953
+ }
33954
+ else {
33955
+ underlineBtn.classList.remove('e-selected-btn');
33956
+ }
33957
+ }
33958
+ if (strikethroughBtn) {
33959
+ if (parent.activeObj.textSettings.strikethrough) {
33960
+ strikethroughBtn.classList.add('e-selected-btn');
33961
+ }
33962
+ else {
33963
+ strikethroughBtn.classList.remove('e-selected-btn');
33964
+ }
33965
+ }
33293
33966
  if (strokeWidthElem) {
33294
33967
  const width = parent.activeObj.shape === 'text' ? parent.activeObj.strokeSettings.outlineWidth : parent.activeObj.strokeSettings.strokeWidth;
33295
33968
  const strokeWidth = Math.round(width).toString();
@@ -33305,25 +33978,23 @@ class ToolbarModule {
33305
33978
  getStrokeWidth(text) {
33306
33979
  let strokeWidth;
33307
33980
  const currentWidth = parseInt(text, 10) / 2;
33308
- switch (currentWidth) {
33309
- case 0:
33310
- strokeWidth = this.l10n.getConstant('NoOutline');
33311
- break;
33312
- case 1:
33313
- strokeWidth = this.l10n.getConstant('XSmall');
33314
- break;
33315
- case 2:
33316
- strokeWidth = this.l10n.getConstant('Small');
33317
- break;
33318
- case 3:
33319
- strokeWidth = this.l10n.getConstant('Medium');
33320
- break;
33321
- case 4:
33322
- strokeWidth = this.l10n.getConstant('Large');
33323
- break;
33324
- case 5:
33325
- strokeWidth = this.l10n.getConstant('XLarge');
33326
- break;
33981
+ if (currentWidth === 0) {
33982
+ strokeWidth = this.l10n.getConstant('NoOutline');
33983
+ }
33984
+ else if (currentWidth > 0 && currentWidth <= 1) {
33985
+ strokeWidth = this.l10n.getConstant('XSmall');
33986
+ }
33987
+ else if (currentWidth > 1 && currentWidth <= 2) {
33988
+ strokeWidth = this.l10n.getConstant('Small');
33989
+ }
33990
+ else if (currentWidth > 2 && currentWidth <= 3) {
33991
+ strokeWidth = this.l10n.getConstant('Medium');
33992
+ }
33993
+ else if (currentWidth > 3 && currentWidth <= 4) {
33994
+ strokeWidth = this.l10n.getConstant('Large');
33995
+ }
33996
+ else {
33997
+ strokeWidth = this.l10n.getConstant('XLarge');
33327
33998
  }
33328
33999
  return strokeWidth;
33329
34000
  }