@leapfrog/interactive-canvas 1.6.0 → 1.8.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.
@@ -21,6 +21,7 @@ import { ISelectionData } from "./types/selection-data.interface";
21
21
  import { ICanvasState } from "./types/canvas-state.interface";
22
22
  import { ITextSelection } from "./mutator/mutable-text-style.interface";
23
23
  import { fabric } from "fabric";
24
+ import { IRichText } from "./object/impl/rich-text";
24
25
  export declare abstract class AbstractInteractiveCanvas implements IInteractiveCanvas {
25
26
  fabric: any;
26
27
  protected readonly fabricCanvas: fabric.Canvas;
@@ -188,6 +189,11 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
188
189
  * @inheritDoc
189
190
  */
190
191
  addTextObject(): Promise<IText>;
192
+ /**
193
+ * @override
194
+ * @inheritDoc
195
+ */
196
+ addRichTextObject(imageUrl: string, htmlContent: string): Promise<IRichText>;
191
197
  /**
192
198
  * @override
193
199
  * @inheritDoc
@@ -276,7 +282,7 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
276
282
  * @override
277
283
  * @inheritDoc
278
284
  */
279
- toImage(): string;
285
+ toImage(multiplier?: number): string;
280
286
  /**
281
287
  * @override
282
288
  * @inheritDoc
@@ -391,7 +391,7 @@ var StackObjectsLayoutFunction = /** @class */ (function () {
391
391
  StackObjectsLayoutFunction.prototype.execute = function (canvas) {
392
392
  var canvasMargin = canvas.getMargin();
393
393
  var canvasDimensions = canvas.getDimensions();
394
- var allObjects = canvas.getObjectsByTypesInternal(ObjectType.TEXT, ObjectType.IMAGE, ObjectType.RECTANGLE, ObjectType.VERTICAL_RULE, ObjectType.HORIZONTAL_RULE);
394
+ var allObjects = canvas.getObjectsByTypesInternal(ObjectType.TEXT, ObjectType.RICH_TEXT, ObjectType.IMAGE, ObjectType.RECTANGLE, ObjectType.VERTICAL_RULE, ObjectType.HORIZONTAL_RULE);
395
395
  var objects = _(allObjects)
396
396
  .partition(function (object) { return object.isPinToBottom(); })
397
397
  .value();
@@ -2415,8 +2415,60 @@ var ObjectType;
2415
2415
  ObjectType["CUTOFF"] = "CUTOFF";
2416
2416
  ObjectType["VERTICAL_RULE"] = "VERTICAL_RULE";
2417
2417
  ObjectType["HORIZONTAL_RULE"] = "HORIZONTAL_RULE";
2418
+ ObjectType["RICH_TEXT"] = "RICH_TEXT";
2418
2419
  })(ObjectType || (ObjectType = {}));
2419
2420
 
2421
+ var RichText = /** @class */ (function (_super) {
2422
+ __extends(RichText, _super);
2423
+ function RichText(canvas, fabricObject, persistedField) {
2424
+ var _this = _super.call(this, canvas, fabricObject, persistedField) || this;
2425
+ _this.data.type = ObjectType.RICH_TEXT;
2426
+ return _this;
2427
+ }
2428
+ Object.defineProperty(RichText.prototype, "htmlContent", {
2429
+ /**
2430
+ * @override
2431
+ * @inheritDoc
2432
+ */
2433
+ get: function () {
2434
+ return this.data.userText;
2435
+ },
2436
+ /**
2437
+ * @override
2438
+ * @inheritDoc
2439
+ */
2440
+ set: function (text) {
2441
+ this.data.userText = text;
2442
+ },
2443
+ enumerable: false,
2444
+ configurable: true
2445
+ });
2446
+ /**
2447
+ * @override
2448
+ * @inheritDoc
2449
+ */
2450
+ RichText.prototype.setRichTextContent = function (renderedContentUrl, htmlContent) {
2451
+ return __awaiter(this, void 0, void 0, function () {
2452
+ var canvasWidthPx;
2453
+ return __generator(this, function (_a) {
2454
+ switch (_a.label) {
2455
+ case 0:
2456
+ canvasWidthPx = this.canvas.getDimensions().widthPx;
2457
+ if (!renderedContentUrl)
2458
+ return [2 /*return*/];
2459
+ this.htmlContent = htmlContent;
2460
+ return [4 /*yield*/, this.setImageUrl(renderedContentUrl)];
2461
+ case 1:
2462
+ _a.sent();
2463
+ this.setImageWidth(canvasWidthPx);
2464
+ return [2 /*return*/];
2465
+ }
2466
+ });
2467
+ });
2468
+ };
2469
+ return RichText;
2470
+ }(Image));
2471
+
2420
2472
  var AbstractInteractiveCanvas = /** @class */ (function () {
2421
2473
  function AbstractInteractiveCanvas(fabric, fabricCanvas, devicePixelRatio) {
2422
2474
  this.fabric = fabric;
@@ -2784,6 +2836,48 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
2784
2836
  });
2785
2837
  });
2786
2838
  };
2839
+ /**
2840
+ * @override
2841
+ * @inheritDoc
2842
+ */
2843
+ AbstractInteractiveCanvas.prototype.addRichTextObject = function (imageUrl, htmlContent) {
2844
+ return __awaiter(this, void 0, void 0, function () {
2845
+ var maxSizeScale, maxWidth, options;
2846
+ var _this = this;
2847
+ return __generator(this, function (_a) {
2848
+ switch (_a.label) {
2849
+ case 0:
2850
+ maxSizeScale = 2;
2851
+ maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
2852
+ options = { crossOrigin: "anonymous" };
2853
+ return [4 /*yield*/, new Promise(function (resolve) {
2854
+ _this.fabric.Image.fromURL(imageUrl, function (fabricImage) {
2855
+ var id = _this.randomId();
2856
+ var newScale = 1;
2857
+ var curWidth = newScale * fabricImage.width;
2858
+ if (curWidth > maxWidth) {
2859
+ newScale = maxWidth / curWidth;
2860
+ }
2861
+ fabricImage.set({
2862
+ id: id,
2863
+ scaleX: newScale,
2864
+ scaleY: newScale
2865
+ });
2866
+ _this.fabricCanvas.add(fabricImage);
2867
+ var object = new RichText(_this, fabricImage);
2868
+ object.htmlContent = htmlContent;
2869
+ _this.trackNewObject(object);
2870
+ object.setImageWidth(_this.dimensions$.value.widthPx);
2871
+ _this.selectFabricObject(fabricImage);
2872
+ _this.syncObjectList();
2873
+ resolve(object);
2874
+ }, options);
2875
+ })];
2876
+ case 1: return [2 /*return*/, _a.sent()];
2877
+ }
2878
+ });
2879
+ });
2880
+ };
2787
2881
  /**
2788
2882
  * @override
2789
2883
  * @inheritDoc
@@ -3093,11 +3187,11 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3093
3187
  * @override
3094
3188
  * @inheritDoc
3095
3189
  */
3096
- AbstractInteractiveCanvas.prototype.toImage = function () {
3190
+ AbstractInteractiveCanvas.prototype.toImage = function (multiplier) {
3097
3191
  var _this = this;
3098
3192
  var options = {
3099
3193
  format: "png",
3100
- multiplier: this.IMAGE_CAPTURE_COEFFICIENT,
3194
+ multiplier: multiplier || this.IMAGE_CAPTURE_COEFFICIENT,
3101
3195
  enableRetinaScaling: true
3102
3196
  };
3103
3197
  console.debug("Capturing canvas image", options);
@@ -3201,6 +3295,8 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3201
3295
  return new HorizontalRule(this, fabricObject, persistedField);
3202
3296
  case ObjectType.VERTICAL_RULE:
3203
3297
  return new VerticalRule(this, fabricObject, persistedField);
3298
+ case ObjectType.RICH_TEXT:
3299
+ return new RichText(this, fabricObject, persistedField);
3204
3300
  default:
3205
3301
  throw new Error("Unknown field type: [" + persistedField.type + "]");
3206
3302
  }
@@ -19,6 +19,7 @@ import { ICanvasState } from "./types/canvas-state.interface";
19
19
  import { AbstractCanvasObject } from "./object/abstract-canvas-object";
20
20
  import { ObjectType } from "./types/object-type.enum";
21
21
  import { fabric } from "fabric";
22
+ import { IRichText } from "./object/impl/rich-text";
22
23
  /**
23
24
  * New leapfrog canvas implementation c. 2019.
24
25
  */
@@ -146,6 +147,12 @@ export interface IInteractiveCanvas {
146
147
  * Add a text object to the canvas.
147
148
  */
148
149
  addTextObject(): Promise<IText>;
150
+ /**
151
+ * Add a rich text element to the canvas.
152
+ * @param imageUrl Url for text-rendered-as-image content.
153
+ * @param htmlContent Rich-text content as HTML.
154
+ */
155
+ addRichTextObject(imageUrl: string, htmlContent: string): Promise<IRichText>;
149
156
  /**
150
157
  * Add a rectangle object to the canvas.
151
158
  */
@@ -219,8 +226,9 @@ export interface IInteractiveCanvas {
219
226
  toSvg(): string;
220
227
  /**
221
228
  * Export the canvas to a DataUrl image.
229
+ * @param multiplier Multiply the image pixel density by this amount.
222
230
  */
223
- toImage(): string;
231
+ toImage(multiplier?: number): string;
224
232
  /**
225
233
  * Notify the canvas that the object list has changed.
226
234
  */
@@ -393,7 +393,7 @@ var StackObjectsLayoutFunction = /** @class */ (function () {
393
393
  StackObjectsLayoutFunction.prototype.execute = function (canvas) {
394
394
  var canvasMargin = canvas.getMargin();
395
395
  var canvasDimensions = canvas.getDimensions();
396
- var allObjects = canvas.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.IMAGE, exports.ObjectType.RECTANGLE, exports.ObjectType.VERTICAL_RULE, exports.ObjectType.HORIZONTAL_RULE);
396
+ var allObjects = canvas.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.RICH_TEXT, exports.ObjectType.IMAGE, exports.ObjectType.RECTANGLE, exports.ObjectType.VERTICAL_RULE, exports.ObjectType.HORIZONTAL_RULE);
397
397
  var objects = _(allObjects)
398
398
  .partition(function (object) { return object.isPinToBottom(); })
399
399
  .value();
@@ -2415,8 +2415,60 @@ var DefaultCanvasProfile = /** @class */ (function () {
2415
2415
  ObjectType["CUTOFF"] = "CUTOFF";
2416
2416
  ObjectType["VERTICAL_RULE"] = "VERTICAL_RULE";
2417
2417
  ObjectType["HORIZONTAL_RULE"] = "HORIZONTAL_RULE";
2418
+ ObjectType["RICH_TEXT"] = "RICH_TEXT";
2418
2419
  })(exports.ObjectType || (exports.ObjectType = {}));
2419
2420
 
2421
+ var RichText = /** @class */ (function (_super) {
2422
+ __extends(RichText, _super);
2423
+ function RichText(canvas, fabricObject, persistedField) {
2424
+ var _this = _super.call(this, canvas, fabricObject, persistedField) || this;
2425
+ _this.data.type = exports.ObjectType.RICH_TEXT;
2426
+ return _this;
2427
+ }
2428
+ Object.defineProperty(RichText.prototype, "htmlContent", {
2429
+ /**
2430
+ * @override
2431
+ * @inheritDoc
2432
+ */
2433
+ get: function () {
2434
+ return this.data.userText;
2435
+ },
2436
+ /**
2437
+ * @override
2438
+ * @inheritDoc
2439
+ */
2440
+ set: function (text) {
2441
+ this.data.userText = text;
2442
+ },
2443
+ enumerable: false,
2444
+ configurable: true
2445
+ });
2446
+ /**
2447
+ * @override
2448
+ * @inheritDoc
2449
+ */
2450
+ RichText.prototype.setRichTextContent = function (renderedContentUrl, htmlContent) {
2451
+ return __awaiter(this, void 0, void 0, function () {
2452
+ var canvasWidthPx;
2453
+ return __generator(this, function (_a) {
2454
+ switch (_a.label) {
2455
+ case 0:
2456
+ canvasWidthPx = this.canvas.getDimensions().widthPx;
2457
+ if (!renderedContentUrl)
2458
+ return [2 /*return*/];
2459
+ this.htmlContent = htmlContent;
2460
+ return [4 /*yield*/, this.setImageUrl(renderedContentUrl)];
2461
+ case 1:
2462
+ _a.sent();
2463
+ this.setImageWidth(canvasWidthPx);
2464
+ return [2 /*return*/];
2465
+ }
2466
+ });
2467
+ });
2468
+ };
2469
+ return RichText;
2470
+ }(Image));
2471
+
2420
2472
  var AbstractInteractiveCanvas = /** @class */ (function () {
2421
2473
  function AbstractInteractiveCanvas(fabric, fabricCanvas, devicePixelRatio) {
2422
2474
  this.fabric = fabric;
@@ -2784,6 +2836,48 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
2784
2836
  });
2785
2837
  });
2786
2838
  };
2839
+ /**
2840
+ * @override
2841
+ * @inheritDoc
2842
+ */
2843
+ AbstractInteractiveCanvas.prototype.addRichTextObject = function (imageUrl, htmlContent) {
2844
+ return __awaiter(this, void 0, void 0, function () {
2845
+ var maxSizeScale, maxWidth, options;
2846
+ var _this = this;
2847
+ return __generator(this, function (_a) {
2848
+ switch (_a.label) {
2849
+ case 0:
2850
+ maxSizeScale = 2;
2851
+ maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
2852
+ options = { crossOrigin: "anonymous" };
2853
+ return [4 /*yield*/, new Promise(function (resolve) {
2854
+ _this.fabric.Image.fromURL(imageUrl, function (fabricImage) {
2855
+ var id = _this.randomId();
2856
+ var newScale = 1;
2857
+ var curWidth = newScale * fabricImage.width;
2858
+ if (curWidth > maxWidth) {
2859
+ newScale = maxWidth / curWidth;
2860
+ }
2861
+ fabricImage.set({
2862
+ id: id,
2863
+ scaleX: newScale,
2864
+ scaleY: newScale
2865
+ });
2866
+ _this.fabricCanvas.add(fabricImage);
2867
+ var object = new RichText(_this, fabricImage);
2868
+ object.htmlContent = htmlContent;
2869
+ _this.trackNewObject(object);
2870
+ object.setImageWidth(_this.dimensions$.value.widthPx);
2871
+ _this.selectFabricObject(fabricImage);
2872
+ _this.syncObjectList();
2873
+ resolve(object);
2874
+ }, options);
2875
+ })];
2876
+ case 1: return [2 /*return*/, _a.sent()];
2877
+ }
2878
+ });
2879
+ });
2880
+ };
2787
2881
  /**
2788
2882
  * @override
2789
2883
  * @inheritDoc
@@ -3093,11 +3187,11 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3093
3187
  * @override
3094
3188
  * @inheritDoc
3095
3189
  */
3096
- AbstractInteractiveCanvas.prototype.toImage = function () {
3190
+ AbstractInteractiveCanvas.prototype.toImage = function (multiplier) {
3097
3191
  var _this = this;
3098
3192
  var options = {
3099
3193
  format: "png",
3100
- multiplier: this.IMAGE_CAPTURE_COEFFICIENT,
3194
+ multiplier: multiplier || this.IMAGE_CAPTURE_COEFFICIENT,
3101
3195
  enableRetinaScaling: true
3102
3196
  };
3103
3197
  console.debug("Capturing canvas image", options);
@@ -3201,6 +3295,8 @@ var AbstractInteractiveCanvas = /** @class */ (function () {
3201
3295
  return new HorizontalRule(this, fabricObject, persistedField);
3202
3296
  case exports.ObjectType.VERTICAL_RULE:
3203
3297
  return new VerticalRule(this, fabricObject, persistedField);
3298
+ case exports.ObjectType.RICH_TEXT:
3299
+ return new RichText(this, fabricObject, persistedField);
3204
3300
  default:
3205
3301
  throw new Error("Unknown field type: [" + persistedField.type + "]");
3206
3302
  }
@@ -0,0 +1,39 @@
1
+ import { CanvasObjectData, IInteractiveCanvas, Image, IMutableImage, IMutablePosition } from "../..";
2
+ import { ICanvasObject } from "../canvas-object.interface";
3
+ import { fabric } from "fabric";
4
+ /**
5
+ * Rich text field.
6
+ * Displays complex text by taking a rendered image of a html block of rich text and displays it on the canvas.
7
+ * The rendering of the text content to an image must be handled by the caller.
8
+ * This is an attempt to work around the poor rich-text support of fabric, which supports virtually no rich-text features on the canvas itself.
9
+ */
10
+ export interface IRichText extends ICanvasObject, IMutableImage, IMutablePosition {
11
+ /**
12
+ * HTML rich text content.
13
+ */
14
+ htmlContent: string;
15
+ /**
16
+ * Set the rich text content by providing the rendered image version of the content and the html content.
17
+ * @param renderedContentUrl Rendered version of the rich-text content.
18
+ * @param htmlContent Html version of the rich text content.
19
+ */
20
+ setRichTextContent(renderedContentUrl: string, htmlContent: string): Promise<void>;
21
+ }
22
+ export declare class RichText extends Image implements IRichText {
23
+ constructor(canvas: IInteractiveCanvas, fabricObject: fabric.Image, persistedField?: CanvasObjectData);
24
+ /**
25
+ * @override
26
+ * @inheritDoc
27
+ */
28
+ get htmlContent(): string;
29
+ /**
30
+ * @override
31
+ * @inheritDoc
32
+ */
33
+ set htmlContent(text: string);
34
+ /**
35
+ * @override
36
+ * @inheritDoc
37
+ */
38
+ setRichTextContent(renderedContentUrl: string, htmlContent: string): Promise<void>;
39
+ }
@@ -6,5 +6,6 @@ export declare enum ObjectType {
6
6
  LIBRARY_IMAGE = "LIBRARY_IMAGE",
7
7
  CUTOFF = "CUTOFF",
8
8
  VERTICAL_RULE = "VERTICAL_RULE",
9
- HORIZONTAL_RULE = "HORIZONTAL_RULE"
9
+ HORIZONTAL_RULE = "HORIZONTAL_RULE",
10
+ RICH_TEXT = "RICH_TEXT"
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leapfrog/interactive-canvas",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Leapfrog interactive canvas",
5
5
  "files": [
6
6
  "dist"