@leapfrog/interactive-canvas 1.12.1 → 1.13.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.
@@ -28,6 +28,7 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
28
28
  protected readonly fabricCanvas: fabric.Canvas;
29
29
  protected devicePixelRatio: number;
30
30
  protected readonly IMAGE_CAPTURE_COEFFICIENT: number;
31
+ abstract readonly headless: boolean;
31
32
  protected readonly fontLibrary: IFontLibrary;
32
33
  protected readonly profile$: BehaviorSubject<ICanvasProfile>;
33
34
  protected readonly layoutManager$: BehaviorSubject<ILayoutManager>;
@@ -1,6 +1,7 @@
1
1
  import { fabric } from "fabric";
2
2
  import { AbstractInteractiveCanvas } from "./abstract-interactive-canvas";
3
3
  export declare class HeadlessInteractiveCanvas extends AbstractInteractiveCanvas {
4
+ readonly headless: boolean;
4
5
  constructor();
5
6
  /**
6
7
  * @override
@@ -1,6 +1,7 @@
1
1
  import { AbstractInteractiveCanvas } from "./abstract-interactive-canvas";
2
2
  export declare class InteractiveCanvas extends AbstractInteractiveCanvas {
3
3
  protected devicePixelRatio: number;
4
+ readonly headless: boolean;
4
5
  private readonly undoStack;
5
6
  constructor(elementId: string, devicePixelRatio: number);
6
7
  /**
@@ -284,6 +284,63 @@ var RedrawAllLayoutFunction = /** @class */ (function () {
284
284
  return RedrawAllLayoutFunction;
285
285
  }());
286
286
 
287
+ var RepositionCutoffsLayoutFunction = /** @class */ (function () {
288
+ function RepositionCutoffsLayoutFunction() {
289
+ }
290
+ RepositionCutoffsLayoutFunction.prototype.execute = function (canvas) {
291
+ canvas.getObjectsByTypeInternal(ObjectType.CUTOFF)
292
+ .forEach(function (cutoff) { return cutoff.updatePosition(); });
293
+ };
294
+ return RepositionCutoffsLayoutFunction;
295
+ }());
296
+
297
+ var RepositionBordersLayoutFunction = /** @class */ (function () {
298
+ function RepositionBordersLayoutFunction() {
299
+ }
300
+ RepositionBordersLayoutFunction.prototype.execute = function (canvas) {
301
+ canvas.getObjectsByTypeInternal(ObjectType.BORDER)
302
+ .forEach(function (border) { return border.updatePosition(); });
303
+ };
304
+ return RepositionBordersLayoutFunction;
305
+ }());
306
+
307
+ var PinToBottomLayoutFunction = /** @class */ (function () {
308
+ function PinToBottomLayoutFunction() {
309
+ }
310
+ PinToBottomLayoutFunction.prototype.execute = function (canvas) {
311
+ canvas.getObjectsInternal()
312
+ .forEach(function (object) { return object.moveToPinnedPosition(); });
313
+ };
314
+ return PinToBottomLayoutFunction;
315
+ }());
316
+
317
+ var ResizeCanvasLayoutFunction = /** @class */ (function () {
318
+ function ResizeCanvasLayoutFunction() {
319
+ }
320
+ ResizeCanvasLayoutFunction.prototype.execute = function (canvas) {
321
+ if (canvas.getLayoutManager().isEnforcedPositioning)
322
+ return;
323
+ if (oc(canvas.getDimensionsRestrictions()).fixed(false))
324
+ return;
325
+ var currentDimensions = canvas.getDimensions();
326
+ var baseDimensions = canvas.getBaseDimensions();
327
+ var textHeightIncreasePx = _(canvas.getObjectsByTypeInternal(ObjectType.TEXT))
328
+ .filter(function (text) { return text.isResizeCanvas(); })
329
+ .reduce(function (x, text) { return x + text.getSizeIncreaseSinceCreation(); }, 0);
330
+ var increase = baseDimensions.withSize(currentDimensions.width, 0);
331
+ while (increase.heightPx < textHeightIncreasePx) {
332
+ increase = increase.withSize(increase.width, increase.height + 1);
333
+ }
334
+ var targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
335
+ if (currentDimensions.height !== targetHeight.height) {
336
+ canvas.setDimensions(targetHeight);
337
+ }
338
+ canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
339
+ canvas.redraw();
340
+ };
341
+ return ResizeCanvasLayoutFunction;
342
+ }());
343
+
287
344
  var LayoutManager;
288
345
  (function (LayoutManager) {
289
346
  LayoutManager["LEGACY"] = "LEGACY";
@@ -291,6 +348,45 @@ var LayoutManager;
291
348
  LayoutManager["ADVANCED"] = "ADVANCED";
292
349
  })(LayoutManager || (LayoutManager = {}));
293
350
 
351
+ var RepositionBackgroundsLayoutFunction = /** @class */ (function () {
352
+ function RepositionBackgroundsLayoutFunction() {
353
+ }
354
+ RepositionBackgroundsLayoutFunction.prototype.execute = function (canvas) {
355
+ canvas.getObjectsByTypeInternal(ObjectType.BACKGROUND_IMAGE)
356
+ .forEach(function (border) { return border.updatePosition(); });
357
+ };
358
+ return RepositionBackgroundsLayoutFunction;
359
+ }());
360
+
361
+ var AdvancedLayoutManager = /** @class */ (function (_super) {
362
+ __extends(AdvancedLayoutManager, _super);
363
+ function AdvancedLayoutManager(canvas) {
364
+ var _this = _super.call(this, canvas) || this;
365
+ _this.key = LayoutManager.ADVANCED;
366
+ _this.pinToBottom = new PinToBottomLayoutFunction();
367
+ _this.redrawAll = new RedrawAllLayoutFunction();
368
+ _this.repositionBorders = new RepositionBordersLayoutFunction();
369
+ _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
370
+ _this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
371
+ _this.resizeCanvas = new ResizeCanvasLayoutFunction();
372
+ return _this;
373
+ }
374
+ AdvancedLayoutManager.prototype.onCanvasDimensionsChange = function () {
375
+ this.pinToBottom.execute(this.canvas);
376
+ this.repositionCutoffs.execute(this.canvas);
377
+ this.repositionBorders.execute(this.canvas);
378
+ this.repositionBackgrounds.execute(this.canvas);
379
+ this.redrawAll.execute(this.canvas);
380
+ };
381
+ AdvancedLayoutManager.prototype.onTextChange = function () {
382
+ this.resizeCanvas.execute(this.canvas);
383
+ };
384
+ AdvancedLayoutManager.prototype.onObjectListChange = function () {
385
+ this.redrawAll.execute(this.canvas);
386
+ };
387
+ return AdvancedLayoutManager;
388
+ }(AbstractLayoutManager));
389
+
294
390
  var UpdateObjectDimensionsLayoutFunction = /** @class */ (function () {
295
391
  function UpdateObjectDimensionsLayoutFunction() {
296
392
  }
@@ -454,26 +550,6 @@ var StackObjectsLayoutFunction = /** @class */ (function () {
454
550
  return StackObjectsLayoutFunction;
455
551
  }());
456
552
 
457
- var RepositionBordersLayoutFunction = /** @class */ (function () {
458
- function RepositionBordersLayoutFunction() {
459
- }
460
- RepositionBordersLayoutFunction.prototype.execute = function (canvas) {
461
- canvas.getObjectsByTypeInternal(ObjectType.BORDER)
462
- .forEach(function (border) { return border.updatePosition(); });
463
- };
464
- return RepositionBordersLayoutFunction;
465
- }());
466
-
467
- var RepositionBackgroundsLayoutFunction = /** @class */ (function () {
468
- function RepositionBackgroundsLayoutFunction() {
469
- }
470
- RepositionBackgroundsLayoutFunction.prototype.execute = function (canvas) {
471
- canvas.getObjectsByTypeInternal(ObjectType.BACKGROUND_IMAGE)
472
- .forEach(function (border) { return border.updatePosition(); });
473
- };
474
- return RepositionBackgroundsLayoutFunction;
475
- }());
476
-
477
553
  var StandardLayoutManager = /** @class */ (function (_super) {
478
554
  __extends(StandardLayoutManager, _super);
479
555
  function StandardLayoutManager(canvas) {
@@ -2389,6 +2465,8 @@ var Text = /** @class */ (function (_super) {
2389
2465
  return this.canvas.getSelection().isText && this.textSelection$.value.length > 0;
2390
2466
  };
2391
2467
  Text.prototype.updateTextSelection = function () {
2468
+ if (this.canvas.headless)
2469
+ return;
2392
2470
  this.textSelection$.next(new TextSelection(this.fabricObject, this.fontLibrary));
2393
2471
  this.notifyCanvasOfTextChanges();
2394
2472
  };
@@ -2710,7 +2788,7 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
2710
2788
  */
2711
2789
  AbstractInteractiveCanvas.prototype.setDimensions = function (dimensions) {
2712
2790
  if (this.dimensionsExceedRestrictions(dimensions)) {
2713
- console.debug("Requested canvas dimensions exceed current restrictions", dimensions, this.dimensionRestrictions$.value);
2791
+ console.info("Requested canvas dimensions exceed current restrictions", dimensions, this.dimensionRestrictions$.value);
2714
2792
  this.dimensionChangeRejections$.next(dimensions);
2715
2793
  return;
2716
2794
  }
@@ -3263,7 +3341,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3263
3341
  return __generator(this, function (_a) {
3264
3342
  switch (_a.label) {
3265
3343
  case 0:
3266
- console.debug("Loading canvas state", canvasState);
3267
3344
  this.setBaseDimensions(canvasState.dimensions);
3268
3345
  if (!(canvasState.canvasJson != undefined)) return [3 /*break*/, 2];
3269
3346
  json_1 = JSON.parse(canvasState.canvasJson);
@@ -3327,7 +3404,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3327
3404
  multiplier: multiplier || this.IMAGE_CAPTURE_COEFFICIENT,
3328
3405
  enableRetinaScaling: true
3329
3406
  };
3330
- console.debug("Capturing canvas image", options);
3331
3407
  var base64 = this.executeWithNormalizedCanvas(function () { return _this.fabricCanvas.toDataURL(options); });
3332
3408
  return replace(base64, /^data:.*;base64,/, "");
3333
3409
  };
@@ -3415,7 +3491,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3415
3491
  };
3416
3492
  AbstractInteractiveCanvas.prototype.bindFields = function (persistedFields) {
3417
3493
  var _this = this;
3418
- console.debug("Binding fields", persistedFields);
3419
3494
  var bound = _(persistedFields)
3420
3495
  .flatMap(function (field) {
3421
3496
  try {
@@ -3427,11 +3502,9 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3427
3502
  }
3428
3503
  })
3429
3504
  .value();
3430
- console.debug("Bound fields", bound);
3431
3505
  this.objects$.next(bound);
3432
3506
  };
3433
3507
  AbstractInteractiveCanvas.prototype.bindField = function (persistedField) {
3434
- console.debug("Binding field", persistedField);
3435
3508
  var fabricObject = this.findFabricObject(persistedField.id);
3436
3509
  switch (persistedField.type) {
3437
3510
  case ObjectType.TEXT:
@@ -3491,7 +3564,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3491
3564
  AbstractInteractiveCanvas.prototype.updateCanvasDimensions = function (dims, zoom) {
3492
3565
  var width = dims.widthPx * zoom;
3493
3566
  var height = dims.heightPx * zoom;
3494
- console.debug("Updating canvas dimensions: zoom: " + zoom + ", width: " + width + ", height: " + height);
3495
3567
  this.fabricCanvas.setZoom(zoom);
3496
3568
  this.fabricCanvas.setDimensions({
3497
3569
  width: width,
@@ -3501,7 +3573,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3501
3573
  AbstractInteractiveCanvas.prototype.onProfileChanged = function (profile) {
3502
3574
  this.setMultiSelect(profile.allowMultiSelect);
3503
3575
  this.layoutManager$.value.onProfileChange(profile);
3504
- console.debug("Canvas profile set", profile);
3505
3576
  };
3506
3577
  AbstractInteractiveCanvas.prototype.getFieldByCanvasObject = function (object) {
3507
3578
  if (!object) {
@@ -3562,7 +3633,9 @@ var SelectionData = /** @class */ (function () {
3562
3633
  var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
3563
3634
  __extends(HeadlessInteractiveCanvas, _super);
3564
3635
  function HeadlessInteractiveCanvas() {
3565
- return _super.call(this, fabric, new fabric.StaticCanvas(null, { width: 640, height: 480 }), null) || this;
3636
+ var _this = _super.call(this, fabric, new fabric.StaticCanvas(null, { width: 640, height: 480 }), null) || this;
3637
+ _this.headless = true;
3638
+ return _this;
3566
3639
  }
3567
3640
  /**
3568
3641
  * @override
@@ -3579,9 +3652,13 @@ var UndoStack = /** @class */ (function () {
3579
3652
  this.canvas = canvas;
3580
3653
  this.undoStates = [];
3581
3654
  this.redoStates = [];
3582
- this.lastUndo = null;
3655
+ this.lastState = null;
3583
3656
  this.size = size;
3584
3657
  }
3658
+ /**
3659
+ * @override
3660
+ * @inheritDoc
3661
+ */
3585
3662
  UndoStack.prototype.save = function (state) {
3586
3663
  var currentState = this.canvas.save();
3587
3664
  var undoState = this.undoStates[this.undoStates.length - 1];
@@ -3590,9 +3667,12 @@ var UndoStack = /** @class */ (function () {
3590
3667
  this.undoStates.push(state);
3591
3668
  if (this.undoStates.length > this.size)
3592
3669
  this.undoStates.splice(0, 1);
3593
- if (!isEqual(this.lastUndo, currentState))
3594
- this.redoStates = [];
3670
+ this.clearRedoStackIfCanvasChanged(currentState);
3595
3671
  };
3672
+ /**
3673
+ * @override
3674
+ * @inheritDoc
3675
+ */
3596
3676
  UndoStack.prototype.undo = function () {
3597
3677
  return __awaiter(this, void 0, void 0, function () {
3598
3678
  var undoState, currentState;
@@ -3608,7 +3688,7 @@ var UndoStack = /** @class */ (function () {
3608
3688
  if (!undoState)
3609
3689
  return [2 /*return*/];
3610
3690
  }
3611
- this.lastUndo = undoState;
3691
+ this.lastState = undoState;
3612
3692
  this.redoStates.push(currentState);
3613
3693
  return [4 /*yield*/, this.canvas.load(undoState)];
3614
3694
  case 1:
@@ -3618,18 +3698,23 @@ var UndoStack = /** @class */ (function () {
3618
3698
  });
3619
3699
  });
3620
3700
  };
3701
+ /**
3702
+ * @override
3703
+ * @inheritDoc
3704
+ */
3621
3705
  UndoStack.prototype.redo = function () {
3622
3706
  return __awaiter(this, void 0, void 0, function () {
3623
- var state, currentState;
3707
+ var redoState, currentState;
3624
3708
  return __generator(this, function (_a) {
3625
3709
  switch (_a.label) {
3626
3710
  case 0:
3627
- state = this.redoStates.pop();
3628
- if (!state)
3711
+ redoState = this.redoStates.pop();
3712
+ if (!redoState)
3629
3713
  return [2 /*return*/];
3630
3714
  currentState = this.canvas.save();
3715
+ this.lastState = redoState;
3631
3716
  this.undoStates.push(currentState);
3632
- return [4 /*yield*/, this.canvas.load(state)];
3717
+ return [4 /*yield*/, this.canvas.load(redoState)];
3633
3718
  case 1:
3634
3719
  _a.sent();
3635
3720
  return [2 /*return*/];
@@ -3637,6 +3722,11 @@ var UndoStack = /** @class */ (function () {
3637
3722
  });
3638
3723
  });
3639
3724
  };
3725
+ UndoStack.prototype.clearRedoStackIfCanvasChanged = function (currentState) {
3726
+ if (isEqual(this.lastState, currentState))
3727
+ return;
3728
+ this.redoStates = [];
3729
+ };
3640
3730
  return UndoStack;
3641
3731
  }());
3642
3732
 
@@ -3645,6 +3735,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3645
3735
  function InteractiveCanvas(elementId, devicePixelRatio) {
3646
3736
  var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
3647
3737
  _this.devicePixelRatio = devicePixelRatio;
3738
+ _this.headless = false;
3648
3739
  _this.undoStack = new UndoStack(_this);
3649
3740
  //Initialize watchers
3650
3741
  _this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
@@ -3696,7 +3787,6 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3696
3787
  };
3697
3788
  InteractiveCanvas.prototype.onFabricSelectionChanged = function () {
3698
3789
  var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
3699
- console.debug("Selection changed", selected);
3700
3790
  this.selection$.next(new SelectionData(selected));
3701
3791
  this.enterTextSelectionModeIfRequired();
3702
3792
  };
@@ -3715,80 +3805,4 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3715
3805
  return InteractiveCanvas;
3716
3806
  }(AbstractInteractiveCanvas));
3717
3807
 
3718
- var RepositionCutoffsLayoutFunction = /** @class */ (function () {
3719
- function RepositionCutoffsLayoutFunction() {
3720
- }
3721
- RepositionCutoffsLayoutFunction.prototype.execute = function (canvas) {
3722
- canvas.getObjectsByTypeInternal(ObjectType.CUTOFF)
3723
- .forEach(function (cutoff) { return cutoff.updatePosition(); });
3724
- };
3725
- return RepositionCutoffsLayoutFunction;
3726
- }());
3727
-
3728
- var PinToBottomLayoutFunction = /** @class */ (function () {
3729
- function PinToBottomLayoutFunction() {
3730
- }
3731
- PinToBottomLayoutFunction.prototype.execute = function (canvas) {
3732
- canvas.getObjectsInternal()
3733
- .forEach(function (object) { return object.moveToPinnedPosition(); });
3734
- };
3735
- return PinToBottomLayoutFunction;
3736
- }());
3737
-
3738
- var ResizeCanvasLayoutFunction = /** @class */ (function () {
3739
- function ResizeCanvasLayoutFunction() {
3740
- }
3741
- ResizeCanvasLayoutFunction.prototype.execute = function (canvas) {
3742
- if (canvas.getLayoutManager().isEnforcedPositioning)
3743
- return;
3744
- if (oc(canvas.getDimensionsRestrictions()).fixed(false))
3745
- return;
3746
- var currentDimensions = canvas.getDimensions();
3747
- var baseDimensions = canvas.getBaseDimensions();
3748
- var textHeightIncreasePx = _(canvas.getObjectsByTypeInternal(ObjectType.TEXT))
3749
- .filter(function (text) { return text.isResizeCanvas(); })
3750
- .reduce(function (x, text) { return x + text.getSizeIncreaseSinceCreation(); }, 0);
3751
- var increase = baseDimensions.withSize(currentDimensions.width, 0);
3752
- while (increase.heightPx < textHeightIncreasePx) {
3753
- increase = increase.withSize(increase.width, increase.height + 1);
3754
- }
3755
- var targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
3756
- if (currentDimensions.height !== targetHeight.height) {
3757
- canvas.setDimensions(targetHeight);
3758
- }
3759
- canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
3760
- canvas.redraw();
3761
- };
3762
- return ResizeCanvasLayoutFunction;
3763
- }());
3764
-
3765
- var AdvancedLayoutManager = /** @class */ (function (_super) {
3766
- __extends(AdvancedLayoutManager, _super);
3767
- function AdvancedLayoutManager(canvas) {
3768
- var _this = _super.call(this, canvas) || this;
3769
- _this.key = LayoutManager.ADVANCED;
3770
- _this.pinToBottom = new PinToBottomLayoutFunction();
3771
- _this.redrawAll = new RedrawAllLayoutFunction();
3772
- _this.repositionBorders = new RepositionBordersLayoutFunction();
3773
- _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
3774
- _this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
3775
- _this.resizeCanvas = new ResizeCanvasLayoutFunction();
3776
- return _this;
3777
- }
3778
- AdvancedLayoutManager.prototype.onCanvasDimensionsChange = function () {
3779
- this.pinToBottom.execute(this.canvas);
3780
- this.repositionCutoffs.execute(this.canvas);
3781
- this.repositionBorders.execute(this.canvas);
3782
- this.repositionBackgrounds.execute(this.canvas);
3783
- this.redrawAll.execute(this.canvas);
3784
- };
3785
- AdvancedLayoutManager.prototype.onTextChange = function () {
3786
- this.resizeCanvas.execute(this.canvas);
3787
- };
3788
- AdvancedLayoutManager.prototype.onObjectListChange = function () {
3789
- this.redrawAll.execute(this.canvas);
3790
- };
3791
- return AdvancedLayoutManager;
3792
- }(AbstractLayoutManager));
3793
-
3794
3808
  export { AbstractCanvasObject, AbstractInteractiveCanvas, AbstractLayoutManager, AdvancedLayoutManager, BackgroundImage, Border, CanvasObjectData, Cutoff, DefaultCanvasProfile, Font, FontLibrary, HeadlessInteractiveCanvas, HorizontalRule, Image, ImageType, InteractiveCanvas, LayoutManager, MillimeterDimensions, ObjectType, PixelCanvasDimensions, Print6ColCanvasDimensions, Print8ColCanvasDimensions, Rectangle, RichText, SelectionData, StandardLayoutManager, Text, UNKNOWN_FONT, UnknownFont, VerticalRule, isMutableBackgroundColor, isMutableColor, isMutableImage, isMutablePosition, isMutableStroke, isMutableText, isMutableTextStyle };
@@ -25,6 +25,10 @@ import { IBackgroundImage } from "./object/impl/background-image";
25
25
  * New leapfrog canvas implementation c. 2019.
26
26
  */
27
27
  export interface IInteractiveCanvas {
28
+ /**
29
+ * True if the canvas is operating in a headless mode.
30
+ */
31
+ readonly headless: boolean;
28
32
  /**
29
33
  * Get the canvas font library.
30
34
  */
@@ -287,12 +287,108 @@ var RedrawAllLayoutFunction = /** @class */ (function () {
287
287
  return RedrawAllLayoutFunction;
288
288
  }());
289
289
 
290
+ var RepositionCutoffsLayoutFunction = /** @class */ (function () {
291
+ function RepositionCutoffsLayoutFunction() {
292
+ }
293
+ RepositionCutoffsLayoutFunction.prototype.execute = function (canvas) {
294
+ canvas.getObjectsByTypeInternal(exports.ObjectType.CUTOFF)
295
+ .forEach(function (cutoff) { return cutoff.updatePosition(); });
296
+ };
297
+ return RepositionCutoffsLayoutFunction;
298
+ }());
299
+
300
+ var RepositionBordersLayoutFunction = /** @class */ (function () {
301
+ function RepositionBordersLayoutFunction() {
302
+ }
303
+ RepositionBordersLayoutFunction.prototype.execute = function (canvas) {
304
+ canvas.getObjectsByTypeInternal(exports.ObjectType.BORDER)
305
+ .forEach(function (border) { return border.updatePosition(); });
306
+ };
307
+ return RepositionBordersLayoutFunction;
308
+ }());
309
+
310
+ var PinToBottomLayoutFunction = /** @class */ (function () {
311
+ function PinToBottomLayoutFunction() {
312
+ }
313
+ PinToBottomLayoutFunction.prototype.execute = function (canvas) {
314
+ canvas.getObjectsInternal()
315
+ .forEach(function (object) { return object.moveToPinnedPosition(); });
316
+ };
317
+ return PinToBottomLayoutFunction;
318
+ }());
319
+
320
+ var ResizeCanvasLayoutFunction = /** @class */ (function () {
321
+ function ResizeCanvasLayoutFunction() {
322
+ }
323
+ ResizeCanvasLayoutFunction.prototype.execute = function (canvas) {
324
+ if (canvas.getLayoutManager().isEnforcedPositioning)
325
+ return;
326
+ if (tsOptchain.oc(canvas.getDimensionsRestrictions()).fixed(false))
327
+ return;
328
+ var currentDimensions = canvas.getDimensions();
329
+ var baseDimensions = canvas.getBaseDimensions();
330
+ var textHeightIncreasePx = _(canvas.getObjectsByTypeInternal(exports.ObjectType.TEXT))
331
+ .filter(function (text) { return text.isResizeCanvas(); })
332
+ .reduce(function (x, text) { return x + text.getSizeIncreaseSinceCreation(); }, 0);
333
+ var increase = baseDimensions.withSize(currentDimensions.width, 0);
334
+ while (increase.heightPx < textHeightIncreasePx) {
335
+ increase = increase.withSize(increase.width, increase.height + 1);
336
+ }
337
+ var targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
338
+ if (currentDimensions.height !== targetHeight.height) {
339
+ canvas.setDimensions(targetHeight);
340
+ }
341
+ canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
342
+ canvas.redraw();
343
+ };
344
+ return ResizeCanvasLayoutFunction;
345
+ }());
346
+
290
347
  (function (LayoutManager) {
291
348
  LayoutManager["LEGACY"] = "LEGACY";
292
349
  LayoutManager["STANDARD"] = "STANDARD";
293
350
  LayoutManager["ADVANCED"] = "ADVANCED";
294
351
  })(exports.LayoutManager || (exports.LayoutManager = {}));
295
352
 
353
+ var RepositionBackgroundsLayoutFunction = /** @class */ (function () {
354
+ function RepositionBackgroundsLayoutFunction() {
355
+ }
356
+ RepositionBackgroundsLayoutFunction.prototype.execute = function (canvas) {
357
+ canvas.getObjectsByTypeInternal(exports.ObjectType.BACKGROUND_IMAGE)
358
+ .forEach(function (border) { return border.updatePosition(); });
359
+ };
360
+ return RepositionBackgroundsLayoutFunction;
361
+ }());
362
+
363
+ var AdvancedLayoutManager = /** @class */ (function (_super) {
364
+ __extends(AdvancedLayoutManager, _super);
365
+ function AdvancedLayoutManager(canvas) {
366
+ var _this = _super.call(this, canvas) || this;
367
+ _this.key = exports.LayoutManager.ADVANCED;
368
+ _this.pinToBottom = new PinToBottomLayoutFunction();
369
+ _this.redrawAll = new RedrawAllLayoutFunction();
370
+ _this.repositionBorders = new RepositionBordersLayoutFunction();
371
+ _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
372
+ _this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
373
+ _this.resizeCanvas = new ResizeCanvasLayoutFunction();
374
+ return _this;
375
+ }
376
+ AdvancedLayoutManager.prototype.onCanvasDimensionsChange = function () {
377
+ this.pinToBottom.execute(this.canvas);
378
+ this.repositionCutoffs.execute(this.canvas);
379
+ this.repositionBorders.execute(this.canvas);
380
+ this.repositionBackgrounds.execute(this.canvas);
381
+ this.redrawAll.execute(this.canvas);
382
+ };
383
+ AdvancedLayoutManager.prototype.onTextChange = function () {
384
+ this.resizeCanvas.execute(this.canvas);
385
+ };
386
+ AdvancedLayoutManager.prototype.onObjectListChange = function () {
387
+ this.redrawAll.execute(this.canvas);
388
+ };
389
+ return AdvancedLayoutManager;
390
+ }(AbstractLayoutManager));
391
+
296
392
  var UpdateObjectDimensionsLayoutFunction = /** @class */ (function () {
297
393
  function UpdateObjectDimensionsLayoutFunction() {
298
394
  }
@@ -456,26 +552,6 @@ var StackObjectsLayoutFunction = /** @class */ (function () {
456
552
  return StackObjectsLayoutFunction;
457
553
  }());
458
554
 
459
- var RepositionBordersLayoutFunction = /** @class */ (function () {
460
- function RepositionBordersLayoutFunction() {
461
- }
462
- RepositionBordersLayoutFunction.prototype.execute = function (canvas) {
463
- canvas.getObjectsByTypeInternal(exports.ObjectType.BORDER)
464
- .forEach(function (border) { return border.updatePosition(); });
465
- };
466
- return RepositionBordersLayoutFunction;
467
- }());
468
-
469
- var RepositionBackgroundsLayoutFunction = /** @class */ (function () {
470
- function RepositionBackgroundsLayoutFunction() {
471
- }
472
- RepositionBackgroundsLayoutFunction.prototype.execute = function (canvas) {
473
- canvas.getObjectsByTypeInternal(exports.ObjectType.BACKGROUND_IMAGE)
474
- .forEach(function (border) { return border.updatePosition(); });
475
- };
476
- return RepositionBackgroundsLayoutFunction;
477
- }());
478
-
479
555
  var StandardLayoutManager = /** @class */ (function (_super) {
480
556
  __extends(StandardLayoutManager, _super);
481
557
  function StandardLayoutManager(canvas) {
@@ -2391,6 +2467,8 @@ var Text = /** @class */ (function (_super) {
2391
2467
  return this.canvas.getSelection().isText && this.textSelection$.value.length > 0;
2392
2468
  };
2393
2469
  Text.prototype.updateTextSelection = function () {
2470
+ if (this.canvas.headless)
2471
+ return;
2394
2472
  this.textSelection$.next(new TextSelection(this.fabricObject, this.fontLibrary));
2395
2473
  this.notifyCanvasOfTextChanges();
2396
2474
  };
@@ -2710,7 +2788,7 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
2710
2788
  */
2711
2789
  AbstractInteractiveCanvas.prototype.setDimensions = function (dimensions) {
2712
2790
  if (this.dimensionsExceedRestrictions(dimensions)) {
2713
- console.debug("Requested canvas dimensions exceed current restrictions", dimensions, this.dimensionRestrictions$.value);
2791
+ console.info("Requested canvas dimensions exceed current restrictions", dimensions, this.dimensionRestrictions$.value);
2714
2792
  this.dimensionChangeRejections$.next(dimensions);
2715
2793
  return;
2716
2794
  }
@@ -3263,7 +3341,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3263
3341
  return __generator(this, function (_a) {
3264
3342
  switch (_a.label) {
3265
3343
  case 0:
3266
- console.debug("Loading canvas state", canvasState);
3267
3344
  this.setBaseDimensions(canvasState.dimensions);
3268
3345
  if (!(canvasState.canvasJson != undefined)) return [3 /*break*/, 2];
3269
3346
  json_1 = JSON.parse(canvasState.canvasJson);
@@ -3327,7 +3404,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3327
3404
  multiplier: multiplier || this.IMAGE_CAPTURE_COEFFICIENT,
3328
3405
  enableRetinaScaling: true
3329
3406
  };
3330
- console.debug("Capturing canvas image", options);
3331
3407
  var base64 = this.executeWithNormalizedCanvas(function () { return _this.fabricCanvas.toDataURL(options); });
3332
3408
  return _.replace(base64, /^data:.*;base64,/, "");
3333
3409
  };
@@ -3415,7 +3491,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3415
3491
  };
3416
3492
  AbstractInteractiveCanvas.prototype.bindFields = function (persistedFields) {
3417
3493
  var _this = this;
3418
- console.debug("Binding fields", persistedFields);
3419
3494
  var bound = _(persistedFields)
3420
3495
  .flatMap(function (field) {
3421
3496
  try {
@@ -3427,11 +3502,9 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3427
3502
  }
3428
3503
  })
3429
3504
  .value();
3430
- console.debug("Bound fields", bound);
3431
3505
  this.objects$.next(bound);
3432
3506
  };
3433
3507
  AbstractInteractiveCanvas.prototype.bindField = function (persistedField) {
3434
- console.debug("Binding field", persistedField);
3435
3508
  var fabricObject = this.findFabricObject(persistedField.id);
3436
3509
  switch (persistedField.type) {
3437
3510
  case exports.ObjectType.TEXT:
@@ -3491,7 +3564,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3491
3564
  AbstractInteractiveCanvas.prototype.updateCanvasDimensions = function (dims, zoom) {
3492
3565
  var width = dims.widthPx * zoom;
3493
3566
  var height = dims.heightPx * zoom;
3494
- console.debug("Updating canvas dimensions: zoom: " + zoom + ", width: " + width + ", height: " + height);
3495
3567
  this.fabricCanvas.setZoom(zoom);
3496
3568
  this.fabricCanvas.setDimensions({
3497
3569
  width: width,
@@ -3501,7 +3573,6 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3501
3573
  AbstractInteractiveCanvas.prototype.onProfileChanged = function (profile) {
3502
3574
  this.setMultiSelect(profile.allowMultiSelect);
3503
3575
  this.layoutManager$.value.onProfileChange(profile);
3504
- console.debug("Canvas profile set", profile);
3505
3576
  };
3506
3577
  AbstractInteractiveCanvas.prototype.getFieldByCanvasObject = function (object) {
3507
3578
  if (!object) {
@@ -3562,7 +3633,9 @@ var SelectionData = /** @class */ (function () {
3562
3633
  var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
3563
3634
  __extends(HeadlessInteractiveCanvas, _super);
3564
3635
  function HeadlessInteractiveCanvas() {
3565
- return _super.call(this, fabric.fabric, new fabric.fabric.StaticCanvas(null, { width: 640, height: 480 }), null) || this;
3636
+ var _this = _super.call(this, fabric.fabric, new fabric.fabric.StaticCanvas(null, { width: 640, height: 480 }), null) || this;
3637
+ _this.headless = true;
3638
+ return _this;
3566
3639
  }
3567
3640
  /**
3568
3641
  * @override
@@ -3579,9 +3652,13 @@ var UndoStack = /** @class */ (function () {
3579
3652
  this.canvas = canvas;
3580
3653
  this.undoStates = [];
3581
3654
  this.redoStates = [];
3582
- this.lastUndo = null;
3655
+ this.lastState = null;
3583
3656
  this.size = size;
3584
3657
  }
3658
+ /**
3659
+ * @override
3660
+ * @inheritDoc
3661
+ */
3585
3662
  UndoStack.prototype.save = function (state) {
3586
3663
  var currentState = this.canvas.save();
3587
3664
  var undoState = this.undoStates[this.undoStates.length - 1];
@@ -3590,9 +3667,12 @@ var UndoStack = /** @class */ (function () {
3590
3667
  this.undoStates.push(state);
3591
3668
  if (this.undoStates.length > this.size)
3592
3669
  this.undoStates.splice(0, 1);
3593
- if (!_.isEqual(this.lastUndo, currentState))
3594
- this.redoStates = [];
3670
+ this.clearRedoStackIfCanvasChanged(currentState);
3595
3671
  };
3672
+ /**
3673
+ * @override
3674
+ * @inheritDoc
3675
+ */
3596
3676
  UndoStack.prototype.undo = function () {
3597
3677
  return __awaiter(this, void 0, void 0, function () {
3598
3678
  var undoState, currentState;
@@ -3608,7 +3688,7 @@ var UndoStack = /** @class */ (function () {
3608
3688
  if (!undoState)
3609
3689
  return [2 /*return*/];
3610
3690
  }
3611
- this.lastUndo = undoState;
3691
+ this.lastState = undoState;
3612
3692
  this.redoStates.push(currentState);
3613
3693
  return [4 /*yield*/, this.canvas.load(undoState)];
3614
3694
  case 1:
@@ -3618,18 +3698,23 @@ var UndoStack = /** @class */ (function () {
3618
3698
  });
3619
3699
  });
3620
3700
  };
3701
+ /**
3702
+ * @override
3703
+ * @inheritDoc
3704
+ */
3621
3705
  UndoStack.prototype.redo = function () {
3622
3706
  return __awaiter(this, void 0, void 0, function () {
3623
- var state, currentState;
3707
+ var redoState, currentState;
3624
3708
  return __generator(this, function (_a) {
3625
3709
  switch (_a.label) {
3626
3710
  case 0:
3627
- state = this.redoStates.pop();
3628
- if (!state)
3711
+ redoState = this.redoStates.pop();
3712
+ if (!redoState)
3629
3713
  return [2 /*return*/];
3630
3714
  currentState = this.canvas.save();
3715
+ this.lastState = redoState;
3631
3716
  this.undoStates.push(currentState);
3632
- return [4 /*yield*/, this.canvas.load(state)];
3717
+ return [4 /*yield*/, this.canvas.load(redoState)];
3633
3718
  case 1:
3634
3719
  _a.sent();
3635
3720
  return [2 /*return*/];
@@ -3637,6 +3722,11 @@ var UndoStack = /** @class */ (function () {
3637
3722
  });
3638
3723
  });
3639
3724
  };
3725
+ UndoStack.prototype.clearRedoStackIfCanvasChanged = function (currentState) {
3726
+ if (_.isEqual(this.lastState, currentState))
3727
+ return;
3728
+ this.redoStates = [];
3729
+ };
3640
3730
  return UndoStack;
3641
3731
  }());
3642
3732
 
@@ -3645,6 +3735,7 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3645
3735
  function InteractiveCanvas(elementId, devicePixelRatio) {
3646
3736
  var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
3647
3737
  _this.devicePixelRatio = devicePixelRatio;
3738
+ _this.headless = false;
3648
3739
  _this.undoStack = new UndoStack(_this);
3649
3740
  //Initialize watchers
3650
3741
  _this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
@@ -3696,7 +3787,6 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3696
3787
  };
3697
3788
  InteractiveCanvas.prototype.onFabricSelectionChanged = function () {
3698
3789
  var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
3699
- console.debug("Selection changed", selected);
3700
3790
  this.selection$.next(new SelectionData(selected));
3701
3791
  this.enterTextSelectionModeIfRequired();
3702
3792
  };
@@ -3715,82 +3805,6 @@ var InteractiveCanvas = /** @class */ (function (_super) {
3715
3805
  return InteractiveCanvas;
3716
3806
  }(AbstractInteractiveCanvas));
3717
3807
 
3718
- var RepositionCutoffsLayoutFunction = /** @class */ (function () {
3719
- function RepositionCutoffsLayoutFunction() {
3720
- }
3721
- RepositionCutoffsLayoutFunction.prototype.execute = function (canvas) {
3722
- canvas.getObjectsByTypeInternal(exports.ObjectType.CUTOFF)
3723
- .forEach(function (cutoff) { return cutoff.updatePosition(); });
3724
- };
3725
- return RepositionCutoffsLayoutFunction;
3726
- }());
3727
-
3728
- var PinToBottomLayoutFunction = /** @class */ (function () {
3729
- function PinToBottomLayoutFunction() {
3730
- }
3731
- PinToBottomLayoutFunction.prototype.execute = function (canvas) {
3732
- canvas.getObjectsInternal()
3733
- .forEach(function (object) { return object.moveToPinnedPosition(); });
3734
- };
3735
- return PinToBottomLayoutFunction;
3736
- }());
3737
-
3738
- var ResizeCanvasLayoutFunction = /** @class */ (function () {
3739
- function ResizeCanvasLayoutFunction() {
3740
- }
3741
- ResizeCanvasLayoutFunction.prototype.execute = function (canvas) {
3742
- if (canvas.getLayoutManager().isEnforcedPositioning)
3743
- return;
3744
- if (tsOptchain.oc(canvas.getDimensionsRestrictions()).fixed(false))
3745
- return;
3746
- var currentDimensions = canvas.getDimensions();
3747
- var baseDimensions = canvas.getBaseDimensions();
3748
- var textHeightIncreasePx = _(canvas.getObjectsByTypeInternal(exports.ObjectType.TEXT))
3749
- .filter(function (text) { return text.isResizeCanvas(); })
3750
- .reduce(function (x, text) { return x + text.getSizeIncreaseSinceCreation(); }, 0);
3751
- var increase = baseDimensions.withSize(currentDimensions.width, 0);
3752
- while (increase.heightPx < textHeightIncreasePx) {
3753
- increase = increase.withSize(increase.width, increase.height + 1);
3754
- }
3755
- var targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
3756
- if (currentDimensions.height !== targetHeight.height) {
3757
- canvas.setDimensions(targetHeight);
3758
- }
3759
- canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
3760
- canvas.redraw();
3761
- };
3762
- return ResizeCanvasLayoutFunction;
3763
- }());
3764
-
3765
- var AdvancedLayoutManager = /** @class */ (function (_super) {
3766
- __extends(AdvancedLayoutManager, _super);
3767
- function AdvancedLayoutManager(canvas) {
3768
- var _this = _super.call(this, canvas) || this;
3769
- _this.key = exports.LayoutManager.ADVANCED;
3770
- _this.pinToBottom = new PinToBottomLayoutFunction();
3771
- _this.redrawAll = new RedrawAllLayoutFunction();
3772
- _this.repositionBorders = new RepositionBordersLayoutFunction();
3773
- _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
3774
- _this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
3775
- _this.resizeCanvas = new ResizeCanvasLayoutFunction();
3776
- return _this;
3777
- }
3778
- AdvancedLayoutManager.prototype.onCanvasDimensionsChange = function () {
3779
- this.pinToBottom.execute(this.canvas);
3780
- this.repositionCutoffs.execute(this.canvas);
3781
- this.repositionBorders.execute(this.canvas);
3782
- this.repositionBackgrounds.execute(this.canvas);
3783
- this.redrawAll.execute(this.canvas);
3784
- };
3785
- AdvancedLayoutManager.prototype.onTextChange = function () {
3786
- this.resizeCanvas.execute(this.canvas);
3787
- };
3788
- AdvancedLayoutManager.prototype.onObjectListChange = function () {
3789
- this.redrawAll.execute(this.canvas);
3790
- };
3791
- return AdvancedLayoutManager;
3792
- }(AbstractLayoutManager));
3793
-
3794
3808
  exports.AbstractCanvasObject = AbstractCanvasObject;
3795
3809
  exports.AbstractInteractiveCanvas = AbstractInteractiveCanvas;
3796
3810
  exports.AbstractLayoutManager = AbstractLayoutManager;
@@ -1,13 +1,27 @@
1
1
  import { ICanvasState } from "./types/canvas-state.interface";
2
2
  import { IInteractiveCanvas } from "./interactive-canvas.interface";
3
- export declare class UndoStack {
3
+ import { IUndoStack } from "./undo-stack.interface";
4
+ export declare class UndoStack implements IUndoStack {
4
5
  protected canvas: IInteractiveCanvas;
5
6
  private readonly size;
6
7
  private undoStates;
7
8
  private redoStates;
8
- private lastUndo;
9
+ private lastState;
9
10
  constructor(canvas: IInteractiveCanvas, size?: number);
11
+ /**
12
+ * @override
13
+ * @inheritDoc
14
+ */
10
15
  save(state: ICanvasState): void;
16
+ /**
17
+ * @override
18
+ * @inheritDoc
19
+ */
11
20
  undo(): Promise<void>;
21
+ /**
22
+ * @override
23
+ * @inheritDoc
24
+ */
12
25
  redo(): Promise<void>;
26
+ private clearRedoStackIfCanvasChanged;
13
27
  }
@@ -0,0 +1,6 @@
1
+ import { ICanvasState } from "./types/canvas-state.interface";
2
+ export interface IUndoStack {
3
+ save(state: ICanvasState): void;
4
+ undo(): Promise<void>;
5
+ redo(): Promise<void>;
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leapfrog/interactive-canvas",
3
- "version": "1.12.1",
3
+ "version": "1.13.0",
4
4
  "description": "Leapfrog interactive canvas",
5
5
  "files": [
6
6
  "dist"