@leapfrog/interactive-canvas 1.10.2 → 1.11.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.
|
@@ -294,6 +294,16 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
|
|
|
294
294
|
* @inheritDoc
|
|
295
295
|
*/
|
|
296
296
|
createPNGStream(): any;
|
|
297
|
+
/**
|
|
298
|
+
* @override
|
|
299
|
+
* @inheritDoc
|
|
300
|
+
*/
|
|
301
|
+
registerUndoState(): void;
|
|
302
|
+
/**
|
|
303
|
+
* @override
|
|
304
|
+
* @inheritDoc
|
|
305
|
+
*/
|
|
306
|
+
undo(): Promise<void>;
|
|
297
307
|
/**
|
|
298
308
|
* Redraw the canvas.
|
|
299
309
|
*/
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { AbstractInteractiveCanvas } from "./abstract-interactive-canvas";
|
|
2
2
|
export declare class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
3
3
|
protected devicePixelRatio: number;
|
|
4
|
+
private readonly undoStack;
|
|
5
|
+
private undoSub;
|
|
4
6
|
constructor(elementId: string, devicePixelRatio: number);
|
|
7
|
+
/**
|
|
8
|
+
* @override
|
|
9
|
+
* @inheritDoc
|
|
10
|
+
*/
|
|
11
|
+
registerUndoState(): void;
|
|
12
|
+
/**
|
|
13
|
+
* @override
|
|
14
|
+
* @inheritDoc
|
|
15
|
+
*/
|
|
16
|
+
undo(): Promise<void>;
|
|
5
17
|
private onFabricSelectionChanged;
|
|
6
18
|
private enterTextSelectionModeIfRequired;
|
|
7
19
|
private onTextEditing;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _ from 'lodash';
|
|
2
|
-
import { round, each, values, reduce, clone, replace, find } from 'lodash';
|
|
2
|
+
import { round, each, values, reduce, clone, replace, find, isEqual } from 'lodash';
|
|
3
3
|
import { oc } from 'ts-optchain';
|
|
4
4
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
5
5
|
import { fabric } from 'fabric';
|
|
@@ -3321,14 +3321,12 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
|
|
|
3321
3321
|
.value();
|
|
3322
3322
|
var includedProperties = ["id"];
|
|
3323
3323
|
var json = this.fabricCanvas.toJSON(includedProperties);
|
|
3324
|
-
|
|
3324
|
+
return {
|
|
3325
3325
|
dimensions: this.dimensions$.value,
|
|
3326
3326
|
canvasJson: JSON.stringify(json),
|
|
3327
3327
|
objects: objects,
|
|
3328
3328
|
backgroundColor: this.backgroundColor$.value
|
|
3329
3329
|
};
|
|
3330
|
-
console.debug("Saving canvas state", state);
|
|
3331
|
-
return state;
|
|
3332
3330
|
};
|
|
3333
3331
|
/**
|
|
3334
3332
|
* @override
|
|
@@ -3416,6 +3414,20 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
|
|
|
3416
3414
|
AbstractInteractiveCanvas.prototype.createPNGStream = function () {
|
|
3417
3415
|
return this.fabricCanvas.createPNGStream();
|
|
3418
3416
|
};
|
|
3417
|
+
/**
|
|
3418
|
+
* @override
|
|
3419
|
+
* @inheritDoc
|
|
3420
|
+
*/
|
|
3421
|
+
AbstractInteractiveCanvas.prototype.registerUndoState = function () {
|
|
3422
|
+
throw Error("Undo not supported on this canvas type");
|
|
3423
|
+
};
|
|
3424
|
+
/**
|
|
3425
|
+
* @override
|
|
3426
|
+
* @inheritDoc
|
|
3427
|
+
*/
|
|
3428
|
+
AbstractInteractiveCanvas.prototype.undo = function () {
|
|
3429
|
+
throw Error("Undo not supported on this canvas type");
|
|
3430
|
+
};
|
|
3419
3431
|
/**
|
|
3420
3432
|
* Redraw the canvas.
|
|
3421
3433
|
*/
|
|
@@ -3630,11 +3642,34 @@ var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
|
|
|
3630
3642
|
return HeadlessInteractiveCanvas;
|
|
3631
3643
|
}(AbstractInteractiveCanvas));
|
|
3632
3644
|
|
|
3645
|
+
var UndoStack = /** @class */ (function () {
|
|
3646
|
+
function UndoStack(size) {
|
|
3647
|
+
this.stack = [];
|
|
3648
|
+
this.size = size;
|
|
3649
|
+
}
|
|
3650
|
+
UndoStack.prototype.push = function (state) {
|
|
3651
|
+
var prev = this.stack[this.stack.length - 1];
|
|
3652
|
+
if (isEqual(prev, state)) {
|
|
3653
|
+
console.error("Ignoring identical undo state"); //todo
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
console.error("Undo Registered"); //todo
|
|
3657
|
+
this.stack.push(state);
|
|
3658
|
+
if (this.stack.length > this.size)
|
|
3659
|
+
this.stack.splice(0, 1);
|
|
3660
|
+
};
|
|
3661
|
+
UndoStack.prototype.pop = function () {
|
|
3662
|
+
return this.stack.pop();
|
|
3663
|
+
};
|
|
3664
|
+
return UndoStack;
|
|
3665
|
+
}());
|
|
3666
|
+
|
|
3633
3667
|
var InteractiveCanvas = /** @class */ (function (_super) {
|
|
3634
3668
|
__extends(InteractiveCanvas, _super);
|
|
3635
3669
|
function InteractiveCanvas(elementId, devicePixelRatio) {
|
|
3636
3670
|
var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
|
|
3637
3671
|
_this.devicePixelRatio = devicePixelRatio;
|
|
3672
|
+
_this.undoStack = new UndoStack(10);
|
|
3638
3673
|
//Initialize watchers
|
|
3639
3674
|
_this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
|
|
3640
3675
|
_this.fabricCanvas.on("selection:created", function () { return _this.onFabricSelectionChanged(); });
|
|
@@ -3644,6 +3679,34 @@ var InteractiveCanvas = /** @class */ (function (_super) {
|
|
|
3644
3679
|
_this.fabricCanvas.on("text:changed", function () { return _this.onTextChange(); });
|
|
3645
3680
|
return _this;
|
|
3646
3681
|
}
|
|
3682
|
+
/**
|
|
3683
|
+
* @override
|
|
3684
|
+
* @inheritDoc
|
|
3685
|
+
*/
|
|
3686
|
+
InteractiveCanvas.prototype.registerUndoState = function () {
|
|
3687
|
+
this.undoStack.push(this.save());
|
|
3688
|
+
};
|
|
3689
|
+
/**
|
|
3690
|
+
* @override
|
|
3691
|
+
* @inheritDoc
|
|
3692
|
+
*/
|
|
3693
|
+
InteractiveCanvas.prototype.undo = function () {
|
|
3694
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3695
|
+
var state;
|
|
3696
|
+
return __generator(this, function (_a) {
|
|
3697
|
+
switch (_a.label) {
|
|
3698
|
+
case 0:
|
|
3699
|
+
state = this.undoStack.pop();
|
|
3700
|
+
if (!state)
|
|
3701
|
+
return [2 /*return*/];
|
|
3702
|
+
return [4 /*yield*/, this.load(state)];
|
|
3703
|
+
case 1:
|
|
3704
|
+
_a.sent();
|
|
3705
|
+
return [2 /*return*/];
|
|
3706
|
+
}
|
|
3707
|
+
});
|
|
3708
|
+
});
|
|
3709
|
+
};
|
|
3647
3710
|
InteractiveCanvas.prototype.onFabricSelectionChanged = function () {
|
|
3648
3711
|
var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|
|
3649
3712
|
console.debug("Selection changed", selected);
|
|
@@ -278,4 +278,12 @@ export interface IInteractiveCanvas {
|
|
|
278
278
|
* Create a PNG stream of the canvas. Only works on headless canvas.
|
|
279
279
|
*/
|
|
280
280
|
createPNGStream(): any;
|
|
281
|
+
/**
|
|
282
|
+
* Save the current state as an undo point.
|
|
283
|
+
*/
|
|
284
|
+
registerUndoState(): void;
|
|
285
|
+
/**
|
|
286
|
+
* Revert the canvas state one entry.
|
|
287
|
+
*/
|
|
288
|
+
undo(): Promise<void>;
|
|
281
289
|
}
|
|
@@ -3321,14 +3321,12 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
|
|
|
3321
3321
|
.value();
|
|
3322
3322
|
var includedProperties = ["id"];
|
|
3323
3323
|
var json = this.fabricCanvas.toJSON(includedProperties);
|
|
3324
|
-
|
|
3324
|
+
return {
|
|
3325
3325
|
dimensions: this.dimensions$.value,
|
|
3326
3326
|
canvasJson: JSON.stringify(json),
|
|
3327
3327
|
objects: objects,
|
|
3328
3328
|
backgroundColor: this.backgroundColor$.value
|
|
3329
3329
|
};
|
|
3330
|
-
console.debug("Saving canvas state", state);
|
|
3331
|
-
return state;
|
|
3332
3330
|
};
|
|
3333
3331
|
/**
|
|
3334
3332
|
* @override
|
|
@@ -3416,6 +3414,20 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
|
|
|
3416
3414
|
AbstractInteractiveCanvas.prototype.createPNGStream = function () {
|
|
3417
3415
|
return this.fabricCanvas.createPNGStream();
|
|
3418
3416
|
};
|
|
3417
|
+
/**
|
|
3418
|
+
* @override
|
|
3419
|
+
* @inheritDoc
|
|
3420
|
+
*/
|
|
3421
|
+
AbstractInteractiveCanvas.prototype.registerUndoState = function () {
|
|
3422
|
+
throw Error("Undo not supported on this canvas type");
|
|
3423
|
+
};
|
|
3424
|
+
/**
|
|
3425
|
+
* @override
|
|
3426
|
+
* @inheritDoc
|
|
3427
|
+
*/
|
|
3428
|
+
AbstractInteractiveCanvas.prototype.undo = function () {
|
|
3429
|
+
throw Error("Undo not supported on this canvas type");
|
|
3430
|
+
};
|
|
3419
3431
|
/**
|
|
3420
3432
|
* Redraw the canvas.
|
|
3421
3433
|
*/
|
|
@@ -3630,11 +3642,34 @@ var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
|
|
|
3630
3642
|
return HeadlessInteractiveCanvas;
|
|
3631
3643
|
}(AbstractInteractiveCanvas));
|
|
3632
3644
|
|
|
3645
|
+
var UndoStack = /** @class */ (function () {
|
|
3646
|
+
function UndoStack(size) {
|
|
3647
|
+
this.stack = [];
|
|
3648
|
+
this.size = size;
|
|
3649
|
+
}
|
|
3650
|
+
UndoStack.prototype.push = function (state) {
|
|
3651
|
+
var prev = this.stack[this.stack.length - 1];
|
|
3652
|
+
if (_.isEqual(prev, state)) {
|
|
3653
|
+
console.error("Ignoring identical undo state"); //todo
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
console.error("Undo Registered"); //todo
|
|
3657
|
+
this.stack.push(state);
|
|
3658
|
+
if (this.stack.length > this.size)
|
|
3659
|
+
this.stack.splice(0, 1);
|
|
3660
|
+
};
|
|
3661
|
+
UndoStack.prototype.pop = function () {
|
|
3662
|
+
return this.stack.pop();
|
|
3663
|
+
};
|
|
3664
|
+
return UndoStack;
|
|
3665
|
+
}());
|
|
3666
|
+
|
|
3633
3667
|
var InteractiveCanvas = /** @class */ (function (_super) {
|
|
3634
3668
|
__extends(InteractiveCanvas, _super);
|
|
3635
3669
|
function InteractiveCanvas(elementId, devicePixelRatio) {
|
|
3636
3670
|
var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
|
|
3637
3671
|
_this.devicePixelRatio = devicePixelRatio;
|
|
3672
|
+
_this.undoStack = new UndoStack(10);
|
|
3638
3673
|
//Initialize watchers
|
|
3639
3674
|
_this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
|
|
3640
3675
|
_this.fabricCanvas.on("selection:created", function () { return _this.onFabricSelectionChanged(); });
|
|
@@ -3644,6 +3679,34 @@ var InteractiveCanvas = /** @class */ (function (_super) {
|
|
|
3644
3679
|
_this.fabricCanvas.on("text:changed", function () { return _this.onTextChange(); });
|
|
3645
3680
|
return _this;
|
|
3646
3681
|
}
|
|
3682
|
+
/**
|
|
3683
|
+
* @override
|
|
3684
|
+
* @inheritDoc
|
|
3685
|
+
*/
|
|
3686
|
+
InteractiveCanvas.prototype.registerUndoState = function () {
|
|
3687
|
+
this.undoStack.push(this.save());
|
|
3688
|
+
};
|
|
3689
|
+
/**
|
|
3690
|
+
* @override
|
|
3691
|
+
* @inheritDoc
|
|
3692
|
+
*/
|
|
3693
|
+
InteractiveCanvas.prototype.undo = function () {
|
|
3694
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3695
|
+
var state;
|
|
3696
|
+
return __generator(this, function (_a) {
|
|
3697
|
+
switch (_a.label) {
|
|
3698
|
+
case 0:
|
|
3699
|
+
state = this.undoStack.pop();
|
|
3700
|
+
if (!state)
|
|
3701
|
+
return [2 /*return*/];
|
|
3702
|
+
return [4 /*yield*/, this.load(state)];
|
|
3703
|
+
case 1:
|
|
3704
|
+
_a.sent();
|
|
3705
|
+
return [2 /*return*/];
|
|
3706
|
+
}
|
|
3707
|
+
});
|
|
3708
|
+
});
|
|
3709
|
+
};
|
|
3647
3710
|
InteractiveCanvas.prototype.onFabricSelectionChanged = function () {
|
|
3648
3711
|
var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|
|
3649
3712
|
console.debug("Selection changed", selected);
|