@syncfusion/ej2-image-editor 30.2.4 → 31.1.17

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 (48) hide show
  1. package/dist/ej2-image-editor.umd.min.js +2 -2
  2. package/dist/ej2-image-editor.umd.min.js.map +1 -1
  3. package/dist/es6/ej2-image-editor.es2015.js +3 -3
  4. package/dist/es6/ej2-image-editor.es2015.js.map +1 -1
  5. package/dist/es6/ej2-image-editor.es5.js +3 -3
  6. package/dist/es6/ej2-image-editor.es5.js.map +1 -1
  7. package/dist/global/ej2-image-editor.min.js +2 -2
  8. package/dist/global/ej2-image-editor.min.js.map +1 -1
  9. package/dist/global/index.d.ts +1 -1
  10. package/dist/ts/image-editor/action/crop.d.ts +44 -0
  11. package/dist/ts/image-editor/action/crop.ts +867 -0
  12. package/dist/ts/image-editor/action/draw.d.ts +187 -0
  13. package/dist/ts/image-editor/action/draw.ts +4924 -0
  14. package/dist/ts/image-editor/action/export.d.ts +29 -0
  15. package/dist/ts/image-editor/action/export.ts +509 -0
  16. package/dist/ts/image-editor/action/filter.d.ts +48 -0
  17. package/dist/ts/image-editor/action/filter.ts +872 -0
  18. package/dist/ts/image-editor/action/freehand-draw.d.ts +68 -0
  19. package/dist/ts/image-editor/action/freehand-draw.ts +1135 -0
  20. package/dist/ts/image-editor/action/index.d.ts +9 -0
  21. package/dist/ts/image-editor/action/index.ts +9 -0
  22. package/dist/ts/image-editor/action/selection.d.ts +178 -0
  23. package/dist/ts/image-editor/action/selection.ts +5241 -0
  24. package/dist/ts/image-editor/action/shape.d.ts +130 -0
  25. package/dist/ts/image-editor/action/shape.ts +3917 -0
  26. package/dist/ts/image-editor/action/transform.d.ts +77 -0
  27. package/dist/ts/image-editor/action/transform.ts +2008 -0
  28. package/dist/ts/image-editor/action/undo-redo.d.ts +52 -0
  29. package/dist/ts/image-editor/action/undo-redo.ts +1169 -0
  30. package/dist/ts/image-editor/base/enum.d.ts +277 -0
  31. package/dist/ts/image-editor/base/enum.ts +288 -0
  32. package/dist/ts/image-editor/base/image-editor-model.d.ts +770 -0
  33. package/dist/ts/image-editor/base/image-editor.d.ts +1928 -0
  34. package/dist/ts/image-editor/base/image-editor.ts +5496 -0
  35. package/dist/ts/image-editor/base/index.d.ts +4 -0
  36. package/dist/ts/image-editor/base/index.ts +4 -0
  37. package/dist/ts/image-editor/base/interface.d.ts +1637 -0
  38. package/dist/ts/image-editor/base/interface.ts +1709 -0
  39. package/dist/ts/image-editor/index.d.ts +3 -0
  40. package/dist/ts/image-editor/index.ts +3 -0
  41. package/dist/ts/image-editor/renderer/index.d.ts +1 -0
  42. package/dist/ts/image-editor/renderer/index.ts +1 -0
  43. package/dist/ts/image-editor/renderer/toolbar.d.ts +171 -0
  44. package/dist/ts/image-editor/renderer/toolbar.ts +6356 -0
  45. package/dist/ts/index.d.ts +4 -0
  46. package/dist/ts/index.ts +4 -0
  47. package/package.json +47 -15
  48. package/src/image-editor/action/undo-redo.js +3 -3
@@ -0,0 +1,1169 @@
1
+ import { isNullOrUndefined, extend } from '@syncfusion/ej2-base';
2
+ import { EditCompleteEventArgs , Adjustment, CurrentObject, FrameValue, ImageEditor, Point, SelectionPoint, Transition, ZoomSettings } from '../index';
3
+ import { Dimension } from '@syncfusion/ej2-inputs';
4
+
5
+ export class UndoRedo {
6
+ private parent: ImageEditor;
7
+ private lowerContext: CanvasRenderingContext2D;
8
+ private upperContext: CanvasRenderingContext2D;
9
+ private tempCurrSelPoint: SelectionPoint;
10
+ private undoRedoStep: number = 0;
11
+ private undoRedoColl: Transition[] = [];
12
+ private appliedUndoRedoColl: Transition[] = [];
13
+ private tempUndoRedoColl: Transition[] = [];
14
+ private tempUndoRedoStep: number = 0;
15
+ private tempActObj: SelectionPoint; // For text editing undo redo
16
+ private isPreventing: boolean = false;
17
+ private preventEditComplete: boolean = false;
18
+ private preventApplyEditComplete: boolean = false;
19
+
20
+ constructor(parent: ImageEditor) {
21
+ this.parent = parent;
22
+ this.addEventListener();
23
+ }
24
+
25
+ public destroy(): void {
26
+ if (this.parent.isDestroyed) { return; }
27
+ this.removeEventListener();
28
+ }
29
+
30
+ private addEventListener(): void {
31
+ this.parent.on('undo-redo', this.undoRedo, this);
32
+ this.parent.on('destroyed', this.destroy, this);
33
+ }
34
+
35
+ private removeEventListener(): void {
36
+ this.parent.off('undo-redo', this.undoRedo);
37
+ this.parent.off('destroyed', this.destroy);
38
+ }
39
+
40
+ private initializeUrPvtProp(): void {
41
+ if (this.parent.lowerCanvas) {this.lowerContext = this.parent.lowerCanvas.getContext('2d'); }
42
+ if (this.parent.upperCanvas) {this.upperContext = this.parent.upperCanvas.getContext('2d'); }
43
+ }
44
+
45
+ private undoRedo(args?: { onPropertyChange?: boolean, prop: string, value?: object }): void {
46
+ this.initializeUrPvtProp();
47
+ switch (args.prop) {
48
+ case 'updateUndoRedoColl':
49
+ this.updateUrc(args.value['operation'], args.value['previousObj'],
50
+ args.value['previousObjColl'], args.value['previousPointColl'], args.value['previousSelPointColl'],
51
+ args.value['previousCropObj'], args.value['previousText'], args.value['currentText'],
52
+ args.value['previousFilter'], args.value['isCircleCrop']);
53
+ break;
54
+ case 'refreshUrc':
55
+ this.refreshUrc(args.value['bool']);
56
+ break;
57
+ case 'updateCurrUrc':
58
+ this.updateCurrUrc(args.value['type'], args.value['isCancel']);
59
+ break;
60
+ case 'call-undo':
61
+ this.callUndo();
62
+ break;
63
+ case 'call-redo':
64
+ this.callRedo();
65
+ break;
66
+ case 'undo':
67
+ this.undo();
68
+ break;
69
+ case 'redo':
70
+ this.redo();
71
+ break;
72
+ case 'updateUrObj':
73
+ this.updateUrObj(args.value['objColl'], args.value['operation']);
74
+ break;
75
+ case 'updateUndoRedo':
76
+ this.updateUndoRedo(args.value ? args.value['operation'] : null);
77
+ break;
78
+ case 'getAppliedUndoRedoColl':
79
+ args.value['obj']['appliedUndoRedoColl'] = this.appliedUndoRedoColl;
80
+ break;
81
+ case 'getUndoRedoStep':
82
+ args.value['obj']['undoRedoStep'] = this.undoRedoStep;
83
+ break;
84
+ case 'setUndoRedoStep':
85
+ this.undoRedoStep = args.value['step'];
86
+ break;
87
+ case 'undoDefault':
88
+ this.undoDefault(args.value['obj']);
89
+ break;
90
+ case 'setPreventUR':
91
+ this.isPreventing = args.value['bool'];
92
+ break;
93
+ case 'updateUndoRedoStack':
94
+ if (args.value && args.value['isPenDraw']) {
95
+ this.updateUndoRedoStack(args.value['isPenDraw']);
96
+ } else {
97
+ this.updateUndoRedoStack();
98
+ }
99
+ break;
100
+ case 'preventEditComplete':
101
+ args.value['obj']['bool'] = this.preventEditComplete;
102
+ break;
103
+ case 'preventApplyEditComplete':
104
+ this.preventApplyEditComplete = args.value['bool'];
105
+ break;
106
+ case 'reset':
107
+ this.reset();
108
+ break;
109
+ }
110
+ }
111
+
112
+ public getModuleName(): string {
113
+ return 'undo-redo';
114
+ }
115
+
116
+ private reset(): void {
117
+ this.tempCurrSelPoint = null; this.undoRedoStep = 0;
118
+ this.undoRedoColl = []; this.appliedUndoRedoColl = []; this.tempActObj = null;
119
+ this.tempUndoRedoColl = []; this.tempUndoRedoStep = 0; this.isPreventing = false;
120
+ this.preventEditComplete = this.preventApplyEditComplete = false;
121
+ }
122
+
123
+ private refreshUrc(refreshToolbar?: boolean): void {
124
+ const parent: ImageEditor = this.parent;
125
+ if (parent.isImageUpdated) {return; }
126
+ refreshToolbar = refreshToolbar ? refreshToolbar : false;
127
+ if (refreshToolbar) {
128
+ parent.notify('toolbar', { prop: 'setEnableDisableUndoRedo', value: {isPrevent: true} });
129
+ this.tempUndoRedoColl = extend([], this.appliedUndoRedoColl, [], true) as Transition[];
130
+ this.tempUndoRedoStep = this.undoRedoStep;
131
+ }
132
+ parent.notify('toolbar', { prop: 'setEnableDisableUndoRedo', value: {isPrevent: false} });
133
+ this.undoRedoColl = this.undoRedoColl.slice(0, this.undoRedoStep);
134
+ this.appliedUndoRedoColl = this.appliedUndoRedoColl.slice(0, this.undoRedoStep);
135
+ parent.isUndoRedo = parent.currObjType.isUndoAction = false;
136
+ parent.notify('toolbar', { prop: 'enable-disable-btns' });
137
+ }
138
+
139
+ private updateCurrUrc(type: string, isCancel?: boolean): void {
140
+ const parent: ImageEditor = this.parent;
141
+ if (parent.isResize || this.isPreventing || parent.noPushUndo) {return; }
142
+ parent.notify('toolbar', { prop: 'setEnableDisableUndoRedo', value: {isPrevent: false} });
143
+ if (type === 'ok') {
144
+ parent.notify('draw', { prop: 'setShapeTextInsert', onPropertyChange: false, value: {bool: false } });
145
+ const collection: Transition[] = this.tempUndoRedoColl.length > 0 ?
146
+ extend([], this.tempUndoRedoColl, [], true) as Transition[] :
147
+ extend([], this.undoRedoColl, [], true) as Transition[];
148
+ const prevObj: Transition = this.undoRedoColl[this.undoRedoColl.length - 1];
149
+ const appliedURColl: Transition = this.appliedUndoRedoColl[this.appliedUndoRedoColl.length - 1];
150
+ const prevTransform: CurrentObject = prevObj ? extend({}, prevObj.previousObj, {}, true) as CurrentObject
151
+ : null;
152
+ if (isNullOrUndefined(appliedURColl)) {
153
+ if (this.undoRedoColl[0]) {
154
+ prevObj.previousCropObj = collection[0].previousCropObj;
155
+ prevObj.previousObj = collection[0].previousObj;
156
+ prevObj.previousObjColl = collection[0].previousObjColl;
157
+ prevObj.previousPointColl = collection[0].previousPointColl;
158
+ prevObj.previousText = collection[0].previousText;
159
+ }
160
+ } else if (prevObj.operation !== 'imageHFlip' && prevObj.operation !== 'imageVFlip') {
161
+ prevObj.previousCropObj = appliedURColl.currentCropObj;
162
+ prevObj.previousObj = appliedURColl.currentObj;
163
+ prevObj.previousObjColl = appliedURColl.currentObjColl;
164
+ prevObj.previousPointColl = appliedURColl.currentPointColl;
165
+ prevObj.previousText = appliedURColl.currentText;
166
+ if (prevObj.operation === 'frame' && prevObj.previousObj && prevTransform) {
167
+ prevObj.previousObj.defaultZoom = prevTransform.defaultZoom;
168
+ prevObj.previousObj.zoomFactor = prevTransform.zoomFactor;
169
+ prevObj.previousObj.cropZoom = prevTransform.cropZoom;
170
+ }
171
+ }
172
+ if (prevObj) {
173
+ if (prevObj.operation !== 'imageHFlip' && prevObj.operation !== 'imageVFlip') {
174
+ const obj: Object = this.getZeroZoomObjPointValue(prevObj.currentObjColl, prevObj.currentPointColl);
175
+ prevObj.currentObjColl = obj['obj'];
176
+ prevObj.currentPointColl = obj['point'];
177
+ const adjObj: Object = {adjustmentLevel: null };
178
+ parent.notify('filter', { prop: 'getAdjustmentLevel', onPropertyChange: false, value: {obj: adjObj }});
179
+ prevObj.currentObj.adjustmentLevel = extend({}, adjObj['adjustmentLevel'], {}, true) as Adjustment;
180
+ parent.notify('filter', { prop: 'setTempAdjVal' });
181
+ prevObj.currentObj.currentFilter = parent.currentFilter;
182
+ }
183
+ this.appliedUndoRedoColl.push(prevObj);
184
+ if (!isCancel) {
185
+ this.triggerActionCompletedEvent(prevObj.operation);
186
+ }
187
+ }
188
+ this.tempUndoRedoColl = []; this.tempUndoRedoStep = 0;
189
+ } else if (this.tempUndoRedoColl.length > 0) {
190
+ this.appliedUndoRedoColl = extend([], this.tempUndoRedoColl, [], true) as Transition[];
191
+ this.undoRedoStep = this.tempUndoRedoStep;
192
+ this.tempUndoRedoColl = []; this.tempUndoRedoStep = 0;
193
+ }
194
+ let lastObj: Transition = this.appliedUndoRedoColl[this.appliedUndoRedoColl.length - 1];
195
+ let lastPrevObj: Transition = this.appliedUndoRedoColl[this.appliedUndoRedoColl.length - 2];
196
+ if (this.appliedUndoRedoColl.length > 16) {
197
+ this.appliedUndoRedoColl.splice(0, 1);
198
+ } else if (!isCancel && lastObj && lastPrevObj) {
199
+ if ((((lastObj.operation === 'shapeTransform' && lastPrevObj.operation === 'shapeTransform') ||
200
+ (lastObj.operation === 'shapeInsert' && lastPrevObj.operation === 'shapeInsert')) &&
201
+ JSON.stringify(lastObj.currentObjColl) === JSON.stringify(lastPrevObj.currentObjColl)) ||
202
+ (lastObj.operation === 'freehand-draw' && lastPrevObj.operation === 'freehand-draw' &&
203
+ JSON.stringify(lastObj.currentPointColl) === JSON.stringify(lastPrevObj.currentPointColl)) ||
204
+ (lastObj.operation === 'freehanddrawCustomized' && lastPrevObj.operation === 'freehanddrawCustomized' &&
205
+ JSON.stringify(lastObj.currentPointColl) === JSON.stringify(lastPrevObj.currentPointColl))) {
206
+ this.appliedUndoRedoColl.splice(this.appliedUndoRedoColl.length - 1, 1);
207
+ } else if (this.undoRedoStep !== this.appliedUndoRedoColl.length - 1) {
208
+ lastObj = this.appliedUndoRedoColl[this.appliedUndoRedoColl.length - 1];
209
+ lastPrevObj = this.appliedUndoRedoColl[this.undoRedoStep];
210
+ if (lastObj && lastPrevObj && lastObj.operation === 'shapeTransform' &&
211
+ lastPrevObj.operation === 'shapeTransform' &&
212
+ JSON.stringify(lastObj.currentObjColl) === JSON.stringify(lastPrevObj.previousObjColl)) {
213
+ this.appliedUndoRedoColl.splice(this.appliedUndoRedoColl.length - 1, 1);
214
+ this.undoRedoColl = [];
215
+ this.undoRedoColl = extend([], this.appliedUndoRedoColl, [], true) as Transition[];
216
+ return;
217
+ }
218
+ }
219
+ }
220
+ this.undoRedoColl = [];
221
+ this.undoRedoColl = extend([], this.appliedUndoRedoColl, [], true) as Transition[];
222
+ if (type === 'ok') {
223
+ this.undoRedoStep = this.undoRedoColl.length;
224
+ parent.notify('toolbar', { prop: 'enable-disable-btns' });
225
+ }
226
+ if (parent.transform.zoomFactor > 0) {
227
+ parent.togglePan = true;
228
+ parent.notify('selection', {prop: 'setDragCanvas', value: {bool: true }});
229
+ }
230
+ }
231
+
232
+ private triggerActionCompletedEvent(action: string): void {
233
+ const parent: ImageEditor = this.parent;
234
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
235
+ const actionMap: any = {'brightness': 'fine-tune', 'contrast': 'fine-tune', 'hue': 'fine-tune',
236
+ 'saturation': 'fine-tune', 'opacity': 'fine-tune', 'blur': 'fine-tune', 'exposure': 'fine-tune',
237
+ 'default': 'filter', 'chrome': 'filter', 'cold': 'filter', 'warm': 'filter',
238
+ 'grayscale': 'filter', 'sepia': 'filter', 'invert': 'filter',
239
+ 'deleteObj': 'shape-delete', 'deleteFreehandDrawing': 'freehand-draw-delete',
240
+ 'shapeInsert': 'shape-insert', 'shapeTransform': 'shape-customize',
241
+ 'freehanddrawCustomized': 'freehand-draw-customize'
242
+ };
243
+ const actionResult: string = actionMap[action as string] || action;
244
+ const actionArgs: EditCompleteEventArgs = { action: actionResult, actionEventArgs: parent.editCompleteArgs };
245
+ parent.triggerEditCompleteEvent(actionArgs);
246
+ }
247
+
248
+ private getUndoRedoAction(action: string): string {
249
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
250
+ const actionMap: any = {'brightness': 'fine-tune', 'contrast': 'fine-tune', 'hue': 'fine-tune',
251
+ 'saturation': 'fine-tune', 'opacity': 'fine-tune', 'blur': 'fine-tune', 'exposure': 'fine-tune',
252
+ 'default': 'filter', 'chrome': 'filter', 'cold': 'filter', 'warm': 'filter',
253
+ 'grayscale': 'filter', 'sepia': 'filter', 'invert': 'filter',
254
+ 'deleteObj': 'shape-delete', 'deleteFreehandDrawing': 'freehand-drawing-delete',
255
+ 'shapeInsert': 'shape-insert', 'shapeTransform': 'shape-customize', 'imageRotate': 'shape-customize',
256
+ 'freehanddraw': 'freehand-draw', 'freehanddrawCustomized': 'freehand-draw-customize',
257
+ 'textAreaCustomization': 'text-area-customization', 'imageHFlip': 'shape-customize',
258
+ 'imageVFlip': 'shape-customize', 'bgColor': 'background-color', 'updateImage': 'image-update'
259
+ };
260
+ return actionMap[action as string] || action;
261
+ }
262
+
263
+ private cancelCropSelection(): void {
264
+ const parent: ImageEditor = this.parent;
265
+ let isCropSelection: boolean = false;
266
+ let splitWords: string[];
267
+ if (parent.activeObj.shape) {splitWords = parent.activeObj.shape.split('-'); }
268
+ if (parent.currObjType.isCustomCrop || (splitWords && splitWords[0] === 'crop')) {
269
+ isCropSelection = true;
270
+ }
271
+ if (isCropSelection) {
272
+ parent.notify('draw', {prop: 'performCancel', value: {isContextualToolbar: null }});
273
+ }
274
+ if (this.tempUndoRedoColl.length !== 0 || this.tempUndoRedoStep !== 0) {
275
+ this.appliedUndoRedoColl = extend([], this.tempUndoRedoColl, [], true) as Transition[];
276
+ this.undoRedoColl = extend([], this.tempUndoRedoColl, [], true) as Transition[];
277
+ this.undoRedoStep = this.tempUndoRedoStep;
278
+ this.tempUndoRedoColl = []; this.tempUndoRedoStep = 0;
279
+ parent.notify('toolbar', { prop: 'setEnableDisableUndoRedo', value: {isPrevent: false} });
280
+ }
281
+ }
282
+
283
+ private refreshToolbarActions(): void {
284
+ const parent: ImageEditor = this.parent;
285
+ if (parent.activeObj.shape) {
286
+ parent.notify('toolbar', { prop: 'refresh-toolbar', onPropertyChange: false, value: {type: 'shapes',
287
+ isApplyBtn: null, isCropping: null, isZooming: null, cType: null}});
288
+ parent.notify('toolbar', { prop: 'update-toolbar-items', onPropertyChange: false});
289
+ } else {
290
+ parent.notify('toolbar', { prop: 'refresh-main-toolbar', onPropertyChange: false});
291
+ }
292
+ }
293
+
294
+ private applyCurrentChanges(): void {
295
+ const parent: ImageEditor = this.parent;
296
+ parent.currObjType.isFiltered = false;
297
+ if (parent.transform.zoomFactor === 0) {
298
+ parent.togglePan = false;
299
+ parent.notify('selection', {prop: 'setDragCanvas', value: {bool: false }});
300
+ }
301
+ if (parent.element.querySelector('.e-contextual-toolbar-wrapper')) {
302
+ parent.element.querySelector('.e-contextual-toolbar-wrapper').classList.add('e-hide');
303
+ }
304
+ if (parent.togglePen) {
305
+ parent.togglePen = false;
306
+ parent.upperCanvas.style.cursor = parent.cursor = 'default';
307
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
308
+ }
309
+ if (this.appliedUndoRedoColl.length > 0) {
310
+ this.undoRedoColl = extend([], this.appliedUndoRedoColl, [], true) as Transition[];
311
+ }
312
+ }
313
+
314
+ private callUndo(): void {
315
+ this.applyCurrentChanges();
316
+ this.undo();
317
+ }
318
+
319
+ private callRedo(): void {
320
+ this.applyCurrentChanges();
321
+ this.redo();
322
+ }
323
+
324
+ private undo(): void {
325
+ const parent: ImageEditor = this.parent;
326
+ this.cancelCropSelection();
327
+ parent.notify('draw', { prop: 'resetFrameZoom', onPropertyChange: false, value: {isOk: false }});
328
+ if (!parent.disabled && parent.isImageLoaded) {
329
+ if (this.undoRedoStep > 0) {
330
+ this.refreshToolbarActions();
331
+ if (parent.activeObj.activePoint && parent.activeObj.activePoint.width !== 0) {
332
+ this.tempActObj = parent.activeObj;
333
+ }
334
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false});
335
+ this.undoRedoStep--;
336
+ parent.notify('toolbar', {prop: 'enable-disable-btns'});
337
+ if (parent.element.querySelector('.e-contextual-toolbar-wrapper')) {
338
+ parent.element.querySelector('.e-contextual-toolbar-wrapper').classList.add('e-hide');
339
+ }
340
+ parent.isUndoRedo = true;
341
+ const obj: Transition = this.undoRedoColl[this.undoRedoStep];
342
+ if (this.undoRedoColl.length === this.undoRedoStep) { parent.currObjType.isUndoAction = false; }
343
+ else { parent.currObjType.isUndoAction = true; }
344
+ if (obj.operation !== 'textAreaCustomization' &&
345
+ (parent.textArea.style.display === 'block' || parent.textArea.style.display === 'inline-block')) {
346
+ parent.textArea.style.display = 'none';
347
+ }
348
+ parent.notify('draw', { prop: 'setCancelAction', onPropertyChange: false, value: {bool: true }});
349
+ let activeObj: SelectionPoint;
350
+ parent.cropObj = extend({}, obj.previousCropObj, {}, true) as CurrentObject;
351
+ parent.afterCropActions = obj.previousObj.afterCropActions;
352
+ this.lowerContext.filter = obj.previousObj.filter;
353
+ parent.notify('filter', { prop: 'setAdjustmentLevel', onPropertyChange: false, value: { adjustmentLevel: obj.previousObj.adjustmentLevel }});
354
+ parent.notify('filter', { prop: 'setTempAdjVal' });
355
+ parent.currentFilter = obj.previousObj.currentFilter;
356
+ parent.notify('filter', { prop: 'setTempFilVal' });
357
+ parent.canvasFilter = this.lowerContext.filter;
358
+ parent.initialAdjustmentValue = this.lowerContext.filter;
359
+ parent.notify('filter', { prop: 'setBevelFilter', onPropertyChange: false, value: { bevelFilter: this.lowerContext.filter }});
360
+ const editCompleteArgs: object = {action: this.getUndoRedoAction(obj.operation) };
361
+ switch (obj.operation) {
362
+ case 'shapeTransform':
363
+ case 'brightness':
364
+ case 'contrast':
365
+ case 'hue':
366
+ case 'saturation':
367
+ case 'opacity':
368
+ case 'blur':
369
+ case 'exposure':
370
+ case 'default':
371
+ case 'chrome':
372
+ case 'cold':
373
+ case 'warm':
374
+ case 'grayscale':
375
+ case 'blackandwhite':
376
+ case 'sepia':
377
+ case 'invert':
378
+ case 'sharpen':
379
+ case 'imageRotate':
380
+ case 'shapeInsert':
381
+ this.shapeTransform(obj.previousObjColl, obj.previousPointColl);
382
+ break;
383
+ case 'freehanddraw':
384
+ case 'freehand-draw':
385
+ this.updateFreehandDraw(obj.previousPointColl, obj.previousSelPointColl);
386
+ parent.notify('freehand-draw', {prop: 'setCurrentFreehandDrawIndex',
387
+ value: {value: parent.pointColl.length}});
388
+ break;
389
+ case 'freehanddrawCustomized':
390
+ this.updateFreehandDrawCustomized(obj.previousObjColl, obj.previousPointColl);
391
+ break;
392
+ case 'deleteFreehandDrawing':
393
+ case 'deleteObj':
394
+ this.updateDelete(obj.operation, obj.previousObjColl, obj.previousPointColl, obj.previousSelPointColl);
395
+ break;
396
+ case 'textAreaCustomization':
397
+ this.shapeTransform(obj.previousObjColl, obj.previousPointColl);
398
+ this.updateTextAreaCustomization(activeObj, obj.previousObjColl);
399
+ break;
400
+ case 'text':
401
+ this.updateText(obj.previousObjColl, true);
402
+ break;
403
+ case 'frame':
404
+ parent.transform.zoomFactor = parent.transform.defaultZoomFactor = obj.previousObj.defaultZoom;
405
+ parent.setProperties({zoomSettings: { zoomFactor: obj.previousObj.zoomFactor}}, true);
406
+ parent.notify('transform', { prop: 'setPreviousZoomValue', onPropertyChange: false,
407
+ value: { previousZoomValue: parent.zoomSettings.zoomFactor } });
408
+ extend(parent.frameObj, obj.previousObj.frameObj);
409
+ parent.notify('draw', {prop: 'render-image', value: {isMouseWheel: true, isPreventClearRect: null, isFrame: true } });
410
+ break;
411
+ case 'imageHFlip':
412
+ this.imageFlip('horizontal', obj.previousObjColl);
413
+ break;
414
+ case 'imageVFlip':
415
+ this.imageFlip('vertical', obj.previousObjColl);
416
+ break;
417
+ case 'bgColor':
418
+ parent.notify('draw', { prop: 'imageBackgroundColor', onPropertyChange: false, value: {color: obj.previousObj.bgColor }});
419
+ parent.notify('draw', { prop: 'render-image', value: { isMouseWheel: false } });
420
+ break;
421
+ case 'updateImage':
422
+ parent.isImageUpdated = true;
423
+ parent.baseImg.src = obj.previousObj.imageSource;
424
+ setTimeout(() => {
425
+ if (parent.cropObj.straighten !== 0) {
426
+ parent.notify('toolbar', { prop: 'performCropTransformClick', value: { shape: 'crop-' + 'custom' } });
427
+ parent.noPushUndo = true;
428
+ parent.crop();
429
+ parent.noPushUndo = false;
430
+ } else {
431
+ parent.notify('draw', { prop: 'render-image', value: { isMouseWheel: false } });
432
+ }
433
+ parent.isImageUpdated = false;
434
+ });
435
+ break;
436
+ default:
437
+ this.undoDefault(obj, true);
438
+ parent.notify('filter', { prop: 'set-adjustment', value: {operation: obj.operation}});
439
+ parent.notify('filter', { prop: 'update-filter', value: {operation: obj.operation, filter: obj.filter}});
440
+ break;
441
+ }
442
+ if (obj.operation === 'crop') {
443
+ if (obj.previousObj.currSelectionPoint) {
444
+ parent.currSelectionPoint = extend({}, obj.previousObj.currSelectionPoint, {}, true) as SelectionPoint;
445
+ if (parent.currSelectionPoint && isNullOrUndefined(parent.currSelectionPoint.shape)) {
446
+ parent.currSelectionPoint = null;
447
+ }
448
+ }
449
+ parent.updateCropTransformItems();
450
+ parent.notify('draw', { prop: 'select', onPropertyChange: false,
451
+ value: {type: 'custom', startX: null, startY: null, width: null, height: null}});
452
+ if (parent.isCircleCrop) {
453
+ parent.isCircleCrop = false;
454
+ this.tempCurrSelPoint = extend({}, parent.currSelectionPoint, {}, true) as SelectionPoint;
455
+ parent.currSelectionPoint = null;
456
+ }
457
+ const tempCircleCrop: boolean = parent.cancelCropSelection.isCircleCrop;
458
+ parent.cancelCropSelection.isCircleCrop = false;
459
+ parent.notify('draw', {prop: 'performCancel', value: {isContextualToolbar: null, isUndoRedo: true }});
460
+ parent.cancelCropSelection.isCircleCrop = tempCircleCrop;
461
+ parent.currObjType.isActiveObj = false;
462
+ if (parent.transform.straighten !== 0) {
463
+ parent.notify('draw', { prop: 'setStraightenActObj', value: {activeObj: null }});
464
+ }
465
+ } else if (obj.operation === 'resize' && parent.cropObj && parent.cropObj.activeObj) {
466
+ parent.currSelectionPoint = extend({}, parent.cropObj.activeObj, {}, true) as SelectionPoint;
467
+ }
468
+ if ((this.undoRedoColl[this.undoRedoStep - 1]
469
+ && this.undoRedoColl[this.undoRedoStep - 1].isCircleCrop)) {
470
+ parent.isCircleCrop = true;
471
+ parent.notify('crop', { prop: 'cropCircle', onPropertyChange: false,
472
+ value: {context: this.lowerContext, isSave: null, isFlip: null}});
473
+ }
474
+ this.endUndoRedo(obj.operation, true);
475
+ const action: EditCompleteEventArgs = { action: 'undo', actionEventArgs: editCompleteArgs };
476
+ parent.triggerEditCompleteEvent(action);
477
+ }
478
+ }
479
+ }
480
+
481
+ private redo(): void {
482
+ const parent: ImageEditor = this.parent;
483
+ this.cancelCropSelection();
484
+ parent.notify('draw', { prop: 'resetFrameZoom', onPropertyChange: false, value: {isOk: false }});
485
+ if (!parent.disabled && parent.isImageLoaded) {
486
+ if (this.undoRedoStep < this.appliedUndoRedoColl.length) {
487
+ this.refreshToolbarActions();
488
+ this.undoRedoStep++;
489
+ parent.notify('toolbar', {prop: 'enable-disable-btns'});
490
+ parent.isUndoRedo = true;
491
+ const obj: Transition = this.undoRedoColl[this.undoRedoStep - 1];
492
+ if (this.undoRedoColl.length === this.undoRedoStep) { parent.currObjType.isUndoAction = false; }
493
+ else { parent.currObjType.isUndoAction = true; }
494
+ if (obj.operation !== 'textAreaCustomization' &&
495
+ (parent.textArea.style.display === 'block' || parent.textArea.style.display === 'inline-block')) {
496
+ parent.textArea.style.display = 'none';
497
+ }
498
+ parent.notify('draw', { prop: 'setCancelAction', onPropertyChange: false, value: {bool: true }});
499
+ parent.cropObj = extend({}, obj.currentCropObj, {}, true) as CurrentObject;
500
+ parent.afterCropActions = obj.currentObj.afterCropActions;
501
+ this.lowerContext.filter = obj.currentObj.filter;
502
+ if (parent.element.querySelector('.e-contextual-toolbar-wrapper')) {
503
+ parent.element.querySelector('.e-contextual-toolbar-wrapper').classList.add('e-hide');
504
+ }
505
+ parent.notify('filter', { prop: 'setAdjustmentLevel', onPropertyChange: false, value: { adjustmentLevel: obj.currentObj.adjustmentLevel }});
506
+ parent.notify('filter', { prop: 'setTempAdjVal' });
507
+ parent.currentFilter = obj.currentObj.currentFilter;
508
+ parent.notify('filter', { prop: 'setTempFilVal' });
509
+ parent.canvasFilter = this.lowerContext.filter;
510
+ parent.initialAdjustmentValue = this.lowerContext.filter;
511
+ parent.notify('filter', { prop: 'setBevelFilter', onPropertyChange: false, value: { bevelFilter: this.lowerContext.filter }});
512
+ let activeObj: SelectionPoint;
513
+ const editCompleteArgs: object = {action: this.getUndoRedoAction(obj.operation) };
514
+ switch (obj.operation) {
515
+ case 'shapeTransform':
516
+ case 'brightness':
517
+ case 'contrast':
518
+ case 'hue':
519
+ case 'saturation':
520
+ case 'opacity':
521
+ case 'blur':
522
+ case 'exposure':
523
+ case 'default':
524
+ case 'chrome':
525
+ case 'cold':
526
+ case 'warm':
527
+ case 'grayscale':
528
+ case 'blackandwhite':
529
+ case 'sepia':
530
+ case 'invert':
531
+ case 'sharpen':
532
+ case 'imageRotate':
533
+ case 'shapeInsert':
534
+ this.shapeTransform(obj.currentObjColl, obj.currentPointColl);
535
+ break;
536
+ case 'freehanddraw':
537
+ case 'freehand-draw':
538
+ this.updateFreehandDraw(obj.currentPointColl, obj.currentSelPointColl);
539
+ parent.notify('freehand-draw', {prop: 'setCurrentFreehandDrawIndex',
540
+ value: {value: parent.pointColl.length}});
541
+ break;
542
+ case 'freehanddrawCustomized':
543
+ this.updateFreehandDrawCustomized(obj.currentObjColl, obj.currentPointColl);
544
+ break;
545
+ case 'deleteFreehandDrawing':
546
+ case 'deleteObj':
547
+ this.updateDelete(obj.operation, obj.currentObjColl, obj.currentPointColl, obj.currentSelPointColl);
548
+ break;
549
+ case 'textAreaCustomization':
550
+ this.shapeTransform(obj.currentObjColl, obj.currentPointColl);
551
+ this.updateTextAreaCustomization(activeObj, obj.currentObjColl);
552
+ break;
553
+ case 'text':
554
+ this.updateText(obj.currentObjColl, false);
555
+ break;
556
+ case 'frame':
557
+ extend(parent.frameObj, obj.currentObj.frameObj);
558
+ parent.notify('draw', {prop: 'render-image', value: {isMouseWheel: true, isPreventClearRect: null, isFrame: true } });
559
+ break;
560
+ case 'imageHFlip':
561
+ this.imageFlip('horizontal', obj.currentObjColl);
562
+ break;
563
+ case 'imageVFlip':
564
+ this.imageFlip('vertical', obj.currentObjColl);
565
+ break;
566
+ case 'bgColor':
567
+ parent.notify('draw', { prop: 'imageBackgroundColor', onPropertyChange: false, value: {color: obj.currentObj.bgColor }});
568
+ parent.notify('draw', { prop: 'render-image', value: { isMouseWheel: false } });
569
+ break;
570
+ case 'updateImage':
571
+ parent.isImageUpdated = true;
572
+ parent.baseImg.src = obj.currentObj.imageSource;
573
+ setTimeout(() => {
574
+ if (parent.cropObj.straighten !== 0) {
575
+ parent.notify('toolbar', { prop: 'performCropTransformClick', value: { shape: 'crop-' + 'custom' } });
576
+ parent.noPushUndo = true;
577
+ parent.crop();
578
+ parent.noPushUndo = false;
579
+ } else {
580
+ parent.notify('draw', { prop: 'render-image', value: { isMouseWheel: false } });
581
+ }
582
+ parent.isImageUpdated = false;
583
+ });
584
+ break;
585
+ default:
586
+ parent.objColl = []; parent.pointColl = []; parent.freehandCounter = 0;
587
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
588
+ value: {obj: {selPointColl: [] }}});
589
+ parent.notify('draw', { prop: 'setCurrentObj', onPropertyChange: false, value: {obj: obj.currentObj, isUndoRedo: true }});
590
+ parent.img.destLeft = obj.currentObj.destPoints.startX;
591
+ parent.img.destTop = obj.currentObj.destPoints.startY;
592
+ activeObj = extend({}, parent.activeObj, {}, true) as SelectionPoint;
593
+ parent.objColl = extend([], obj.currentObjColl, [], true) as SelectionPoint[];
594
+ parent.pointColl = extend([], obj.currentPointColl, [], true) as Point[];
595
+ parent.freehandCounter = parent.pointColl.length;
596
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
597
+ value: {obj: {selPointColl: extend([], obj.currentSelPointColl, [], true) as Point[] } }});
598
+ parent.transform.straighten = 0;
599
+ this.lowerContext.filter = 'none';
600
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
601
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
602
+ this.lowerContext.filter = obj.currentObj.filter;
603
+ parent.prevStraightenedDegree = parent.transform.straighten;
604
+ parent.activeObj = activeObj;
605
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
606
+ if (parent.activeObj.activePoint.width !== 0 && parent.activeObj.activePoint.height !== 0) {
607
+ parent.notify('draw', { prop: 'drawObject', onPropertyChange: false, value: {canvas: 'duplicate'}});
608
+ }
609
+ parent.notify('filter', { prop: 'set-adjustment', value: {operation: obj.operation}});
610
+ parent.notify('filter', { prop: 'update-filter', value: {operation: obj.operation }});
611
+ break;
612
+ }
613
+ if (obj.operation === 'crop' && obj.isCircleCrop) {
614
+ parent.isCircleCrop = true;
615
+ parent.currSelectionPoint = extend({}, this.tempCurrSelPoint, {}, true) as SelectionPoint;
616
+ this.tempCurrSelPoint = null;
617
+ }
618
+ if (obj.operation === 'crop' && !obj.isCircleCrop) {
619
+ parent.isCircleCrop = false;
620
+ }
621
+ if (obj.operation === 'crop' && obj.currentObj.currSelectionPoint) {
622
+ parent.currSelectionPoint = extend({}, obj.currentObj.currSelectionPoint, {}, true) as SelectionPoint;
623
+ parent.notify('draw', { prop: 'setStraightenActObj', value: {activeObj: parent.currSelectionPoint }});
624
+ }
625
+ if (parent.currSelectionPoint && isNullOrUndefined(parent.currSelectionPoint.shape)) {
626
+ parent.currSelectionPoint = null;
627
+ }
628
+ if (obj.operation === 'resize' && parent.cropObj && parent.cropObj.activeObj) {
629
+ parent.currSelectionPoint = extend({}, parent.cropObj.activeObj, {}, true) as SelectionPoint;
630
+ }
631
+ this.endUndoRedo(obj.operation, false);
632
+ const action: EditCompleteEventArgs = { action: 'redo', actionEventArgs: editCompleteArgs };
633
+ parent.triggerEditCompleteEvent(action);
634
+ }
635
+ }
636
+ }
637
+
638
+ private imageFlip(type: string, objColl: SelectionPoint[]): void {
639
+ const parent: ImageEditor = this.parent;
640
+ this.shapeTransform(objColl, null);
641
+ parent.activeObj = extend({}, parent.objColl[parent.objColl.length - 1], {}, true) as SelectionPoint;
642
+ const { shape, isHorImageFlip, isVerImageFlip } = parent.activeObj;
643
+ parent.objColl.pop();
644
+ if (shape && shape === 'image') {
645
+ if (type === 'horizontal') {
646
+ if (isNullOrUndefined(isHorImageFlip) && isVerImageFlip) {
647
+ parent.activeObj.isHorImageFlip = true; parent.activeObj.isVerImageFlip = null;
648
+ parent.horizontalFlip(this.upperContext, true);
649
+ } else {
650
+ if (isNullOrUndefined(isHorImageFlip) || !isHorImageFlip) {
651
+ parent.activeObj.isHorImageFlip = true;
652
+ } else {
653
+ parent.activeObj.isHorImageFlip = null;
654
+ }
655
+ parent.horizontalFlip(this.upperContext, true);
656
+ }
657
+ } else if (type === 'vertical') {
658
+ if (isNullOrUndefined(isVerImageFlip) && isHorImageFlip) {
659
+ parent.activeObj.isVerImageFlip = true; parent.activeObj.isHorImageFlip = null;
660
+ parent.verticalFlip(this.upperContext, true);
661
+ } else {
662
+ if (isNullOrUndefined(isVerImageFlip) || !isVerImageFlip) {
663
+ parent.activeObj.isVerImageFlip = true;
664
+ } else {
665
+ parent.activeObj.isVerImageFlip = null;
666
+ }
667
+ parent.verticalFlip(this.upperContext, true);
668
+ }
669
+ }
670
+ parent.notify('shape', { prop: 'applyActObj', onPropertyChange: false, value: {isMouseDown: true }});
671
+ } else {
672
+ parent.notify('draw', { prop: 'render-image', value: { isMouseWheel: true } });
673
+ }
674
+ }
675
+
676
+ private shapeTransform(objColl: SelectionPoint[], pointColl: Point[]): void {
677
+ const parent: ImageEditor = this.parent;
678
+ parent.objColl = extend([], objColl, [], true) as SelectionPoint[];
679
+ if (pointColl) {
680
+ parent.pointColl = extend([], pointColl, [], true) as Point[];
681
+ parent.freehandCounter = parent.pointColl.length;
682
+ }
683
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
684
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
685
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
686
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
687
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
688
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false});
689
+ }
690
+
691
+ private updateFreehandDraw(pointColl: Point[], selPointColl: Point[]): void {
692
+ const parent: ImageEditor = this.parent;
693
+ parent.pointColl = pointColl;
694
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
695
+ value: {obj: {selPointColl: selPointColl }}});
696
+ parent.freehandCounter = parent.pointColl.length;
697
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
698
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
699
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
700
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
701
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
702
+ }
703
+
704
+ private updateFreehandDrawCustomized(objColl: SelectionPoint[], pointColl: Point[]): void {
705
+ const parent: ImageEditor = this.parent;
706
+ parent.objColl = extend([], objColl, [], true) as SelectionPoint[];
707
+ parent.pointColl = pointColl;
708
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
709
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
710
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
711
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
712
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
713
+ }
714
+
715
+ private updateDelete(operation: string, objColl: SelectionPoint[], pointColl: Point[], selPointColl: Point[]): void {
716
+ const parent: ImageEditor = this.parent;
717
+ if (operation === 'deleteFreehandDrawing') {
718
+ parent.pointColl = pointColl;
719
+ parent.freehandCounter = parent.pointColl.length;
720
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
721
+ value: {obj: {selPointColl: selPointColl } }});
722
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
723
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
724
+ } else if (operation === 'deleteObj') {
725
+ parent.objColl = objColl as SelectionPoint[];
726
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
727
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
728
+ }
729
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
730
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
731
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
732
+ }
733
+
734
+ private updateTextAreaCustomization(activeObj: SelectionPoint, objColl: SelectionPoint[]): void {
735
+ const parent: ImageEditor = this.parent;
736
+ parent.objColl = extend([], objColl, [], true) as SelectionPoint[];
737
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
738
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
739
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
740
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
741
+ for (let i: number = 0, len: number = (objColl as SelectionPoint[]).length; i < len; i++) {
742
+ if (this.tempActObj) {
743
+ if (this.tempActObj.currIndex === (objColl as SelectionPoint[])[i as number].currIndex) {
744
+ activeObj = extend({}, objColl[i as number], {}, true) as SelectionPoint;
745
+ parent.objColl.splice(i, 1);
746
+ break;
747
+ }
748
+ } else {
749
+ activeObj = extend({}, objColl[objColl.length - 1], {}, true) as SelectionPoint;
750
+ parent.objColl.splice(i, 1);
751
+ break;
752
+ }
753
+ }
754
+ if (activeObj) { this.updateTextBox(activeObj); }
755
+ if (parent.textArea.style.display === 'block' || parent.textArea.style.display === 'inline-block') {
756
+ parent.notify('shape', { prop: 'redrawActObj', onPropertyChange: false,
757
+ value: {x: null, y: null, isMouseDown: null}});
758
+ }
759
+ }
760
+
761
+ private updateText(objColl: SelectionPoint[], allowActiveObj: boolean): void {
762
+ const parent: ImageEditor = this.parent;
763
+ if (this.tempActObj) {
764
+ parent.activeObj = extend({}, this.tempActObj, {}, true) as SelectionPoint;
765
+ }
766
+ if (objColl.length === 0 && parent.objColl.length === 1) {
767
+ this.tempActObj = extend({}, parent.objColl[0], {}, true) as SelectionPoint;
768
+ } else {
769
+ for (let i: number = 0, iLen: number = parent.objColl.length; i < iLen; i++) {
770
+ if (parent.objColl[i as number] && isNullOrUndefined(objColl[i as number])) {
771
+ this.tempActObj = extend({}, parent.objColl[i as number], {}, true) as SelectionPoint;
772
+ break;
773
+ }
774
+ if (objColl[i as number].currIndex !== parent.objColl[i as number].currIndex) {
775
+ this.tempActObj = extend({}, parent.objColl[i as number], {}, true) as SelectionPoint;
776
+ break;
777
+ }
778
+ }
779
+ }
780
+ if (allowActiveObj) {parent.activeObj = extend({}, this.tempActObj, {}, true) as SelectionPoint; }
781
+ parent.objColl = extend([], objColl, [], true) as SelectionPoint[];
782
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
783
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: true }});
784
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
785
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
786
+ parent.isUndoRedo = true; parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
787
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false});
788
+ }
789
+
790
+ private updateTextBox(obj: SelectionPoint): void {
791
+ const parent: ImageEditor = this.parent;
792
+ this.upperContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
793
+ this.lowerContext.clearRect(0, 0, parent.lowerCanvas.width, parent.lowerCanvas.height);
794
+ parent.notify('draw', { prop: 'redrawImgWithObj', onPropertyChange: false});
795
+ parent.notify('toolbar', { prop: 'destroy-qa-toolbar', onPropertyChange: false});
796
+ const textArea: HTMLInputElement = parent.textArea;
797
+ textArea.style.display = 'block';
798
+ textArea.style.fontFamily = obj.textSettings.fontFamily;
799
+ textArea.style.fontSize = obj.textSettings.fontSize + 'px';
800
+ textArea.style.color = obj.strokeSettings.strokeColor;
801
+ textArea.style.fontWeight = obj.textSettings.bold ? 'bold' : 'normal';
802
+ textArea.style.fontStyle = obj.textSettings.italic ? 'italic' : 'normal';
803
+ textArea.style.textDecoration = (obj.textSettings.underline && obj.textSettings.strikethrough) ? 'underline line-through' :
804
+ (obj.textSettings.underline) ? 'underline' :
805
+ (obj.textSettings.strikethrough) ? 'line-through' :
806
+ 'none';
807
+ textArea.style.border = '2px solid ' + parent.themeColl[parent.theme]['primaryColor'];
808
+ textArea.value = obj.keyHistory;
809
+ parent.activeObj = extend({}, obj, {}, true) as SelectionPoint;
810
+ parent.notify('shape', { prop: 'updateFontStyles', onPropertyChange: false,
811
+ value: { isTextBox: null}});
812
+ parent.textArea.style.width = parent.activeObj.activePoint.width + 'px';
813
+ }
814
+
815
+ private undoDefault(obj: Transition, isUndoRedo?: boolean): void {
816
+ this.lowerContext.filter = obj.previousObj.filter;
817
+ const parent: ImageEditor = this.parent;
818
+ parent.objColl = []; parent.pointColl = []; parent.freehandCounter = 0;
819
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
820
+ value: {obj: {selPointColl: [] } }});
821
+ const isCircleCrop: boolean = !isUndoRedo ? obj.isCircleCrop : false;
822
+ parent.notify('draw', { prop: 'setCurrentObj', onPropertyChange: false, value: {obj: obj.previousObj, isUndoRedo: isUndoRedo, isCircleCrop: isCircleCrop }});
823
+ parent.prevStraightenedDegree = parent.transform.straighten;
824
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
825
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false});
826
+ parent.img.destLeft = obj.previousObj.destPoints.startX;
827
+ parent.img.destTop = obj.previousObj.destPoints.startY;
828
+ const activeObj: SelectionPoint = extend({}, parent.activeObj, {}, true) as SelectionPoint;
829
+ parent.objColl = extend([], obj.previousObjColl, [], true) as SelectionPoint[];
830
+ parent.pointColl = extend([], obj.previousPointColl, [], true) as Point[];
831
+ parent.freehandCounter = parent.pointColl.length;
832
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
833
+ value: {obj: {selPointColl: extend([], obj.previousSelPointColl, [], true) as Point[] } }});
834
+ parent.transform.straighten = 0;
835
+ this.lowerContext.filter = 'none';
836
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
837
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: null }});
838
+ this.lowerContext.filter = obj.previousObj.filter;
839
+ parent.activeObj = activeObj;
840
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
841
+ if (parent.activeObj.activePoint.width !== 0 && parent.activeObj.activePoint.height !== 0) {
842
+ parent.notify('draw', { prop: 'drawObject', onPropertyChange: false, value: {canvas: 'duplicate'}});
843
+ }
844
+ }
845
+
846
+ private endUndoRedo(operation: string, isUndo: boolean): void {
847
+ const parent: ImageEditor = this.parent;
848
+ const frameObj: FrameValue = {type: 'none', color: '#fff', size: 20, inset: 20, offset: 20, radius: 0, amount: 1, border: 'solid', gradientColor: '' };
849
+ if (((parent.currSelectionPoint && parent.currSelectionPoint.shape === 'crop-circle') || parent.isCircleCrop) &&
850
+ JSON.stringify(parent.frameObj) !== JSON.stringify(frameObj)) {
851
+ parent.notify('draw', {prop: 'render-image', value: {isMouseWheel: true } });
852
+ }
853
+ parent.notify('draw', { prop: 'clearOuterCanvas', onPropertyChange: false, value: {context: this.lowerContext}});
854
+ if (parent.isCircleCrop && ((isUndo && operation !== 'crop') || !isUndo)) {
855
+ parent.notify('crop', { prop: 'cropCircle', onPropertyChange: false,
856
+ value: {context: this.lowerContext, isSave: null, isFlip: null}});
857
+ }
858
+ if (parent.transform.zoomFactor > 0) {
859
+ parent.notify('selection', {prop: 'setDragCanvas', value: {bool: true }});
860
+ }
861
+ parent.notify('draw', { prop: 'setCancelAction', onPropertyChange: false, value: {bool: false }});
862
+ if (parent.activeObj.shape && parent.activeObj.shape.split('-')[0] === 'crop') {
863
+ parent.notify('toolbar', { prop: 'refresh-toolbar', onPropertyChange: false, value: {type: 'main',
864
+ isApplyBtn: true, isCropping: true, isZooming: null, cType: null}});
865
+ } else {
866
+ parent.notify('toolbar', { prop: 'refresh-main-toolbar', onPropertyChange: false});
867
+ }
868
+ parent.notify('toolbar', {prop: 'enable-disable-btns'});
869
+ if (document.getElementById(parent.element.id + '_quickAccessToolbarArea')) {
870
+ document.getElementById(parent.element.id + '_quickAccessToolbarArea').style.display = 'none';
871
+ }
872
+ parent.notify('toolbar', {prop: 'enable-disable-btns'});
873
+ if (parent.transform.degree !== 0) {
874
+ parent.notify('transform', { prop: 'drawPannedImage', onPropertyChange: false,
875
+ value: {xDiff: 0, yDiff: 0 }});
876
+ }
877
+ parent.notify('filter', { prop: 'setAdjustmentValue', onPropertyChange: false, value: {adjustmentValue: this.lowerContext.filter }});
878
+ parent.currObjType.isCustomCrop = false;
879
+ }
880
+
881
+ private updateUrc(operation: string, previousObj: CurrentObject, previousObjColl: SelectionPoint[],
882
+ previousPointColl: Point[], previousSelPointColl: Point[],
883
+ previousCropObj: CurrentObject, previousText?: string,
884
+ currentText?: string, previousFilter?: string, isCircleCrop?: boolean): void {
885
+ const parent: ImageEditor = this.parent;
886
+ if (parent.isResize || this.isPreventing) {return; }
887
+ const obj: Object = {isInitialLoaded: false };
888
+ if (parent.currObjType.isUndoAction) { this.refreshUrc(true); }
889
+ parent.notify('draw', { prop: 'isInitialLoaded', onPropertyChange: false, value: {object: obj }});
890
+ if (!obj['isInitialLoaded'] && parent.allowUndoRedo) {
891
+ const object: Object = {currObj: {} as CurrentObject };
892
+ parent.notify('filter', { prop: 'getCurrentObj', onPropertyChange: false, value: {object: object }});
893
+ const currentObj: CurrentObject = object['currObj'];
894
+ currentObj.objColl = extend([], parent.objColl, [], true) as SelectionPoint[];
895
+ currentObj.pointColl = extend([], parent.pointColl, [], true) as Point[];
896
+ currentObj.afterCropActions = extend([], parent.afterCropActions, [], true) as string[];
897
+ const selPointCollObj: Object = {selPointColl: null };
898
+ parent.notify('freehand-draw', { prop: 'getSelPointColl', onPropertyChange: false,
899
+ value: {obj: selPointCollObj }});
900
+ currentObj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true) as Point[];
901
+ if (operation === 'crop') {
902
+ currentObj.currSelectionPoint = extend({}, parent.currSelectionPoint, {}, true) as SelectionPoint;
903
+ } else if (operation === 'frame') {
904
+ previousObj.destPoints = {startX: parent.frameDestPoints.destLeft, startY: parent.frameDestPoints.destTop,
905
+ width: parent.frameDestPoints.destWidth, height: parent.frameDestPoints.destHeight };
906
+ currentObj.destPoints = {startX: parent.frameDestPoints.destLeft, startY: parent.frameDestPoints.destTop,
907
+ width: parent.frameDestPoints.destWidth, height: parent.frameDestPoints.destHeight };
908
+ if (!isNullOrUndefined(parent.tempFrameZoomLevel)) {
909
+ previousObj.defaultZoom = currentObj.defaultZoom = parent.tempFrameZoomLevel;
910
+ }
911
+ } else if ((operation === 'imageHFlip' || operation === 'imageVFlip') && this.appliedUndoRedoColl.length > 0) {
912
+ const index: string = previousObjColl[previousObjColl.length - 1].currIndex;
913
+ previousObjColl = this.appliedUndoRedoColl[this.appliedUndoRedoColl.length - 1].currentObjColl;
914
+ if (index) {
915
+ for (let i: number = 0, len: number = previousObjColl.length; i < len; i++) {
916
+ if (previousObjColl[i as number].currIndex === index) {
917
+ const actObj: SelectionPoint = extend({}, previousObjColl[i as number], {}, true) as SelectionPoint;
918
+ previousObjColl.splice(i, 1);
919
+ previousObjColl.push(actObj);
920
+ break;
921
+ }
922
+ }
923
+ }
924
+ }
925
+ this.undoRedoColl.push({operation: operation, previousObj: previousObj, currentObj: currentObj,
926
+ previousObjColl: previousObjColl, currentObjColl: currentObj.objColl,
927
+ previousPointColl: previousPointColl, currentPointColl: currentObj.pointColl,
928
+ previousSelPointColl: previousSelPointColl, currentSelPointColl: currentObj.selPointColl,
929
+ previousCropObj: previousCropObj, currentCropObj: extend({}, parent.cropObj, {}, true) as CurrentObject,
930
+ previousText: previousText, currentText: currentText, filter: previousFilter, isCircleCrop: isCircleCrop });
931
+ parent.notify('toolbar', { prop: 'enable-disable-btns', onPropertyChange: false});
932
+ }
933
+ }
934
+
935
+ private updateUrObj(objColl: SelectionPoint[], operation?: string): void {
936
+ const parent: ImageEditor = this.parent;
937
+ if (parent.allowUndoRedo) {
938
+ if (parent.currObjType.isUndoAction && !parent.isShapeDrawing) { this.refreshUrc(true); }
939
+ if (isNullOrUndefined(parent.activeObj.imageRatio)) {
940
+ parent.notify('shape', { prop: 'updImgRatioForActObj', onPropertyChange: false});
941
+ }
942
+ parent.objColl.push(parent.activeObj);
943
+ const cropObj: CurrentObject = extend({}, parent.cropObj, {}, true) as CurrentObject;
944
+ const object: Object = {currObj: {} as CurrentObject };
945
+ parent.notify('filter', { prop: 'getCurrentObj', onPropertyChange: false, value: {object: object }});
946
+ const obj: CurrentObject = object['currObj'];
947
+ obj.objColl = extend([], parent.objColl, [], true) as SelectionPoint[];
948
+ obj.pointColl = extend([], parent.pointColl, [], true) as Point[];
949
+ obj.afterCropActions = extend([], parent.afterCropActions, [], true) as string[];
950
+ const selPointCollObj: Object = {selPointColl: null };
951
+ parent.notify('freehand-draw', { prop: 'getSelPointColl', onPropertyChange: false,
952
+ value: {obj: selPointCollObj }});
953
+ obj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true) as Point[];
954
+ const oper: string = operation ? operation : 'shapeTransform';
955
+ this.undoRedoColl.push({operation: oper, previousObj: obj, currentObj: obj,
956
+ previousObjColl: objColl, currentObjColl: obj.objColl,
957
+ previousPointColl: obj.pointColl, currentPointColl: obj.pointColl,
958
+ previousSelPointColl: obj.selPointColl, currentSelPointColl: obj.selPointColl,
959
+ previousCropObj: cropObj, currentCropObj: cropObj});
960
+ parent.notify('selection', { prop: 'redrawShape', onPropertyChange: false,
961
+ value: {obj: parent.objColl[parent.objColl.length - 1]}});
962
+ }
963
+ }
964
+
965
+ private updateUndoRedo(operation?: string): void {
966
+ const parent: ImageEditor = this.parent;
967
+ const prevCropObj: CurrentObject = extend({}, parent.cropObj, {}, true) as CurrentObject;
968
+ const object: Object = {currObj: {} as CurrentObject };
969
+ parent.notify('filter', { prop: 'getCurrentObj', onPropertyChange: false, value: {object: object }});
970
+ const prevObj: CurrentObject = object['currObj'];
971
+ prevObj.objColl = extend([], parent.objColl, [], true) as SelectionPoint[];
972
+ prevObj.pointColl = extend([], parent.pointColl, [], true) as Point[];
973
+ prevObj.afterCropActions = extend([], parent.afterCropActions, [], true) as string[];
974
+ const selPointCollObj: Object = {selPointColl: null };
975
+ parent.notify('freehand-draw', { prop: 'getSelPointColl', onPropertyChange: false,
976
+ value: {obj: selPointCollObj }});
977
+ prevObj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true) as Point[];
978
+ if (isNullOrUndefined(parent.activeObj.imageRatio)) {
979
+ parent.notify('shape', { prop: 'updImgRatioForActObj', onPropertyChange: false});
980
+ }
981
+ parent.objColl.push(parent.activeObj);
982
+ const oper: string = operation ? operation : 'shapeTransform';
983
+ this.updateUrc(oper, prevObj, prevObj.objColl, prevObj.pointColl, prevObj.selPointColl, prevCropObj);
984
+ parent.objColl.pop();
985
+ parent.notify('shape', { prop: 'applyActObj', onPropertyChange: false, value: {isMouseDown: null}});
986
+ parent.notify('shape', { prop: 'refreshActiveObj', onPropertyChange: false});
987
+ parent.notify('toolbar', { prop: 'refresh-toolbar', onPropertyChange: false, value: { type: 'shapes',
988
+ isApplyBtn: null, isCropping: null, isZooming: null, cType: null } });
989
+ parent.notify('toolbar', { prop: 'refresh-toolbar', onPropertyChange: false, value: { type: 'main',
990
+ isApplyBtn: null, isCropping: null, isZooming: null, cType: null } });
991
+ }
992
+
993
+ private getZeroZoomObjPointValue(obj: SelectionPoint[], point: Point[]): Object {
994
+ const parent: ImageEditor = this.parent;
995
+ this.updateObjColl();
996
+ const object: Object = {currObj: {} as CurrentObject };
997
+ parent.notify('filter', { prop: 'getCurrentObj', onPropertyChange: false, value: {object: object }});
998
+ const currentObj: CurrentObject = object['currObj'];
999
+ currentObj.objColl = extend([], parent.objColl, [], true) as SelectionPoint[];
1000
+ currentObj.pointColl = extend([], parent.pointColl, [], true) as Point[];
1001
+ currentObj.afterCropActions = extend([], parent.afterCropActions, [], true) as string[];
1002
+ const selPointCollObj: Object = {selPointColl: null };
1003
+ parent.notify('freehand-draw', { prop: 'getSelPointColl', onPropertyChange: false,
1004
+ value: {obj: selPointCollObj }});
1005
+ currentObj.selPointColl = extend([], selPointCollObj['selPointColl'], [], true) as Point[];
1006
+ const cropDimensionObj: Object = {cropDimension: null };
1007
+ parent.notify('transform', { prop: 'getCropDimension', onPropertyChange: false, value: {obj: cropDimensionObj }});
1008
+ let getZeroZoomObjColl: SelectionPoint[] = extend([], parent.objColl, [], true) as SelectionPoint[];
1009
+ let getZeroZoomPointColl: Point[] = extend([], parent.pointColl, [], true) as Point[];
1010
+ const arrowObj: Object = {arrowDimension: null };
1011
+ this.parent.notify('draw', { prop: 'getArrowDimension', onPropertyChange: false, value: {obj: arrowObj }});
1012
+ const tempArrowObj: Object = extend({}, arrowObj['arrowDimension'], {}, true) as Object;
1013
+ if (parent.transform.zoomFactor > 0 && (obj.length > 0 || point.length > 0)) {
1014
+ if (obj.length > 0) {
1015
+ for (let i: number = 0; i < obj.length; i++) {
1016
+ if (obj[i as number].currIndex) {
1017
+ continue;
1018
+ } else {
1019
+ obj[i as number].currIndex = 'shape_' + (i + 1);
1020
+ }
1021
+ }
1022
+ }
1023
+ parent.objColl = obj; parent.pointColl = point;
1024
+ const isUndoRedo: boolean = parent.isUndoRedo;
1025
+ const isCropTab: boolean = parent.isCropTab;
1026
+ if (parent.transform.zoomFactor !== 0) {
1027
+ parent.isUndoRedo = true;
1028
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
1029
+ value: {ctx: this.lowerContext, shape: 'zoom', pen: 'zoom', isPreventApply: true }});
1030
+ parent.notify('freehand-draw', { prop: 'updateFHDColl', onPropertyChange: false});
1031
+ parent.isCropTab = true;
1032
+ const zoomSettings: ZoomSettings = extend({}, parent.zoomSettings, null, true) as ZoomSettings;
1033
+ if (parent.transform.zoomFactor > 0) {
1034
+ parent.notify('transform', { prop: 'zoomAction', onPropertyChange: false,
1035
+ value: {zoomFactor: -parent.transform.zoomFactor, zoomPoint: null, isResize: null }});
1036
+ } else {
1037
+ parent.notify('transform', { prop: 'zoomAction', onPropertyChange: false,
1038
+ value: {zoomFactor: Math.abs(parent.transform.zoomFactor), zoomPoint: null, isResize: null }});
1039
+ }
1040
+ parent.zoomSettings = zoomSettings; parent.isCropTab = isCropTab; parent.isUndoRedo = isUndoRedo;
1041
+ getZeroZoomObjColl = extend([], parent.objColl, [], true) as SelectionPoint[];
1042
+ getZeroZoomPointColl = extend([], parent.pointColl, [], true) as Point[];
1043
+ parent.objColl = []; parent.pointColl = []; parent.freehandCounter = 0;
1044
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
1045
+ value: {obj: {selPointColl: [] } }});
1046
+ parent.notify('transform', { prop: 'setCropDimension', onPropertyChange: false,
1047
+ value: {width: cropDimensionObj['cropDimension']['width'], height: cropDimensionObj['cropDimension']['height']}});
1048
+ const maxDimension: Dimension = {width: cropDimensionObj['cropDimension']['width'], height: cropDimensionObj['cropDimension']['height'] };
1049
+ maxDimension.width += (maxDimension.width * currentObj.defaultZoom);
1050
+ maxDimension.height += (maxDimension.height * currentObj.defaultZoom);
1051
+ parent.notify('draw', {prop: 'setZoomCropWidth', value: {width: maxDimension.width, height: maxDimension.height }});
1052
+ parent.notify('draw', { prop: 'setCurrentObj', onPropertyChange: false, value: {obj: currentObj}});
1053
+ parent.img.destLeft = currentObj.destPoints.startX; parent.img.destTop = currentObj.destPoints.startY;
1054
+ parent.panPoint.totalPannedPoint = currentObj.totalPannedPoint;
1055
+ parent.panPoint.totalPannedClientPoint = currentObj.totalPannedClientPoint;
1056
+ parent.panPoint.totalPannedInternalPoint = currentObj.totalPannedInternalPoint;
1057
+ parent.objColl = extend([], currentObj.objColl, [], true) as SelectionPoint[];
1058
+ parent.pointColl = extend([], currentObj.pointColl, [], true) as Point[];
1059
+ parent.freehandCounter = parent.pointColl.length;
1060
+ parent.notify('draw', { prop: 'setArrowDimension', onPropertyChange: false, value: {arrowDimension: tempArrowObj }});
1061
+ parent.notify('freehand-draw', { prop: 'setSelPointColl', onPropertyChange: false,
1062
+ value: {obj: {selPointColl: extend([], currentObj.selPointColl, [], true) as Point[] } }});
1063
+ this.lowerContext.filter = 'none';
1064
+ parent.transform.straighten = 0;
1065
+ this.applyImgTranform();
1066
+ parent.notify('shape', { prop: 'drawAnnotations', onPropertyChange: false,
1067
+ value: {ctx: this.lowerContext, shape: 'iterate', pen: 'iterate', isPreventApply: null }});
1068
+ parent.notify('freehand-draw', { prop: 'updateFHDCurPts', onPropertyChange: false});
1069
+ this.lowerContext.filter = currentObj.filter;
1070
+ if (parent.transform.degree !== 0) {
1071
+ parent.notify('transform', { prop: 'drawPannedImage', onPropertyChange: false,
1072
+ value: {xDiff: 0, yDiff: 0 }});
1073
+ }
1074
+ parent.notify('draw', { prop: 'clearOuterCanvas', onPropertyChange: false, value: {context: this.lowerContext}});
1075
+ if (parent.isCircleCrop || (parent.currSelectionPoint && parent.currSelectionPoint.shape === 'crop-circle')) {
1076
+ parent.notify('crop', { prop: 'cropCircle', onPropertyChange: false,
1077
+ value: {context: this.lowerContext, isSave: null, isFlip: null}});
1078
+ }
1079
+ }
1080
+ }
1081
+ return {obj: getZeroZoomObjColl, point: getZeroZoomPointColl };
1082
+ }
1083
+
1084
+ private updateObjColl(): void {
1085
+ const parent: ImageEditor = this.parent;
1086
+ for (let i: number = 0; i < parent.objColl.length; i++) {
1087
+ let obj: SelectionPoint = parent.objColl[i as number];
1088
+ let isUpdated: boolean = false;
1089
+ if (obj.shape === 'line' || obj.shape === 'arrow') {
1090
+ if (obj.activePoint.width < 0) {
1091
+ obj.activePoint.width = Math.abs(obj.activePoint.width);
1092
+ isUpdated = true;
1093
+ }
1094
+ if (obj.activePoint.height < 0) {
1095
+ obj.activePoint.height = Math.abs(obj.activePoint.height);
1096
+ isUpdated = true;
1097
+ }
1098
+ if (isUpdated) {
1099
+ const activeObj: SelectionPoint = extend({}, parent.activeObj, {}, true) as SelectionPoint;
1100
+ parent.activeObj = obj;
1101
+ parent.notify('shape', { prop: 'updImgRatioForActObj', onPropertyChange: false });
1102
+ obj = parent.activeObj;
1103
+ parent.activeObj = activeObj;
1104
+ }
1105
+ }
1106
+ }
1107
+ }
1108
+
1109
+ private applyImgTranform(): void {
1110
+ const parent: ImageEditor = this.parent;
1111
+ const obj: SelectionPoint = extend({}, parent.activeObj, {}, true) as SelectionPoint;
1112
+ for (let i: number = 0, len: number = parent.objColl.length; i < len; i++) {
1113
+ if (parent.objColl[i as number].shape === 'image') {
1114
+ parent.activeObj = extend({}, parent.objColl[i as number], {}, true) as SelectionPoint;
1115
+ const ctx: CanvasRenderingContext2D = parent.objColl[i as number].imageCanvas.getContext('2d');
1116
+ parent.notify('selection', { prop: 'applyTransformToImg', onPropertyChange: false, value: {ctx: ctx }});
1117
+ this.upperContext.clearRect(0, 0, parent.upperCanvas.width, parent.upperCanvas.height);
1118
+ parent.notify('selection', { prop: 'setImageClarity', onPropertyChange: false, value: {bool: true }});
1119
+ }
1120
+ }
1121
+ parent.activeObj = obj;
1122
+ }
1123
+
1124
+ private updateUndoRedoStack(isPenDraw?: boolean): void {
1125
+ const parent: ImageEditor = this.parent;
1126
+ if ((parent.activeObj.currIndex && parent.activeObj.activePoint.width !== 0 ||
1127
+ parent.activeObj.activePoint.height !== 0 || (parent.activeObj.pointColl &&
1128
+ parent.activeObj.pointColl.length > 0)) || isPenDraw) {
1129
+ const isTextArea: boolean = parent.textArea.style.display === 'none' ? false : true;
1130
+ const temp: boolean = parent.noPushUndo;
1131
+ parent.noPushUndo = false; parent.isUndoRedoStack = true;
1132
+ this.preventEditComplete = true;
1133
+ if (isPenDraw) {
1134
+ const tempTogglePen: boolean = parent.togglePen;
1135
+ const obj: Object = {freehandDrawSelectedId: null };
1136
+ parent.notify('freehand-draw', { prop: 'getFreehandDrawSelectedId', onPropertyChange: false, value: {obj: obj }});
1137
+ parent.okBtn();
1138
+ parent.noPushUndo = temp;
1139
+ if (obj['freehandDrawSelectedId']){
1140
+ parent.noRedact = true;
1141
+ parent.selectShape(obj['freehandDrawSelectedId']);
1142
+ } else {
1143
+ parent.freeHandDraw(true);
1144
+ }
1145
+ parent.togglePen = tempTogglePen;
1146
+ } else if (parent.activeObj.currIndex) {
1147
+ const shapeId: string = parent.activeObj.currIndex;
1148
+ parent.okBtn();
1149
+ parent.noPushUndo = temp;
1150
+ parent.noRedact = true;
1151
+ parent.selectShape(shapeId);
1152
+ if (parent.drawingShape) {
1153
+ parent.notify('selection', { prop: 'setCurrentDrawingShape', onPropertyChange: false, value: {value: parent.drawingShape.toLowerCase() }});
1154
+ }
1155
+ if (isTextArea) {
1156
+ parent.enableTextEditing();
1157
+ }
1158
+ }
1159
+ if (this.preventEditComplete) {
1160
+ parent.isUndoRedoStack = this.preventEditComplete = false;
1161
+ if (!this.preventApplyEditComplete) {
1162
+ this.triggerActionCompletedEvent('shape-customize');
1163
+ }
1164
+ this.triggerActionCompletedEvent('shape-select');
1165
+ }
1166
+ parent.isUndoRedoStack = this.preventEditComplete = false;
1167
+ }
1168
+ }
1169
+ }