@leapfrog/interactive-canvas 1.11.2 → 1.12.0

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.
@@ -304,6 +304,11 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
304
304
  * @inheritDoc
305
305
  */
306
306
  undo(): Promise<void>;
307
+ /**
308
+ * @override
309
+ * @inheritDoc
310
+ */
311
+ redo(): Promise<void>;
307
312
  /**
308
313
  * Redraw the canvas.
309
314
  */
@@ -13,6 +13,11 @@ export declare class InteractiveCanvas extends AbstractInteractiveCanvas {
13
13
  * @inheritDoc
14
14
  */
15
15
  undo(): Promise<void>;
16
+ /**
17
+ * @override
18
+ * @inheritDoc
19
+ */
20
+ redo(): Promise<void>;
16
21
  private onFabricSelectionChanged;
17
22
  private enterTextSelectionModeIfRequired;
18
23
  private onTextEditing;
@@ -3428,6 +3428,13 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3428
3428
  AbstractInteractiveCanvas.prototype.undo = function () {
3429
3429
  throw Error("Undo not supported on this canvas type");
3430
3430
  };
3431
+ /**
3432
+ * @override
3433
+ * @inheritDoc
3434
+ */
3435
+ AbstractInteractiveCanvas.prototype.redo = function () {
3436
+ throw Error("Redo not supported on this canvas type");
3437
+ };
3431
3438
  /**
3432
3439
  * Redraw the canvas.
3433
3440
  */
@@ -3643,20 +3650,68 @@ var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
3643
3650
  }(AbstractInteractiveCanvas));
3644
3651
 
3645
3652
  var UndoStack = /** @class */ (function () {
3646
- function UndoStack(size) {
3647
- this.stack = [];
3653
+ function UndoStack(canvas, size) {
3654
+ if (size === void 0) { size = 100; }
3655
+ this.canvas = canvas;
3656
+ this.undoStates = [];
3657
+ this.redoStates = [];
3658
+ this.lastUndo = null;
3648
3659
  this.size = size;
3649
3660
  }
3650
- UndoStack.prototype.push = function (state) {
3651
- var prev = this.stack[this.stack.length - 1];
3652
- if (isEqual(prev, state))
3661
+ UndoStack.prototype.save = function (state) {
3662
+ var currentState = this.canvas.save();
3663
+ var undoState = this.undoStates[this.undoStates.length - 1];
3664
+ if (isEqual(undoState, state))
3653
3665
  return;
3654
- this.stack.push(state);
3655
- if (this.stack.length > this.size)
3656
- this.stack.splice(0, 1);
3666
+ this.undoStates.push(state);
3667
+ if (this.undoStates.length > this.size)
3668
+ this.undoStates.splice(0, 1);
3669
+ if (!isEqual(this.lastUndo, currentState))
3670
+ this.redoStates = [];
3657
3671
  };
3658
- UndoStack.prototype.pop = function () {
3659
- return this.stack.pop();
3672
+ UndoStack.prototype.undo = function () {
3673
+ return __awaiter(this, void 0, void 0, function () {
3674
+ var undoState, currentState;
3675
+ return __generator(this, function (_a) {
3676
+ switch (_a.label) {
3677
+ case 0:
3678
+ undoState = this.undoStates.pop();
3679
+ if (!undoState)
3680
+ return [2 /*return*/];
3681
+ currentState = this.canvas.save();
3682
+ if (isEqual(undoState, currentState)) {
3683
+ undoState = this.undoStates.pop();
3684
+ if (!undoState)
3685
+ return [2 /*return*/];
3686
+ }
3687
+ this.lastUndo = undoState;
3688
+ this.redoStates.push(currentState);
3689
+ return [4 /*yield*/, this.canvas.load(undoState)];
3690
+ case 1:
3691
+ _a.sent();
3692
+ return [2 /*return*/];
3693
+ }
3694
+ });
3695
+ });
3696
+ };
3697
+ UndoStack.prototype.redo = function () {
3698
+ return __awaiter(this, void 0, void 0, function () {
3699
+ var state, currentState;
3700
+ return __generator(this, function (_a) {
3701
+ switch (_a.label) {
3702
+ case 0:
3703
+ state = this.redoStates.pop();
3704
+ if (!state)
3705
+ return [2 /*return*/];
3706
+ currentState = this.canvas.save();
3707
+ this.undoStates.push(currentState);
3708
+ return [4 /*yield*/, this.canvas.load(state)];
3709
+ case 1:
3710
+ _a.sent();
3711
+ return [2 /*return*/];
3712
+ }
3713
+ });
3714
+ });
3660
3715
  };
3661
3716
  return UndoStack;
3662
3717
  }());
@@ -3666,7 +3721,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3666
3721
  function InteractiveCanvas(elementId, devicePixelRatio) {
3667
3722
  var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
3668
3723
  _this.devicePixelRatio = devicePixelRatio;
3669
- _this.undoStack = new UndoStack(100);
3724
+ _this.undoStack = new UndoStack(_this);
3670
3725
  //Initialize watchers
3671
3726
  _this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
3672
3727
  _this.fabricCanvas.on("selection:created", function () { return _this.onFabricSelectionChanged(); });
@@ -3681,7 +3736,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3681
3736
  * @inheritDoc
3682
3737
  */
3683
3738
  InteractiveCanvas.prototype.registerUndoState = function () {
3684
- this.undoStack.push(this.save());
3739
+ this.undoStack.save(this.save());
3685
3740
  };
3686
3741
  /**
3687
3742
  * @override
@@ -3689,20 +3744,25 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3689
3744
  */
3690
3745
  InteractiveCanvas.prototype.undo = function () {
3691
3746
  return __awaiter(this, void 0, void 0, function () {
3692
- var state;
3693
3747
  return __generator(this, function (_a) {
3694
3748
  switch (_a.label) {
3695
- case 0:
3696
- state = this.undoStack.pop();
3697
- if (!state)
3698
- return [2 /*return*/];
3699
- //If the undo state matches the current state, pop again as the undo will have no effect
3700
- if (isEqual(state, this.save())) {
3701
- state = this.undoStack.pop();
3702
- if (!state)
3703
- return [2 /*return*/];
3704
- }
3705
- return [4 /*yield*/, this.load(state)];
3749
+ case 0: return [4 /*yield*/, this.undoStack.undo()];
3750
+ case 1:
3751
+ _a.sent();
3752
+ return [2 /*return*/];
3753
+ }
3754
+ });
3755
+ });
3756
+ };
3757
+ /**
3758
+ * @override
3759
+ * @inheritDoc
3760
+ */
3761
+ InteractiveCanvas.prototype.redo = function () {
3762
+ return __awaiter(this, void 0, void 0, function () {
3763
+ return __generator(this, function (_a) {
3764
+ switch (_a.label) {
3765
+ case 0: return [4 /*yield*/, this.undoStack.redo()];
3706
3766
  case 1:
3707
3767
  _a.sent();
3708
3768
  return [2 /*return*/];
@@ -286,4 +286,8 @@ export interface IInteractiveCanvas {
286
286
  * Revert the canvas state one entry.
287
287
  */
288
288
  undo(): Promise<void>;
289
+ /**
290
+ * Revert the canvas state one entry.
291
+ */
292
+ redo(): Promise<void>;
289
293
  }
@@ -3428,6 +3428,13 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3428
3428
  AbstractInteractiveCanvas.prototype.undo = function () {
3429
3429
  throw Error("Undo not supported on this canvas type");
3430
3430
  };
3431
+ /**
3432
+ * @override
3433
+ * @inheritDoc
3434
+ */
3435
+ AbstractInteractiveCanvas.prototype.redo = function () {
3436
+ throw Error("Redo not supported on this canvas type");
3437
+ };
3431
3438
  /**
3432
3439
  * Redraw the canvas.
3433
3440
  */
@@ -3643,20 +3650,68 @@ var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
3643
3650
  }(AbstractInteractiveCanvas));
3644
3651
 
3645
3652
  var UndoStack = /** @class */ (function () {
3646
- function UndoStack(size) {
3647
- this.stack = [];
3653
+ function UndoStack(canvas, size) {
3654
+ if (size === void 0) { size = 100; }
3655
+ this.canvas = canvas;
3656
+ this.undoStates = [];
3657
+ this.redoStates = [];
3658
+ this.lastUndo = null;
3648
3659
  this.size = size;
3649
3660
  }
3650
- UndoStack.prototype.push = function (state) {
3651
- var prev = this.stack[this.stack.length - 1];
3652
- if (_.isEqual(prev, state))
3661
+ UndoStack.prototype.save = function (state) {
3662
+ var currentState = this.canvas.save();
3663
+ var undoState = this.undoStates[this.undoStates.length - 1];
3664
+ if (_.isEqual(undoState, state))
3653
3665
  return;
3654
- this.stack.push(state);
3655
- if (this.stack.length > this.size)
3656
- this.stack.splice(0, 1);
3666
+ this.undoStates.push(state);
3667
+ if (this.undoStates.length > this.size)
3668
+ this.undoStates.splice(0, 1);
3669
+ if (!_.isEqual(this.lastUndo, currentState))
3670
+ this.redoStates = [];
3657
3671
  };
3658
- UndoStack.prototype.pop = function () {
3659
- return this.stack.pop();
3672
+ UndoStack.prototype.undo = function () {
3673
+ return __awaiter(this, void 0, void 0, function () {
3674
+ var undoState, currentState;
3675
+ return __generator(this, function (_a) {
3676
+ switch (_a.label) {
3677
+ case 0:
3678
+ undoState = this.undoStates.pop();
3679
+ if (!undoState)
3680
+ return [2 /*return*/];
3681
+ currentState = this.canvas.save();
3682
+ if (_.isEqual(undoState, currentState)) {
3683
+ undoState = this.undoStates.pop();
3684
+ if (!undoState)
3685
+ return [2 /*return*/];
3686
+ }
3687
+ this.lastUndo = undoState;
3688
+ this.redoStates.push(currentState);
3689
+ return [4 /*yield*/, this.canvas.load(undoState)];
3690
+ case 1:
3691
+ _a.sent();
3692
+ return [2 /*return*/];
3693
+ }
3694
+ });
3695
+ });
3696
+ };
3697
+ UndoStack.prototype.redo = function () {
3698
+ return __awaiter(this, void 0, void 0, function () {
3699
+ var state, currentState;
3700
+ return __generator(this, function (_a) {
3701
+ switch (_a.label) {
3702
+ case 0:
3703
+ state = this.redoStates.pop();
3704
+ if (!state)
3705
+ return [2 /*return*/];
3706
+ currentState = this.canvas.save();
3707
+ this.undoStates.push(currentState);
3708
+ return [4 /*yield*/, this.canvas.load(state)];
3709
+ case 1:
3710
+ _a.sent();
3711
+ return [2 /*return*/];
3712
+ }
3713
+ });
3714
+ });
3660
3715
  };
3661
3716
  return UndoStack;
3662
3717
  }());
@@ -3666,7 +3721,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3666
3721
  function InteractiveCanvas(elementId, devicePixelRatio) {
3667
3722
  var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
3668
3723
  _this.devicePixelRatio = devicePixelRatio;
3669
- _this.undoStack = new UndoStack(100);
3724
+ _this.undoStack = new UndoStack(_this);
3670
3725
  //Initialize watchers
3671
3726
  _this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
3672
3727
  _this.fabricCanvas.on("selection:created", function () { return _this.onFabricSelectionChanged(); });
@@ -3681,7 +3736,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3681
3736
  * @inheritDoc
3682
3737
  */
3683
3738
  InteractiveCanvas.prototype.registerUndoState = function () {
3684
- this.undoStack.push(this.save());
3739
+ this.undoStack.save(this.save());
3685
3740
  };
3686
3741
  /**
3687
3742
  * @override
@@ -3689,20 +3744,25 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3689
3744
  */
3690
3745
  InteractiveCanvas.prototype.undo = function () {
3691
3746
  return __awaiter(this, void 0, void 0, function () {
3692
- var state;
3693
3747
  return __generator(this, function (_a) {
3694
3748
  switch (_a.label) {
3695
- case 0:
3696
- state = this.undoStack.pop();
3697
- if (!state)
3698
- return [2 /*return*/];
3699
- //If the undo state matches the current state, pop again as the undo will have no effect
3700
- if (_.isEqual(state, this.save())) {
3701
- state = this.undoStack.pop();
3702
- if (!state)
3703
- return [2 /*return*/];
3704
- }
3705
- return [4 /*yield*/, this.load(state)];
3749
+ case 0: return [4 /*yield*/, this.undoStack.undo()];
3750
+ case 1:
3751
+ _a.sent();
3752
+ return [2 /*return*/];
3753
+ }
3754
+ });
3755
+ });
3756
+ };
3757
+ /**
3758
+ * @override
3759
+ * @inheritDoc
3760
+ */
3761
+ InteractiveCanvas.prototype.redo = function () {
3762
+ return __awaiter(this, void 0, void 0, function () {
3763
+ return __generator(this, function (_a) {
3764
+ switch (_a.label) {
3765
+ case 0: return [4 /*yield*/, this.undoStack.redo()];
3706
3766
  case 1:
3707
3767
  _a.sent();
3708
3768
  return [2 /*return*/];
@@ -1,8 +1,13 @@
1
1
  import { ICanvasState } from "./types/canvas-state.interface";
2
+ import { IInteractiveCanvas } from "./interactive-canvas.interface";
2
3
  export declare class UndoStack {
4
+ protected canvas: IInteractiveCanvas;
3
5
  private readonly size;
4
- private stack;
5
- constructor(size: number);
6
- push(state: ICanvasState): void;
7
- pop(): ICanvasState;
6
+ private undoStates;
7
+ private redoStates;
8
+ private lastUndo;
9
+ constructor(canvas: IInteractiveCanvas, size?: number);
10
+ save(state: ICanvasState): void;
11
+ undo(): Promise<void>;
12
+ redo(): Promise<void>;
8
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leapfrog/interactive-canvas",
3
- "version": "1.11.2",
3
+ "version": "1.12.0",
4
4
  "description": "Leapfrog interactive canvas",
5
5
  "files": [
6
6
  "dist"