@leapfrog/interactive-canvas 2.0.21-beta-2 → 2.0.21

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.
@@ -19,6 +19,7 @@ import { ObjectType } from "./types/object-type.enum";
19
19
  import { ICanvasObject } from "./object/canvas-object.interface";
20
20
  import { ISelectionData } from "./types/selection-data.interface";
21
21
  import { ICanvasState } from "./types/canvas-state.interface";
22
+ import { CanvasObjectData } from "./object/canvas-object-data";
22
23
  import { ITextSelection } from "./mutator/mutable-text-style.interface";
23
24
  import { TEvent, FabricObject, Canvas } from "fabric";
24
25
  import { IRichText } from "./object/impl/rich-text";
@@ -334,6 +335,11 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
334
335
  * @inheritDoc
335
336
  */
336
337
  redo(): Promise<void>;
338
+ /**
339
+ * @override
340
+ * @inheritDoc
341
+ */
342
+ cloneObject(sourceObject: FabricObject, objectData: CanvasObjectData): Promise<void>;
337
343
  /**
338
344
  * Redraw the canvas.
339
345
  */
@@ -1,4 +1,4 @@
1
- import _, { round, each, values, reduce, clone, isEqual } from 'lodash';
1
+ import _, { round, each, values, reduce, clone, max, isEqual } from 'lodash';
2
2
  import { BehaviorSubject, Subject } from 'rxjs';
3
3
  import * as fabric from 'fabric';
4
4
 
@@ -533,6 +533,38 @@ function isMutableText(object) {
533
533
  return "setText" in object;
534
534
  }
535
535
 
536
+ /******************************************************************************
537
+ Copyright (c) Microsoft Corporation.
538
+
539
+ Permission to use, copy, modify, and/or distribute this software for any
540
+ purpose with or without fee is hereby granted.
541
+
542
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
543
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
544
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
545
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
546
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
547
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
548
+ PERFORMANCE OF THIS SOFTWARE.
549
+ ***************************************************************************** */
550
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
551
+
552
+
553
+ function __awaiter(thisArg, _arguments, P, generator) {
554
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
555
+ return new (P || (P = Promise))(function (resolve, reject) {
556
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
557
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
558
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
559
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
560
+ });
561
+ }
562
+
563
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
564
+ var e = new Error(message);
565
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
566
+ };
567
+
536
568
  /**
537
569
  * Data for a persisted canvas object.
538
570
  */
@@ -765,6 +797,15 @@ class AbstractCanvasObject {
765
797
  this.canvas.removeObject(this);
766
798
  this.onDelete();
767
799
  }
800
+ /**
801
+ * @override
802
+ * @inheritDoc
803
+ */
804
+ clone() {
805
+ return __awaiter(this, void 0, void 0, function* () {
806
+ yield this.canvas.cloneObject(this.fabricObject, this.data);
807
+ });
808
+ }
768
809
  /**
769
810
  * @override
770
811
  * @inheritDoc
@@ -1020,38 +1061,6 @@ class FieldDimensions {
1020
1061
  }
1021
1062
  }
1022
1063
 
1023
- /******************************************************************************
1024
- Copyright (c) Microsoft Corporation.
1025
-
1026
- Permission to use, copy, modify, and/or distribute this software for any
1027
- purpose with or without fee is hereby granted.
1028
-
1029
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1030
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1031
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1032
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1033
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1034
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1035
- PERFORMANCE OF THIS SOFTWARE.
1036
- ***************************************************************************** */
1037
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1038
-
1039
-
1040
- function __awaiter(thisArg, _arguments, P, generator) {
1041
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1042
- return new (P || (P = Promise))(function (resolve, reject) {
1043
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1044
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1045
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1046
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1047
- });
1048
- }
1049
-
1050
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1051
- var e = new Error(message);
1052
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1053
- };
1054
-
1055
1064
  class BackgroundImage extends AbstractCanvasObject {
1056
1065
  constructor(canvas, fabricObject, persistedField) {
1057
1066
  super(ObjectType.BACKGROUND_IMAGE, canvas, fabricObject, persistedField);
@@ -1777,7 +1786,7 @@ class Text extends AbstractCanvasObject {
1777
1786
  this.data.userText = this.fabricObject.text;
1778
1787
  this.textSelection$ = new BehaviorSubject(new TextSelection(this.fabricObject, this.fontLibrary));
1779
1788
  this.fabricObject.set({ strokeWidth: 0 });
1780
- this.fabricObject.on("text:changed", () => this.onTextChange());
1789
+ this.fabricObject.on("changed", () => this.onTextChange());
1781
1790
  this.fabricObject.on("selection:changed", () => this.onSelectionChange());
1782
1791
  this.applyBulletListMonkeyPatches();
1783
1792
  }
@@ -2028,11 +2037,12 @@ class Text extends AbstractCanvasObject {
2028
2037
  */
2029
2038
  setFontSize(fontSize) {
2030
2039
  if (this.hasTextSelection()) {
2031
- this.fabricObject.setSelectionStyles({ fontSize });
2040
+ this.fabricObject.setSelectionStyles({ fontSize: fontSize });
2032
2041
  }
2033
2042
  else {
2034
2043
  this.fabricObject.set({ fontSize: fontSize });
2035
2044
  }
2045
+ this.fabricObject.dirty = true;
2036
2046
  this.redraw();
2037
2047
  this.updateTextSelection();
2038
2048
  }
@@ -2130,7 +2140,7 @@ class Text extends AbstractCanvasObject {
2130
2140
  if (!this.isBulleted())
2131
2141
  return 0;
2132
2142
  let fontSize = 0;
2133
- _.each(this.fabricObject._textLines, (textLine, lineIndex) => {
2143
+ each(this.fabricObject._textLines, (textLine, lineIndex) => {
2134
2144
  fontSize = Math.max(fontSize, this.fabricObject.getValueOfPropertyAt(lineIndex, 0, "fontSize"));
2135
2145
  });
2136
2146
  return fontSize * 0.6;
@@ -2143,11 +2153,10 @@ class Text extends AbstractCanvasObject {
2143
2153
  if (!this.isOrderedList())
2144
2154
  return 0;
2145
2155
  const orderedListMarkerEntities = this.fabricObject._orderedListMarkerEntities;
2146
- let max = _(orderedListMarkerEntities)
2156
+ let maxValue = max((orderedListMarkerEntities !== null && orderedListMarkerEntities !== void 0 ? orderedListMarkerEntities : [])
2147
2157
  .filter((x) => !!x)
2148
- .map((x) => x.getBoundingRect().width)
2149
- .max();
2150
- return max ? (max * 1.2) : 0;
2158
+ .map((x) => x.getBoundingRect().width));
2159
+ return maxValue ? (maxValue * 1.2) : 0;
2151
2160
  }
2152
2161
  /**
2153
2162
  * @override
@@ -2281,7 +2290,7 @@ class Text extends AbstractCanvasObject {
2281
2290
  if (this.data.bulleted) {
2282
2291
  const bullets = this.fabricObject["_bullets"];
2283
2292
  delete this.fabricObject["_bullets"];
2284
- _.each(bullets, (bullet) => this.canvas.removeFabricObject(bullet));
2293
+ each(bullets, (bullet) => this.canvas.removeFabricObject(bullet));
2285
2294
  this.fabricObject["objectCaching"] = true;
2286
2295
  }
2287
2296
  }
@@ -2289,7 +2298,7 @@ class Text extends AbstractCanvasObject {
2289
2298
  if (this.fabricObject._isOrderedList) {
2290
2299
  const markerEntities = this.fabricObject._orderedListMarkerEntities;
2291
2300
  delete this.fabricObject._orderedListMarkerEntities;
2292
- _.each(markerEntities, (marker) => this.canvas.removeFabricObject(marker));
2301
+ each(markerEntities, (marker) => this.canvas.removeFabricObject(marker));
2293
2302
  this.fabricObject["objectCaching"] = true;
2294
2303
  }
2295
2304
  }
@@ -2306,7 +2315,7 @@ class Text extends AbstractCanvasObject {
2306
2315
  // Determine list of active bullets
2307
2316
  const currentBullets = this.fabricObject.get("_bullets");
2308
2317
  const activeBullets = {};
2309
- _.each(this.fabricObject._textLines, (textLine, lineIndex) => {
2318
+ each(this.fabricObject._textLines, (textLine, lineIndex) => {
2310
2319
  if (textLine.length) {
2311
2320
  // Start of real lines will have offset 0 in styleMap
2312
2321
  const styleMap = this.fabricObject._styleMap[lineIndex];
@@ -2343,13 +2352,13 @@ class Text extends AbstractCanvasObject {
2343
2352
  let canvasDirty = false;
2344
2353
  if (canvas) {
2345
2354
  canvas.renderOnAddRemove = false;
2346
- _.each(activeBullets, (bullet) => {
2355
+ each(activeBullets, (bullet) => {
2347
2356
  if (!canvas.contains(bullet)) {
2348
2357
  canvas.add(bullet);
2349
2358
  canvasDirty = true;
2350
2359
  }
2351
2360
  });
2352
- _.each(currentBullets, (bullet, key) => {
2361
+ each(currentBullets, (bullet, key) => {
2353
2362
  if (!activeBullets[key]) {
2354
2363
  canvas.remove(bullet);
2355
2364
  canvasDirty = true;
@@ -2366,7 +2375,7 @@ class Text extends AbstractCanvasObject {
2366
2375
  if (this.fabricObject._isOrderedList) {
2367
2376
  const existingMarkers = (_a = this.fabricObject._orderedListMarkerEntities) !== null && _a !== void 0 ? _a : [];
2368
2377
  const activeMarkers = [];
2369
- _.each(this.fabricObject._textLines, (textLine, lineIndex) => {
2378
+ each(this.fabricObject._textLines, (textLine, lineIndex) => {
2370
2379
  if (textLine.length) {
2371
2380
  // Start of real lines will have offset 0 in styleMap
2372
2381
  const styleMap = this.fabricObject._styleMap[lineIndex];
@@ -2402,7 +2411,7 @@ class Text extends AbstractCanvasObject {
2402
2411
  let canvasDirty = false;
2403
2412
  if (canvas) {
2404
2413
  canvas.renderOnAddRemove = false;
2405
- _.each(activeMarkers, (marker) => {
2414
+ each(activeMarkers, (marker) => {
2406
2415
  if (!marker)
2407
2416
  return;
2408
2417
  if (!canvas.contains(marker)) {
@@ -2410,7 +2419,7 @@ class Text extends AbstractCanvasObject {
2410
2419
  canvasDirty = true;
2411
2420
  }
2412
2421
  });
2413
- _.each(existingMarkers, (marker, key) => {
2422
+ each(existingMarkers, (marker, key) => {
2414
2423
  if (!marker)
2415
2424
  return;
2416
2425
  if (!activeMarkers[key]) {
@@ -3502,6 +3511,33 @@ class AbstractInteractiveCanvas {
3502
3511
  redo() {
3503
3512
  throw new Error("Redo not supported on this canvas type");
3504
3513
  }
3514
+ /**
3515
+ * @override
3516
+ * @inheritDoc
3517
+ */
3518
+ cloneObject(sourceObject, objectData) {
3519
+ return __awaiter(this, void 0, void 0, function* () {
3520
+ if (sourceObject && (sourceObject.type === 'text' || sourceObject.type === 'textbox')) {
3521
+ const clonedObject = yield sourceObject.clone(["id", "_isSlaveObject", "_isOrderedList", "_orderedListStart"]);
3522
+ const newId = this.randomId();
3523
+ clonedObject.set({
3524
+ id: newId,
3525
+ top: clonedObject.top + 20,
3526
+ evented: true
3527
+ });
3528
+ const newObjectData = new CanvasObjectData(ObjectType.TEXT, newId);
3529
+ newObjectData.bulleted = objectData.bulleted;
3530
+ newObjectData.columnWidthPercent = objectData.columnWidthPercent;
3531
+ newObjectData.margin = objectData.margin;
3532
+ this.fabricCanvas.add(clonedObject);
3533
+ const newTextObject = new Text(this, clonedObject, newObjectData);
3534
+ newTextObject.setCoords();
3535
+ this.trackNewObject(newTextObject);
3536
+ this.selectFabricObject(clonedObject);
3537
+ this.syncObjectList();
3538
+ }
3539
+ });
3540
+ }
3505
3541
  /**
3506
3542
  * Redraw the canvas.
3507
3543
  */
@@ -21,6 +21,7 @@ import { ObjectType } from "./types/object-type.enum";
21
21
  import { IRichText } from "./object/impl/rich-text";
22
22
  import { IBackgroundImage } from "./object/impl/background-image";
23
23
  import { FabricObject } from "fabric";
24
+ import { CanvasObjectData } from "./object/canvas-object-data";
24
25
  /**
25
26
  * New leapfrog canvas implementation c. 2019.
26
27
  */
@@ -314,4 +315,8 @@ export interface IInteractiveCanvas {
314
315
  * Revert the canvas state one entry.
315
316
  */
316
317
  redo(): Promise<void>;
318
+ /**
319
+ * Clone text box object to the canvas.
320
+ */
321
+ cloneObject(object: FabricObject, data: CanvasObjectData): Promise<void>;
317
322
  }
@@ -554,6 +554,38 @@ function isMutableText(object) {
554
554
  return "setText" in object;
555
555
  }
556
556
 
557
+ /******************************************************************************
558
+ Copyright (c) Microsoft Corporation.
559
+
560
+ Permission to use, copy, modify, and/or distribute this software for any
561
+ purpose with or without fee is hereby granted.
562
+
563
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
564
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
565
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
566
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
567
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
568
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
569
+ PERFORMANCE OF THIS SOFTWARE.
570
+ ***************************************************************************** */
571
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
572
+
573
+
574
+ function __awaiter(thisArg, _arguments, P, generator) {
575
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
576
+ return new (P || (P = Promise))(function (resolve, reject) {
577
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
578
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
579
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
580
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
581
+ });
582
+ }
583
+
584
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
585
+ var e = new Error(message);
586
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
587
+ };
588
+
557
589
  /**
558
590
  * Data for a persisted canvas object.
559
591
  */
@@ -786,6 +818,15 @@ class AbstractCanvasObject {
786
818
  this.canvas.removeObject(this);
787
819
  this.onDelete();
788
820
  }
821
+ /**
822
+ * @override
823
+ * @inheritDoc
824
+ */
825
+ clone() {
826
+ return __awaiter(this, void 0, void 0, function* () {
827
+ yield this.canvas.cloneObject(this.fabricObject, this.data);
828
+ });
829
+ }
789
830
  /**
790
831
  * @override
791
832
  * @inheritDoc
@@ -1041,38 +1082,6 @@ class FieldDimensions {
1041
1082
  }
1042
1083
  }
1043
1084
 
1044
- /******************************************************************************
1045
- Copyright (c) Microsoft Corporation.
1046
-
1047
- Permission to use, copy, modify, and/or distribute this software for any
1048
- purpose with or without fee is hereby granted.
1049
-
1050
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1051
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1052
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1053
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1054
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1055
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1056
- PERFORMANCE OF THIS SOFTWARE.
1057
- ***************************************************************************** */
1058
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1059
-
1060
-
1061
- function __awaiter(thisArg, _arguments, P, generator) {
1062
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1063
- return new (P || (P = Promise))(function (resolve, reject) {
1064
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1065
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1066
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1067
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1068
- });
1069
- }
1070
-
1071
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1072
- var e = new Error(message);
1073
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1074
- };
1075
-
1076
1085
  class BackgroundImage extends AbstractCanvasObject {
1077
1086
  constructor(canvas, fabricObject, persistedField) {
1078
1087
  super(exports.ObjectType.BACKGROUND_IMAGE, canvas, fabricObject, persistedField);
@@ -1798,7 +1807,7 @@ class Text extends AbstractCanvasObject {
1798
1807
  this.data.userText = this.fabricObject.text;
1799
1808
  this.textSelection$ = new rxjs.BehaviorSubject(new TextSelection(this.fabricObject, this.fontLibrary));
1800
1809
  this.fabricObject.set({ strokeWidth: 0 });
1801
- this.fabricObject.on("text:changed", () => this.onTextChange());
1810
+ this.fabricObject.on("changed", () => this.onTextChange());
1802
1811
  this.fabricObject.on("selection:changed", () => this.onSelectionChange());
1803
1812
  this.applyBulletListMonkeyPatches();
1804
1813
  }
@@ -2049,11 +2058,12 @@ class Text extends AbstractCanvasObject {
2049
2058
  */
2050
2059
  setFontSize(fontSize) {
2051
2060
  if (this.hasTextSelection()) {
2052
- this.fabricObject.setSelectionStyles({ fontSize });
2061
+ this.fabricObject.setSelectionStyles({ fontSize: fontSize });
2053
2062
  }
2054
2063
  else {
2055
2064
  this.fabricObject.set({ fontSize: fontSize });
2056
2065
  }
2066
+ this.fabricObject.dirty = true;
2057
2067
  this.redraw();
2058
2068
  this.updateTextSelection();
2059
2069
  }
@@ -2164,11 +2174,10 @@ class Text extends AbstractCanvasObject {
2164
2174
  if (!this.isOrderedList())
2165
2175
  return 0;
2166
2176
  const orderedListMarkerEntities = this.fabricObject._orderedListMarkerEntities;
2167
- let max = _(orderedListMarkerEntities)
2177
+ let maxValue = _.max((orderedListMarkerEntities !== null && orderedListMarkerEntities !== void 0 ? orderedListMarkerEntities : [])
2168
2178
  .filter((x) => !!x)
2169
- .map((x) => x.getBoundingRect().width)
2170
- .max();
2171
- return max ? (max * 1.2) : 0;
2179
+ .map((x) => x.getBoundingRect().width));
2180
+ return maxValue ? (maxValue * 1.2) : 0;
2172
2181
  }
2173
2182
  /**
2174
2183
  * @override
@@ -3523,6 +3532,33 @@ class AbstractInteractiveCanvas {
3523
3532
  redo() {
3524
3533
  throw new Error("Redo not supported on this canvas type");
3525
3534
  }
3535
+ /**
3536
+ * @override
3537
+ * @inheritDoc
3538
+ */
3539
+ cloneObject(sourceObject, objectData) {
3540
+ return __awaiter(this, void 0, void 0, function* () {
3541
+ if (sourceObject && (sourceObject.type === 'text' || sourceObject.type === 'textbox')) {
3542
+ const clonedObject = yield sourceObject.clone(["id", "_isSlaveObject", "_isOrderedList", "_orderedListStart"]);
3543
+ const newId = this.randomId();
3544
+ clonedObject.set({
3545
+ id: newId,
3546
+ top: clonedObject.top + 20,
3547
+ evented: true
3548
+ });
3549
+ const newObjectData = new CanvasObjectData(exports.ObjectType.TEXT, newId);
3550
+ newObjectData.bulleted = objectData.bulleted;
3551
+ newObjectData.columnWidthPercent = objectData.columnWidthPercent;
3552
+ newObjectData.margin = objectData.margin;
3553
+ this.fabricCanvas.add(clonedObject);
3554
+ const newTextObject = new Text(this, clonedObject, newObjectData);
3555
+ newTextObject.setCoords();
3556
+ this.trackNewObject(newTextObject);
3557
+ this.selectFabricObject(clonedObject);
3558
+ this.syncObjectList();
3559
+ }
3560
+ });
3561
+ }
3526
3562
  /**
3527
3563
  * Redraw the canvas.
3528
3564
  */
@@ -124,6 +124,11 @@ export declare abstract class AbstractCanvasObject<T extends FabricObject> imple
124
124
  * @inheritDoc
125
125
  */
126
126
  delete(): void;
127
+ /**
128
+ * @override
129
+ * @inheritDoc
130
+ */
131
+ clone(): Promise<void>;
127
132
  /**
128
133
  * @override
129
134
  * @inheritDoc
@@ -93,6 +93,10 @@ export interface ICanvasObject {
93
93
  * Delete this object, removing it from the canvas.
94
94
  */
95
95
  delete(): void;
96
+ /**
97
+ * Clone the text object, adding it to the canvas.
98
+ */
99
+ clone(): void;
96
100
  /**
97
101
  * Persist this object, returning a copy of the data block.
98
102
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leapfrog/interactive-canvas",
3
- "version": "2.0.21-beta-2",
3
+ "version": "2.0.21",
4
4
  "description": "Leapfrog interactive canvas",
5
5
  "files": [
6
6
  "dist"