@leapfrog/interactive-canvas 1.0.2 → 1.0.4

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.
Files changed (58) hide show
  1. package/dist/abstract-interactive-canvas.d.ts +340 -0
  2. package/dist/dimensions/pixel-canvas-dimensions.d.ts +13 -0
  3. package/dist/dimensions/print-6-col-canvas-dimensions.d.ts +18 -0
  4. package/dist/dimensions/print-8-col-canvas-dimensions.d.ts +18 -0
  5. package/dist/font/font-library.d.ts +27 -0
  6. package/dist/font/font-library.interface.d.ts +24 -0
  7. package/dist/font/font.interface.d.ts +20 -0
  8. package/dist/font/unknown-font.d.ts +6 -0
  9. package/dist/headless-interactive-canvas.d.ts +9 -0
  10. package/dist/index.d.ts +49 -0
  11. package/dist/interactive-canvas.d.ts +8 -0
  12. package/dist/interactive-canvas.es.js +3225 -0
  13. package/dist/interactive-canvas.interface.d.ts +267 -0
  14. package/dist/interactive-canvas.js +3254 -0
  15. package/dist/layout/abstract-layout-manager.d.ts +17 -0
  16. package/dist/layout/advanced-layout-manager.d.ts +15 -0
  17. package/dist/layout/function/pin-to-bottom.layout-function.d.ts +4 -0
  18. package/dist/layout/function/redraw-all.layout-function.d.ts +4 -0
  19. package/dist/layout/function/reposition-borders.layout-function.d.ts +4 -0
  20. package/dist/layout/function/reposition-cutoffs.layout-function.d.ts +4 -0
  21. package/dist/layout/function/resize-canvas.layout-function.d.ts +4 -0
  22. package/dist/layout/function/stack-objects.layout-function.d.ts +11 -0
  23. package/dist/layout/function/update-object-dimensions.layout-function.d.ts +4 -0
  24. package/dist/layout/layout-manager.enum.d.ts +5 -0
  25. package/dist/layout/layout-manager.interface.d.ts +13 -0
  26. package/dist/layout/standard-layout-manager.d.ts +35 -0
  27. package/dist/mutator/mutable-background-color.interface.d.ts +15 -0
  28. package/dist/mutator/mutable-color.interface.d.ts +6 -0
  29. package/dist/mutator/mutable-image.interface.d.ts +28 -0
  30. package/dist/mutator/mutable-position.interface.d.ts +33 -0
  31. package/dist/mutator/mutable-text-style.interface.d.ts +163 -0
  32. package/dist/mutator/mutable-text.interface.d.ts +40 -0
  33. package/dist/object/abstract-canvas-object.d.ts +155 -0
  34. package/dist/object/canvas-object-data.d.ts +24 -0
  35. package/dist/object/canvas-object.interface.d.ts +96 -0
  36. package/dist/object/impl/border.d.ts +70 -0
  37. package/dist/object/impl/cutoff.d.ts +59 -0
  38. package/dist/object/impl/horizontal-rule.d.ts +88 -0
  39. package/dist/object/impl/image.d.ts +81 -0
  40. package/dist/object/impl/rectangle.d.ts +58 -0
  41. package/dist/object/impl/text.d.ts +264 -0
  42. package/dist/object/impl/vertical-rule.d.ts +88 -0
  43. package/dist/profile/canvas-profile.interface.d.ts +22 -0
  44. package/dist/profile/default-canvas-profile.d.ts +23 -0
  45. package/dist/types/canvas-dimension-restrictions.interface.d.ts +14 -0
  46. package/dist/types/canvas-dimensions.interface.d.ts +21 -0
  47. package/dist/types/canvas-state.interface.d.ts +11 -0
  48. package/dist/types/dimension-restrictions.interface.d.ts +6 -0
  49. package/dist/types/image-type.enum.d.ts +6 -0
  50. package/dist/types/margin.interface.d.ts +6 -0
  51. package/dist/types/object-dimensions.interface.d.ts +23 -0
  52. package/dist/types/object-type.enum.d.ts +10 -0
  53. package/dist/types/overflow.interface.d.ts +4 -0
  54. package/dist/types/position.interface.d.ts +6 -0
  55. package/dist/types/rect.interface.d.ts +6 -0
  56. package/dist/types/selection-data.interface.d.ts +19 -0
  57. package/dist/types/text-alignment.interface.d.ts +1 -0
  58. package/package.json +1 -1
@@ -0,0 +1,3254 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _ = require('lodash');
6
+ var tsOptchain = require('ts-optchain');
7
+ var rxjs = require('rxjs');
8
+ var fabric = require('fabric');
9
+
10
+ var PixelCanvasDimensions = /** @class */ (function () {
11
+ function PixelCanvasDimensions(width, height) {
12
+ this.widthUnit = "px";
13
+ this.heightUnit = "px";
14
+ this.width = width;
15
+ this.widthPx = width;
16
+ this.height = height;
17
+ this.heightPx = height;
18
+ }
19
+ PixelCanvasDimensions.prototype.withSize = function (width, height) {
20
+ return new PixelCanvasDimensions(width, height);
21
+ };
22
+ PixelCanvasDimensions.prototype.widthPxToMm = function (px) {
23
+ return void 0;
24
+ };
25
+ PixelCanvasDimensions.prototype.heightPxToMm = function (px) {
26
+ return void 0;
27
+ };
28
+ return PixelCanvasDimensions;
29
+ }());
30
+
31
+ var COLUMN_WIDTH_MM = 41;
32
+ var GUTTER_WIDTH_MM = 3;
33
+ var PIXELS_PER_MM = 3.937;
34
+ var Print6ColCanvasDimensions = /** @class */ (function () {
35
+ function Print6ColCanvasDimensions(width, height) {
36
+ this.widthUnit = "column(s)";
37
+ this.heightUnit = "cm";
38
+ this.width = width;
39
+ this.gutterCount = Math.max(0, width - 1);
40
+ this.gutterTotalMm = this.gutterCount * GUTTER_WIDTH_MM;
41
+ this.columnsTotalMm = width * COLUMN_WIDTH_MM;
42
+ this.widthMm = Math.max(0, this.columnsTotalMm + this.gutterTotalMm);
43
+ this.widthPx = _.round(this.widthMm * PIXELS_PER_MM);
44
+ this.height = height;
45
+ this.heightMm = Math.max(0, height * 10);
46
+ this.heightPx = _.round(this.heightMm * PIXELS_PER_MM);
47
+ }
48
+ Print6ColCanvasDimensions.prototype.withSize = function (width, height) {
49
+ return new Print6ColCanvasDimensions(width, height);
50
+ };
51
+ Print6ColCanvasDimensions.prototype.widthPxToMm = function (px) {
52
+ return px / PIXELS_PER_MM;
53
+ };
54
+ Print6ColCanvasDimensions.prototype.heightPxToMm = function (px) {
55
+ return px / PIXELS_PER_MM;
56
+ };
57
+ return Print6ColCanvasDimensions;
58
+ }());
59
+
60
+ var COLUMN_WIDTH_MM$1 = 30.8772;
61
+ var GUTTER_WIDTH_MM$1 = 2.1053;
62
+ var PIXELS_PER_MM$1 = 3.937;
63
+ var Print8ColCanvasDimensions = /** @class */ (function () {
64
+ function Print8ColCanvasDimensions(width, height) {
65
+ this.widthUnit = "column(s)";
66
+ this.heightUnit = "cm";
67
+ this.width = width;
68
+ this.gutterCount = Math.max(0, width - 1);
69
+ this.gutterTotalMm = this.gutterCount * GUTTER_WIDTH_MM$1;
70
+ this.columnsTotalMm = width * COLUMN_WIDTH_MM$1;
71
+ this.widthMm = Math.max(0, this.columnsTotalMm + this.gutterTotalMm);
72
+ this.widthPx = _.round(this.widthMm * PIXELS_PER_MM$1);
73
+ this.height = height;
74
+ this.heightMm = Math.max(0, height * 10);
75
+ this.heightPx = _.round(this.heightMm * PIXELS_PER_MM$1);
76
+ }
77
+ Print8ColCanvasDimensions.prototype.withSize = function (width, height) {
78
+ return new Print8ColCanvasDimensions(width, height);
79
+ };
80
+ Print8ColCanvasDimensions.prototype.widthPxToMm = function (px) {
81
+ return px / PIXELS_PER_MM$1;
82
+ };
83
+ Print8ColCanvasDimensions.prototype.heightPxToMm = function (px) {
84
+ return px / PIXELS_PER_MM$1;
85
+ };
86
+ return Print8ColCanvasDimensions;
87
+ }());
88
+
89
+ /*! *****************************************************************************
90
+ Copyright (c) Microsoft Corporation.
91
+
92
+ Permission to use, copy, modify, and/or distribute this software for any
93
+ purpose with or without fee is hereby granted.
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
96
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
97
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
98
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
99
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
100
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
101
+ PERFORMANCE OF THIS SOFTWARE.
102
+ ***************************************************************************** */
103
+ /* global Reflect, Promise */
104
+
105
+ var extendStatics = function(d, b) {
106
+ extendStatics = Object.setPrototypeOf ||
107
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
108
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
109
+ return extendStatics(d, b);
110
+ };
111
+
112
+ function __extends(d, b) {
113
+ extendStatics(d, b);
114
+ function __() { this.constructor = d; }
115
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
116
+ }
117
+
118
+ function __awaiter(thisArg, _arguments, P, generator) {
119
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
120
+ return new (P || (P = Promise))(function (resolve, reject) {
121
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
122
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
123
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
124
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
125
+ });
126
+ }
127
+
128
+ function __generator(thisArg, body) {
129
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
130
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
131
+ function verb(n) { return function (v) { return step([n, v]); }; }
132
+ function step(op) {
133
+ if (f) throw new TypeError("Generator is already executing.");
134
+ while (_) try {
135
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
136
+ if (y = 0, t) op = [op[0] & 2, t.value];
137
+ switch (op[0]) {
138
+ case 0: case 1: t = op; break;
139
+ case 4: _.label++; return { value: op[1], done: false };
140
+ case 5: _.label++; y = op[1]; op = [0]; continue;
141
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
142
+ default:
143
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
144
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
145
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
146
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
147
+ if (t[2]) _.ops.pop();
148
+ _.trys.pop(); continue;
149
+ }
150
+ op = body.call(thisArg, _);
151
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
152
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
153
+ }
154
+ }
155
+
156
+ function __spreadArrays() {
157
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
158
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
159
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
160
+ r[k] = a[j];
161
+ return r;
162
+ }
163
+
164
+ var Font = /** @class */ (function () {
165
+ function Font() {
166
+ }
167
+ /**
168
+ * @override
169
+ * @inheritDoc
170
+ */
171
+ Font.prototype.isBold = function (fontWeight) {
172
+ return fontWeight === this.boldWeight;
173
+ };
174
+ return Font;
175
+ }());
176
+
177
+ var UnknownFont = /** @class */ (function (_super) {
178
+ __extends(UnknownFont, _super);
179
+ function UnknownFont() {
180
+ var _this = _super !== null && _super.apply(this, arguments) || this;
181
+ _this.family = "_Unknown_";
182
+ _this.normalWeight = 400;
183
+ _this.boldWeight = 700;
184
+ return _this;
185
+ }
186
+ return UnknownFont;
187
+ }(Font));
188
+
189
+ var UNKNOWN_FONT = new UnknownFont();
190
+ var FontLibrary = /** @class */ (function () {
191
+ function FontLibrary() {
192
+ this._fonts = {};
193
+ }
194
+ /**
195
+ * @override
196
+ * @inheritDoc
197
+ */
198
+ FontLibrary.prototype.registerFont = function (font) {
199
+ this._fonts[font.family] = font;
200
+ };
201
+ /**
202
+ * @override
203
+ * @inheritDoc
204
+ */
205
+ FontLibrary.prototype.registerFonts = function (fonts) {
206
+ var _this = this;
207
+ _.each(fonts, function (font) { return _this._fonts[font.family] = font; });
208
+ };
209
+ /**
210
+ * @override
211
+ * @inheritDoc
212
+ */
213
+ FontLibrary.prototype.getFonts = function () {
214
+ return _.values(this._fonts);
215
+ };
216
+ /**
217
+ * @override
218
+ * @inheritDoc
219
+ */
220
+ FontLibrary.prototype.getFont = function (family) {
221
+ return this._fonts[family] || UNKNOWN_FONT;
222
+ };
223
+ return FontLibrary;
224
+ }());
225
+
226
+ var AbstractLayoutManager = /** @class */ (function () {
227
+ function AbstractLayoutManager(canvas) {
228
+ this.isEnforcedPositioning = false;
229
+ this.enterTextEditImmediatelyOnSelect = false;
230
+ this.canvas = canvas;
231
+ }
232
+ AbstractLayoutManager.prototype.getCanvas = function () {
233
+ return this.canvas;
234
+ };
235
+ AbstractLayoutManager.prototype.onInit = function () {
236
+ //noop
237
+ };
238
+ AbstractLayoutManager.prototype.onProfileChange = function (profile) {
239
+ //noop
240
+ };
241
+ AbstractLayoutManager.prototype.onCanvasDimensionsChange = function () {
242
+ //noop
243
+ };
244
+ AbstractLayoutManager.prototype.onTextChange = function () {
245
+ //noop
246
+ };
247
+ AbstractLayoutManager.prototype.onObjectListChange = function () {
248
+ //noop
249
+ };
250
+ AbstractLayoutManager.prototype.onMarginChange = function () {
251
+ //noop
252
+ };
253
+ return AbstractLayoutManager;
254
+ }());
255
+
256
+ var RedrawAllLayoutFunction = /** @class */ (function () {
257
+ function RedrawAllLayoutFunction() {
258
+ }
259
+ RedrawAllLayoutFunction.prototype.execute = function (canvas) {
260
+ canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
261
+ canvas.redraw();
262
+ };
263
+ return RedrawAllLayoutFunction;
264
+ }());
265
+
266
+ var RepositionCutoffsLayoutFunction = /** @class */ (function () {
267
+ function RepositionCutoffsLayoutFunction() {
268
+ }
269
+ RepositionCutoffsLayoutFunction.prototype.execute = function (canvas) {
270
+ canvas.getObjectsByTypeInternal(exports.ObjectType.CUTOFF)
271
+ .forEach(function (cutoff) { return cutoff.updatePosition(); });
272
+ };
273
+ return RepositionCutoffsLayoutFunction;
274
+ }());
275
+
276
+ var RepositionBordersLayoutFunction = /** @class */ (function () {
277
+ function RepositionBordersLayoutFunction() {
278
+ }
279
+ RepositionBordersLayoutFunction.prototype.execute = function (canvas) {
280
+ canvas.getObjectsByTypeInternal(exports.ObjectType.BORDER)
281
+ .forEach(function (border) { return border.updatePosition(); });
282
+ };
283
+ return RepositionBordersLayoutFunction;
284
+ }());
285
+
286
+ var PinToBottomLayoutFunction = /** @class */ (function () {
287
+ function PinToBottomLayoutFunction() {
288
+ }
289
+ PinToBottomLayoutFunction.prototype.execute = function (canvas) {
290
+ canvas.getObjectsInternal()
291
+ .forEach(function (object) { return object.moveToPinnedPosition(); });
292
+ };
293
+ return PinToBottomLayoutFunction;
294
+ }());
295
+
296
+ var ResizeCanvasLayoutFunction = /** @class */ (function () {
297
+ function ResizeCanvasLayoutFunction() {
298
+ }
299
+ ResizeCanvasLayoutFunction.prototype.execute = function (canvas) {
300
+ if (canvas.getLayoutManager().isEnforcedPositioning)
301
+ return;
302
+ var currentDimensions = canvas.getDimensions();
303
+ var baseDimensions = canvas.getBaseDimensions();
304
+ var textHeightIncreasePx = _(canvas.getObjectsByTypeInternal(exports.ObjectType.TEXT))
305
+ .filter(function (text) { return text.isResizeCanvas(); })
306
+ .reduce(function (x, text) { return x + text.getSizeIncreaseSinceCreation(); }, 0);
307
+ var increase = baseDimensions.withSize(currentDimensions.width, 0);
308
+ while (increase.heightPx < textHeightIncreasePx) {
309
+ increase = increase.withSize(increase.width, increase.height + 1);
310
+ }
311
+ var targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
312
+ if (currentDimensions.height !== targetHeight.height) {
313
+ canvas.setDimensions(targetHeight);
314
+ }
315
+ canvas.getObjectsInternal().forEach(function (object) { return object.setCoords(); });
316
+ canvas.redraw();
317
+ };
318
+ return ResizeCanvasLayoutFunction;
319
+ }());
320
+
321
+ (function (LayoutManager) {
322
+ LayoutManager["LEGACY"] = "LEGACY";
323
+ LayoutManager["STANDARD"] = "STANDARD";
324
+ LayoutManager["ADVANCED"] = "ADVANCED";
325
+ })(exports.LayoutManager || (exports.LayoutManager = {}));
326
+
327
+ var AdvancedLayoutManager = /** @class */ (function (_super) {
328
+ __extends(AdvancedLayoutManager, _super);
329
+ function AdvancedLayoutManager(canvas) {
330
+ var _this = _super.call(this, canvas) || this;
331
+ _this.key = exports.LayoutManager.ADVANCED;
332
+ _this.pinToBottom = new PinToBottomLayoutFunction();
333
+ _this.redrawAll = new RedrawAllLayoutFunction();
334
+ _this.repositionBorders = new RepositionBordersLayoutFunction();
335
+ _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
336
+ _this.resizeCanvas = new ResizeCanvasLayoutFunction();
337
+ return _this;
338
+ }
339
+ AdvancedLayoutManager.prototype.onCanvasDimensionsChange = function () {
340
+ this.pinToBottom.execute(this.canvas);
341
+ this.repositionCutoffs.execute(this.canvas);
342
+ this.repositionBorders.execute(this.canvas);
343
+ this.redrawAll.execute(this.canvas);
344
+ };
345
+ AdvancedLayoutManager.prototype.onTextChange = function () {
346
+ this.resizeCanvas.execute(this.canvas);
347
+ };
348
+ AdvancedLayoutManager.prototype.onObjectListChange = function () {
349
+ this.redrawAll.execute(this.canvas);
350
+ };
351
+ return AdvancedLayoutManager;
352
+ }(AbstractLayoutManager));
353
+
354
+ var UpdateObjectDimensionsLayoutFunction = /** @class */ (function () {
355
+ function UpdateObjectDimensionsLayoutFunction() {
356
+ }
357
+ UpdateObjectDimensionsLayoutFunction.prototype.execute = function (canvas) {
358
+ canvas.getObjectsInternal().forEach(function (object) { return object.updateDimensions(); });
359
+ };
360
+ return UpdateObjectDimensionsLayoutFunction;
361
+ }());
362
+
363
+ var MIN_MAGNITUDE = 1;
364
+ var BULLET_MARGIN = 15;
365
+ var StackObjectsLayoutFunction = /** @class */ (function () {
366
+ function StackObjectsLayoutFunction() {
367
+ }
368
+ StackObjectsLayoutFunction.prototype.execute = function (canvas) {
369
+ var canvasMargin = canvas.getMargin();
370
+ var canvasDimensions = canvas.getDimensions();
371
+ var allObjects = canvas.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.IMAGE, exports.ObjectType.RECTANGLE, exports.ObjectType.VERTICAL_RULE, exports.ObjectType.HORIZONTAL_RULE);
372
+ var objects = _(allObjects)
373
+ .partition(function (object) { return object.isPinToBottom(); })
374
+ .value();
375
+ var footerObjects = objects[0];
376
+ var bodyObjects = objects[1];
377
+ var bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
378
+ //Make one pass and set the widths of all elements. This will force objects with dynamic heights (like text) to take on their necessary height before trying to lay them out.
379
+ this.applyWidths(allObjects, bodyWidth);
380
+ var bodyRows = this.getRows(bodyObjects);
381
+ var footerRows = this.getRows(footerObjects);
382
+ var minimumHeight = canvasMargin.top + bodyRows.totalHeight + footerRows.totalHeight + canvasMargin.bottom;
383
+ this.adjustCanvasSize(canvas, minimumHeight);
384
+ this.layoutFooter(footerRows, canvas);
385
+ this.layoutBody(bodyRows, canvas, footerRows.totalHeight);
386
+ };
387
+ StackObjectsLayoutFunction.prototype.layoutFooter = function (footerRows, canvas) {
388
+ var canvasDimensions = canvas.getDimensions();
389
+ var canvasMargin = canvas.getMargin();
390
+ var layoutAreaWidth = canvasDimensions.widthPx - canvasMargin.left - canvasMargin.right;
391
+ var nextObjectTop = canvasDimensions.heightPx - canvasMargin.bottom - footerRows.totalHeight;
392
+ var currentColumnWidthPercent = 0;
393
+ _.each(footerRows.rows, function (row) {
394
+ _.each(row.objects, function (object) {
395
+ var columnOffset = currentColumnWidthPercent / 100 * layoutAreaWidth;
396
+ var objectMargin = tsOptchain.oc(object.getMargin()).left(0);
397
+ var left = canvasMargin.left + columnOffset + objectMargin;
398
+ if (object.getType() === exports.ObjectType.VERTICAL_RULE)
399
+ object.setPosition({ height: row.height });
400
+ object.setPosition({
401
+ top: nextObjectTop + tsOptchain.oc(object.getMargin()).top(0),
402
+ left: left
403
+ });
404
+ currentColumnWidthPercent += object.getColumnWidthPercent();
405
+ });
406
+ currentColumnWidthPercent = 0;
407
+ nextObjectTop += row.height;
408
+ });
409
+ };
410
+ StackObjectsLayoutFunction.prototype.layoutBody = function (bodyRows, canvas, footerHeight) {
411
+ var canvasDimensions = canvas.getDimensions();
412
+ var canvasMargin = canvas.getMargin();
413
+ var workableWidth = canvasDimensions.widthPx - canvasMargin.left - canvasMargin.right;
414
+ var workableHeight = canvasDimensions.heightPx - canvasMargin.top - canvasMargin.bottom - footerHeight;
415
+ var leftoverSpace = workableHeight - bodyRows.totalHeight;
416
+ var spacesRequired = this.countSpaces(bodyRows);
417
+ var spaceSize = leftoverSpace / spacesRequired;
418
+ var nextObjectTop = canvasMargin.top;
419
+ var currentColumnWidthPercent = 0;
420
+ for (var i = 0; i < bodyRows.rows.length; i++) {
421
+ var row = bodyRows.rows[i];
422
+ var nextRow = bodyRows.rows[i + 1];
423
+ for (var _i = 0, _a = row.objects; _i < _a.length; _i++) {
424
+ var object = _a[_i];
425
+ var columnOffset = currentColumnWidthPercent / 100 * workableWidth;
426
+ var objectMargin = tsOptchain.oc(object.getMargin()).left(0);
427
+ var objectLeft = canvasMargin.left + columnOffset + objectMargin;
428
+ if (object.getType() === exports.ObjectType.TEXT && object.isBulleted())
429
+ objectLeft += BULLET_MARGIN;
430
+ if (object.getType() === exports.ObjectType.VERTICAL_RULE)
431
+ object.setPosition({ height: row.height });
432
+ object.setPosition({
433
+ top: nextObjectTop + tsOptchain.oc(object.getMargin()).top(0),
434
+ left: objectLeft
435
+ });
436
+ currentColumnWidthPercent += object.getColumnWidthPercent();
437
+ }
438
+ currentColumnWidthPercent = 0;
439
+ nextObjectTop += row.height;
440
+ var thisRowIsHR = row.objects.length === 1 && row.objects[0].getType() === exports.ObjectType.HORIZONTAL_RULE;
441
+ var nextRowIsHR = tsOptchain.oc(nextRow).objects.length() === 1 && tsOptchain.oc(nextRow).objects()[0].getType() === exports.ObjectType.HORIZONTAL_RULE;
442
+ if (!thisRowIsHR && !nextRowIsHR) {
443
+ nextObjectTop += spaceSize;
444
+ }
445
+ }
446
+ };
447
+ StackObjectsLayoutFunction.prototype.applyWidths = function (objects, layoutWidth) {
448
+ _(objects).forEach(function (object) {
449
+ var targetWidth = object.getColumnWidthPercent() / 100 * layoutWidth;
450
+ var actualWidth = targetWidth - tsOptchain.oc(object.getMargin()).left(0) - tsOptchain.oc(object.getMargin()).right(0);
451
+ if (object.getType() === exports.ObjectType.VERTICAL_RULE)
452
+ return;
453
+ if (object.getType() === exports.ObjectType.TEXT && object.isBulleted())
454
+ actualWidth -= BULLET_MARGIN;
455
+ object.setPosition({
456
+ width: actualWidth
457
+ });
458
+ object.updateDimensions();
459
+ });
460
+ };
461
+ StackObjectsLayoutFunction.prototype.adjustCanvasSize = function (canvas, requiredHeight) {
462
+ var dimensions = canvas.getDimensions();
463
+ var targetDimensions = canvas.getDimensions().withSize(dimensions.width, MIN_MAGNITUDE);
464
+ while (targetDimensions.heightPx < requiredHeight) {
465
+ targetDimensions = targetDimensions.withSize(dimensions.width, targetDimensions.height + 1);
466
+ }
467
+ if (dimensions.height !== targetDimensions.height) {
468
+ canvas.setDimensions(targetDimensions);
469
+ }
470
+ };
471
+ StackObjectsLayoutFunction.prototype.getRows = function (objectsToLayout) {
472
+ var _this = this;
473
+ var result = { totalHeight: 0, rows: [] };
474
+ var currentWidth = 0;
475
+ var row = { objects: [], height: 1 };
476
+ _.each(objectsToLayout, function (object) {
477
+ var nextWidth = object.getColumnWidthPercent();
478
+ var objectHeight = _this.getObjectHeight(object);
479
+ if (currentWidth + nextWidth > 100) {
480
+ result.rows.push(row);
481
+ row = { objects: [], height: 1 };
482
+ currentWidth = 0;
483
+ }
484
+ row.objects.push(object);
485
+ if (object.getType() !== exports.ObjectType.VERTICAL_RULE)
486
+ row.height = Math.max(row.height, objectHeight);
487
+ currentWidth += nextWidth;
488
+ });
489
+ if (row.objects.length)
490
+ result.rows.push(row);
491
+ result.totalHeight = _.reduce(result.rows, function (x, y) { return x + y.height; }, 0);
492
+ return result;
493
+ };
494
+ StackObjectsLayoutFunction.prototype.getObjectHeight = function (element) {
495
+ return element.getBoundingBox().height
496
+ + tsOptchain.oc(element.getMargin()).top(0)
497
+ + tsOptchain.oc(element.getMargin()).bottom(0);
498
+ };
499
+ StackObjectsLayoutFunction.prototype.countSpaces = function (rows) {
500
+ var count = 0;
501
+ for (var i = 0; i < rows.rows.length - 1; i++) {
502
+ var row = rows.rows[i];
503
+ var nextRow = rows.rows[i + 1];
504
+ var thisRowIsHR = row.objects.length === 1 && row.objects[0].getType() === exports.ObjectType.HORIZONTAL_RULE;
505
+ var nextRowIsHR = tsOptchain.oc(nextRow).objects.length() === 1 && tsOptchain.oc(nextRow).objects()[0].getType() === exports.ObjectType.HORIZONTAL_RULE;
506
+ if (!thisRowIsHR && !nextRowIsHR) {
507
+ count++;
508
+ }
509
+ }
510
+ return count;
511
+ };
512
+ return StackObjectsLayoutFunction;
513
+ }());
514
+
515
+ var StandardLayoutManager = /** @class */ (function (_super) {
516
+ __extends(StandardLayoutManager, _super);
517
+ function StandardLayoutManager(canvas) {
518
+ var _this = _super.call(this, canvas) || this;
519
+ _this.key = exports.LayoutManager.STANDARD;
520
+ _this.isEnforcedPositioning = true;
521
+ _this.enterTextEditImmediatelyOnSelect = true;
522
+ _this.redrawAll = new RedrawAllLayoutFunction();
523
+ _this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
524
+ _this.repositionBorders = new RepositionBordersLayoutFunction();
525
+ _this.stackObjects = new StackObjectsLayoutFunction();
526
+ _this.updateObjectDimensions = new UpdateObjectDimensionsLayoutFunction();
527
+ return _this;
528
+ }
529
+ /**
530
+ * @override
531
+ */
532
+ StandardLayoutManager.prototype.onInit = function () {
533
+ this.stackAndRedraw();
534
+ };
535
+ /**
536
+ * @override
537
+ */
538
+ StandardLayoutManager.prototype.onProfileChange = function (profile) {
539
+ this.canvas.setMultiSelect(false);
540
+ this.redrawAll.execute(this.canvas);
541
+ };
542
+ /**
543
+ * @override
544
+ */
545
+ StandardLayoutManager.prototype.onTextChange = function () {
546
+ this.stackAndRedraw();
547
+ };
548
+ /**
549
+ * @override
550
+ */
551
+ StandardLayoutManager.prototype.onObjectListChange = function () {
552
+ this.stackAndRedraw();
553
+ };
554
+ /**
555
+ * @override
556
+ */
557
+ StandardLayoutManager.prototype.onMarginChange = function () {
558
+ this.stackAndRedraw();
559
+ };
560
+ StandardLayoutManager.prototype.stackAndRedraw = function () {
561
+ this.stackObjects.execute(this.canvas);
562
+ this.repositionCutoffs.execute(this.canvas);
563
+ this.repositionBorders.execute(this.canvas);
564
+ this.updateObjectDimensions.execute(this.canvas);
565
+ this.redrawAll.execute(this.canvas);
566
+ };
567
+ return StandardLayoutManager;
568
+ }(AbstractLayoutManager));
569
+
570
+ function isMutableBackgroundColor(object) {
571
+ return "setBackgroundColor" in object;
572
+ }
573
+
574
+ function isMutableColor(object) {
575
+ return "setColor" in object;
576
+ }
577
+
578
+ function isMutableImage(object) {
579
+ return "setImageUrl" in object;
580
+ }
581
+
582
+ function isMutablePosition(object) {
583
+ return "centerHorizontally" in object;
584
+ }
585
+
586
+ function isMutableText(object) {
587
+ return "setText" in object;
588
+ }
589
+
590
+ function isMutableTextStyle(object) {
591
+ return "getTextSelection" in object;
592
+ }
593
+
594
+ /**
595
+ * Data for a persisted canvas object.
596
+ */
597
+ var CanvasObjectData = /** @class */ (function () {
598
+ function CanvasObjectData(type, id) {
599
+ this.id = id;
600
+ this.type = type;
601
+ }
602
+ return CanvasObjectData;
603
+ }());
604
+
605
+ var ROTATION_SNAP_ANGLE = 45;
606
+ var AbstractCanvasObject = /** @class */ (function () {
607
+ /**
608
+ * Create a new instance.
609
+ * @param type Object type.
610
+ * @param canvas Interactive canvas that the field will be rendered on.
611
+ * @param fabricObject The fabric object to bind this field to.
612
+ * @param data Existing persisted field data to load from, if applicable.
613
+ */
614
+ function AbstractCanvasObject(type, canvas, fabricObject, data) {
615
+ var _this = this;
616
+ this.canvas = canvas;
617
+ this.fabricObject = fabricObject;
618
+ this.data = data ? data : new CanvasObjectData(type, this.fabricObject.id);
619
+ this.dimensions$ = new rxjs.BehaviorSubject(new FieldDimensions(this.fabricObject, this.canvas));
620
+ this.updatePinToBottomDistance();
621
+ this.canvas.getProfile$().subscribe(function (profile) { return _this.onProfileChange(profile); });
622
+ this.canvas.getLayoutManager$().subscribe(function (layoutManager) { return _this.onLayoutManagerChange(layoutManager); });
623
+ this.fabricObject.on("moving", function (e) { return _this.onMove(e); });
624
+ this.fabricObject.on("rotating", function (e) { return _this.onRotate(e); });
625
+ this.fabricObject.on("scaling", function (e) { return _this.onScale(e); });
626
+ }
627
+ /**
628
+ * @override
629
+ * @inheritDoc
630
+ */
631
+ AbstractCanvasObject.prototype.getId = function () {
632
+ return this.data.id;
633
+ };
634
+ /**
635
+ * @override
636
+ * @inheritDoc
637
+ */
638
+ AbstractCanvasObject.prototype.getType = function () {
639
+ return this.data.type;
640
+ };
641
+ /**
642
+ * @override
643
+ * @inheritDoc
644
+ */
645
+ AbstractCanvasObject.prototype.getDescription = function () {
646
+ switch (this.data.type) {
647
+ case exports.ObjectType.BORDER:
648
+ return "Border";
649
+ case exports.ObjectType.CUTOFF:
650
+ return "Bottom Border";
651
+ case exports.ObjectType.IMAGE:
652
+ return "Image";
653
+ case exports.ObjectType.LIBRARY_IMAGE:
654
+ return "Library Image";
655
+ case exports.ObjectType.RECTANGLE:
656
+ return "Rectangle";
657
+ case exports.ObjectType.TEXT:
658
+ return "Text";
659
+ default:
660
+ return "Field";
661
+ }
662
+ };
663
+ /**
664
+ * @override
665
+ * @inheritDoc
666
+ */
667
+ AbstractCanvasObject.prototype.setSortCaption = function (value) {
668
+ this.data.sortCaption = value;
669
+ };
670
+ /**
671
+ * @override
672
+ * @inheritDoc
673
+ */
674
+ AbstractCanvasObject.prototype.isSortCaption = function () {
675
+ return this.data.sortCaption;
676
+ };
677
+ /**
678
+ * @override
679
+ * @inheritDoc
680
+ */
681
+ AbstractCanvasObject.prototype.getDimensions = function () {
682
+ return this.dimensions$.value;
683
+ };
684
+ /**
685
+ * @override
686
+ * @inheritDoc
687
+ */
688
+ AbstractCanvasObject.prototype.getDimensions$ = function () {
689
+ return this.dimensions$;
690
+ };
691
+ /**
692
+ * @override
693
+ * @inheritDoc
694
+ */
695
+ AbstractCanvasObject.prototype.getMargin = function () {
696
+ return this.data.margin || {
697
+ top: 0,
698
+ right: 0,
699
+ bottom: 0,
700
+ left: 0
701
+ };
702
+ };
703
+ /**
704
+ * @override
705
+ * @inheritDoc
706
+ */
707
+ AbstractCanvasObject.prototype.setMargin = function (margin) {
708
+ if (!margin)
709
+ return;
710
+ var newMargin = tsOptchain.oc(this.data).margin({
711
+ top: 0,
712
+ right: 0,
713
+ bottom: 0,
714
+ left: 0
715
+ });
716
+ if (margin.top != undefined)
717
+ newMargin.top = margin.top || 0;
718
+ if (margin.right != undefined)
719
+ newMargin.right = margin.right || 0;
720
+ if (margin.bottom != undefined)
721
+ newMargin.bottom = margin.bottom || 0;
722
+ if (margin.left != undefined)
723
+ newMargin.left = margin.left || 0;
724
+ this.data.margin = newMargin;
725
+ this.canvas.notifyObjectListChanged();
726
+ };
727
+ /**
728
+ * @override
729
+ * @inheritDoc
730
+ */
731
+ AbstractCanvasObject.prototype.getColumnWidthPercent = function () {
732
+ return Math.max(Math.min(tsOptchain.oc(this.data).columnWidthPercent(100), 100), 0);
733
+ };
734
+ /**
735
+ * @override
736
+ * @inheritDoc
737
+ */
738
+ AbstractCanvasObject.prototype.setColumnWidthPercent = function (percent) {
739
+ this.data.columnWidthPercent = percent;
740
+ this.canvas.notifyObjectListChanged();
741
+ };
742
+ /**
743
+ * @override
744
+ * @inheritDoc
745
+ */
746
+ AbstractCanvasObject.prototype.bringForward = function () {
747
+ this.fabricObject.bringForward();
748
+ this.canvas.syncObjectList();
749
+ };
750
+ /**
751
+ * @override
752
+ * @inheritDoc
753
+ */
754
+ AbstractCanvasObject.prototype.bringToFront = function () {
755
+ this.fabricObject.bringToFront();
756
+ this.canvas.syncObjectList();
757
+ };
758
+ /**
759
+ * @override
760
+ * @inheritDoc
761
+ */
762
+ AbstractCanvasObject.prototype.sendBackward = function () {
763
+ this.fabricObject.sendBackwards();
764
+ this.canvas.syncObjectList();
765
+ };
766
+ /**
767
+ * @override
768
+ * @inheritDoc
769
+ */
770
+ AbstractCanvasObject.prototype.sendToBack = function () {
771
+ this.fabricObject.sendToBack();
772
+ this.canvas.syncObjectList();
773
+ };
774
+ /**
775
+ * @override
776
+ * @inheritDoc
777
+ */
778
+ AbstractCanvasObject.prototype.moveUp = function () {
779
+ this.sendBackward();
780
+ };
781
+ /**
782
+ * @override
783
+ * @inheritDoc
784
+ */
785
+ AbstractCanvasObject.prototype.moveDown = function () {
786
+ this.bringForward();
787
+ };
788
+ /**
789
+ * @override
790
+ * @inheritDoc
791
+ */
792
+ AbstractCanvasObject.prototype.delete = function () {
793
+ this.canvas.removeObject(this);
794
+ this.onDelete();
795
+ };
796
+ /**
797
+ * @override
798
+ * @inheritDoc
799
+ */
800
+ AbstractCanvasObject.prototype.persist = function () {
801
+ return _.clone(this.data);
802
+ };
803
+ /**
804
+ * @override
805
+ * @inheritDoc
806
+ */
807
+ AbstractCanvasObject.prototype.isPinToBottom = function () {
808
+ return this.data.pinToBottom;
809
+ };
810
+ /**
811
+ * @override
812
+ * @inheritDoc
813
+ */
814
+ AbstractCanvasObject.prototype.setPinToBottom = function (value) {
815
+ if (value === void 0) { value = true; }
816
+ this.updatePinToBottomDistance();
817
+ this.data.pinToBottom = value;
818
+ this.canvas.notifyObjectListChanged();
819
+ this.updateFabricObjectBehavior();
820
+ };
821
+ /**
822
+ * Get the underlying fabric object.
823
+ * (Internal use only, do not expose this outside the canvas module).
824
+ */
825
+ AbstractCanvasObject.prototype.getFabricObjectInternal = function () {
826
+ return this.fabricObject;
827
+ };
828
+ AbstractCanvasObject.prototype.setPosition = function (position) {
829
+ var scale = this.getDimensions().scale;
830
+ if (position.top != undefined)
831
+ this.fabricObject.set({ top: position.top });
832
+ if (position.left != undefined)
833
+ this.fabricObject.set({ left: position.left });
834
+ if (position.width != undefined)
835
+ this.fabricObject.set({ width: position.width / scale.x });
836
+ if (position.height != undefined)
837
+ this.fabricObject.set({ height: position.height / scale.y });
838
+ };
839
+ AbstractCanvasObject.prototype.setCoords = function () {
840
+ this.fabricObject.setCoords();
841
+ };
842
+ AbstractCanvasObject.prototype.updateDimensions = function () {
843
+ this.setCoords();
844
+ var dimensions = new FieldDimensions(this.fabricObject, this.canvas);
845
+ this.dimensions$.next(dimensions);
846
+ };
847
+ AbstractCanvasObject.prototype.getBoundingBox = function () {
848
+ var absolute = true;
849
+ var calculate = true;
850
+ return this.fabricObject.getBoundingRect(absolute, calculate);
851
+ };
852
+ AbstractCanvasObject.prototype.moveToPinnedPosition = function () {
853
+ if (this.data.pinToBottom) {
854
+ this.setPosition({
855
+ top: this.canvas.getDimensions().heightPx - this.pinToBottomDistance
856
+ });
857
+ }
858
+ };
859
+ AbstractCanvasObject.prototype.updatePinToBottomDistance = function () {
860
+ this.pinToBottomDistance = this.canvas.getDimensions().heightPx - this.getDimensions().top.px;
861
+ };
862
+ AbstractCanvasObject.prototype.redraw = function () {
863
+ this.canvas.redraw();
864
+ };
865
+ // noinspection JSUnusedLocalSymbols
866
+ AbstractCanvasObject.prototype.onProfileChange = function (profile) {
867
+ this.updateFabricObjectBehavior();
868
+ this.redraw();
869
+ };
870
+ // noinspection JSUnusedLocalSymbols
871
+ AbstractCanvasObject.prototype.onLayoutManagerChange = function (layoutManager) {
872
+ this.updateFabricObjectBehavior();
873
+ this.redraw();
874
+ };
875
+ // noinspection JSUnusedLocalSymbols
876
+ AbstractCanvasObject.prototype.onMove = function (event) {
877
+ if (!this.canvas.getProfile().allowObjectsToLeaveCanvas) {
878
+ this.preventLeavingCanvas();
879
+ }
880
+ this.updateDimensions();
881
+ };
882
+ AbstractCanvasObject.prototype.onRotate = function (event) {
883
+ if (event.e.shiftKey) {
884
+ this.fabricObject.set({ snapAngle: 0 });
885
+ }
886
+ else {
887
+ this.fabricObject.set({ snapAngle: ROTATION_SNAP_ANGLE });
888
+ }
889
+ this.updateDimensions();
890
+ };
891
+ // noinspection JSUnusedLocalSymbols
892
+ AbstractCanvasObject.prototype.onScale = function (event) {
893
+ this.updateDimensions();
894
+ };
895
+ AbstractCanvasObject.prototype.onDelete = function () {
896
+ //no-op
897
+ };
898
+ AbstractCanvasObject.prototype.preventLeavingCanvas = function () {
899
+ var overflow = this.getCanvasOverflow();
900
+ if (overflow.hasOverflow) {
901
+ var adjustX = overflow.left || -overflow.right;
902
+ var adjustY = overflow.top || -overflow.bottom;
903
+ this.fabricObject.set({
904
+ top: this.fabricObject.top + adjustY,
905
+ left: this.fabricObject.left + adjustX
906
+ });
907
+ this.redraw();
908
+ }
909
+ };
910
+ AbstractCanvasObject.prototype.getCanvasOverflow = function () {
911
+ var bound = this.getBoundingBox();
912
+ var canvasDimensions = this.canvas.getDimensions();
913
+ var top = Math.max(0, 0 - bound.top);
914
+ var right = Math.max(0, bound.left + bound.width - canvasDimensions.widthPx);
915
+ var bottom = Math.max(0, bound.top + bound.height - canvasDimensions.heightPx);
916
+ var left = Math.max(0, 0 - bound.left);
917
+ return {
918
+ top: top,
919
+ right: right,
920
+ bottom: bottom,
921
+ left: left,
922
+ hasOverflow: top > 0 || right > 0 || bottom > 0 || left > 0
923
+ };
924
+ };
925
+ AbstractCanvasObject.prototype.centerHorizontallyInternal = function () {
926
+ var canvasWidth = this.canvas.getDimensions().widthPx;
927
+ var objectWidth = this.getDimensions().width.px;
928
+ this.fabricObject.set({ left: ((canvasWidth - objectWidth) / 2) - 0.5 });
929
+ this.updateDimensions();
930
+ this.redraw();
931
+ };
932
+ AbstractCanvasObject.prototype.centerVerticallyInternal = function () {
933
+ var canvasHeight = this.canvas.getDimensions().heightPx;
934
+ var objectHeight = this.getDimensions().height.px;
935
+ this.fabricObject.set({ top: ((canvasHeight - objectHeight) / 2) - 0.5 });
936
+ this.redraw();
937
+ this.updateDimensions();
938
+ };
939
+ AbstractCanvasObject.prototype.nudgeInternal = function (x, y) {
940
+ if (x === void 0) { x = 0; }
941
+ if (y === void 0) { y = 0; }
942
+ this.fabricObject.set({
943
+ top: this.getDimensions().top.px + y,
944
+ left: this.getDimensions().left.px + x
945
+ });
946
+ this.redraw();
947
+ this.updateDimensions();
948
+ };
949
+ AbstractCanvasObject.prototype.updateFabricObjectBehavior = function () {
950
+ var allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
951
+ var profile = this.canvas.getProfile();
952
+ var options = {
953
+ allowMove: allowManualPositioning && profile.allowMove && !this.isPinToBottom(),
954
+ allowRotate: allowManualPositioning && profile.allowRotate && !this.isPinToBottom(),
955
+ allowScale: allowManualPositioning && profile.allowScale && !this.isPinToBottom()
956
+ };
957
+ this.fabricObject.set({
958
+ lockMovementX: !options.allowMove,
959
+ lockMovementY: !options.allowMove,
960
+ lockScalingX: !options.allowScale,
961
+ lockScalingY: !options.allowScale,
962
+ lockScalingFlip: true,
963
+ lockRotation: !options.allowRotate
964
+ });
965
+ this.fabricObject.setControlsVisibility({
966
+ tl: options.allowScale,
967
+ tr: options.allowScale,
968
+ br: options.allowScale,
969
+ bl: options.allowScale,
970
+ ml: options.allowScale,
971
+ mt: options.allowScale,
972
+ mr: options.allowScale,
973
+ mb: options.allowScale,
974
+ mtr: options.allowRotate
975
+ });
976
+ };
977
+ return AbstractCanvasObject;
978
+ }());
979
+ var FieldDimensions = /** @class */ (function () {
980
+ function FieldDimensions(fabricObject, canvas) {
981
+ var widthPxToMmFunction = canvas.getDimensions().widthPxToMm;
982
+ var heightPxToMmFunction = canvas.getDimensions().heightPxToMm;
983
+ this.top = { px: fabricObject.top, mm: heightPxToMmFunction(fabricObject.top) };
984
+ this.left = { px: fabricObject.left, mm: widthPxToMmFunction(fabricObject.left) };
985
+ var widthPx = fabricObject.width * fabricObject.scaleX;
986
+ var heightPx = fabricObject.height * fabricObject.scaleY;
987
+ this.width = { px: widthPx, mm: widthPxToMmFunction(widthPx) };
988
+ this.height = { px: heightPx, mm: heightPxToMmFunction(heightPx) };
989
+ this.scale = { x: fabricObject.scaleX, y: fabricObject.scaleY };
990
+ this.angle = fabricObject.angle;
991
+ }
992
+ return FieldDimensions;
993
+ }());
994
+
995
+ var Border = /** @class */ (function (_super) {
996
+ __extends(Border, _super);
997
+ function Border(canvas, fabricObject, persistedField) {
998
+ var _this = _super.call(this, exports.ObjectType.BORDER, canvas, fabricObject, persistedField) || this;
999
+ _this.strokeWidth$ = new rxjs.BehaviorSubject(0);
1000
+ _this.canvas = canvas;
1001
+ _this.strokeWidth$.next(_this.fabricObject.strokeWidth);
1002
+ _this.updatePosition();
1003
+ return _this;
1004
+ }
1005
+ /**
1006
+ * @override
1007
+ * @inheritDoc
1008
+ */
1009
+ Border.prototype.getColor = function () {
1010
+ return this.fabricObject.stroke;
1011
+ };
1012
+ /**
1013
+ * @override
1014
+ * @inheritDoc
1015
+ */
1016
+ Border.prototype.setColor = function (color) {
1017
+ this.fabricObject.set({ stroke: color });
1018
+ this.data.color = color;
1019
+ this.redraw();
1020
+ };
1021
+ /**
1022
+ * @override
1023
+ * @inheritDoc
1024
+ */
1025
+ Border.prototype.getStrokeWidth = function () {
1026
+ return this.fabricObject.strokeWidth;
1027
+ };
1028
+ /**
1029
+ * @override
1030
+ * @inheritDoc
1031
+ */
1032
+ Border.prototype.getStrokeWidth$ = function () {
1033
+ return this.strokeWidth$;
1034
+ };
1035
+ /**
1036
+ * @override
1037
+ * @inheritDoc
1038
+ */
1039
+ Border.prototype.setStrokeWidth = function (width) {
1040
+ this.strokeWidth$.next(width);
1041
+ this.data.strokeWidth = width;
1042
+ this.updatePosition();
1043
+ this.canvas.notifyMarginChanged();
1044
+ this.redraw();
1045
+ };
1046
+ Border.prototype.getPadding = function () {
1047
+ return this.data.padding || {
1048
+ top: 2,
1049
+ right: 2,
1050
+ bottom: 2,
1051
+ left: 2
1052
+ };
1053
+ };
1054
+ Border.prototype.setPadding = function (padding) {
1055
+ if (!padding)
1056
+ return;
1057
+ this.data.padding = {
1058
+ top: padding.top || 2,
1059
+ right: padding.right || 2,
1060
+ bottom: padding.bottom || 2,
1061
+ left: padding.left || 2
1062
+ };
1063
+ this.canvas.notifyMarginChanged();
1064
+ this.redraw();
1065
+ };
1066
+ Border.prototype.updatePosition = function () {
1067
+ this.fabricObject.set({
1068
+ strokeWidth: this.strokeWidth$.value,
1069
+ top: 0,
1070
+ left: 0,
1071
+ width: this.canvas.getDimensions().widthPx - this.strokeWidth$.value,
1072
+ height: this.canvas.getDimensions().heightPx - this.strokeWidth$.value
1073
+ });
1074
+ };
1075
+ /**
1076
+ * @override
1077
+ * @inheritDoc
1078
+ */
1079
+ Border.prototype.updateFabricObjectBehavior = function () {
1080
+ _super.prototype.updateFabricObjectBehavior.call(this);
1081
+ this.fabricObject.set({
1082
+ lockMovementX: true,
1083
+ lockMovementY: true,
1084
+ lockScalingX: true,
1085
+ lockScalingY: true,
1086
+ lockScalingFlip: true
1087
+ });
1088
+ this.fabricObject.setControlsVisibility({
1089
+ tl: false,
1090
+ tr: false,
1091
+ br: false,
1092
+ bl: false,
1093
+ ml: false,
1094
+ mt: false,
1095
+ mr: false,
1096
+ mb: false,
1097
+ mtr: false
1098
+ });
1099
+ this.redraw();
1100
+ };
1101
+ return Border;
1102
+ }(AbstractCanvasObject));
1103
+
1104
+ var Cutoff = /** @class */ (function (_super) {
1105
+ __extends(Cutoff, _super);
1106
+ function Cutoff(canvas, fabricObject, persistedField) {
1107
+ var _this = _super.call(this, exports.ObjectType.CUTOFF, canvas, fabricObject, persistedField) || this;
1108
+ _this.strokeWidth$ = new rxjs.BehaviorSubject(0);
1109
+ _this.canvas = canvas;
1110
+ _this.strokeWidth$.next(_this.fabricObject.height);
1111
+ _this.updatePosition();
1112
+ _this.fabricObject.set({ strokeWidth: 0 });
1113
+ return _this;
1114
+ }
1115
+ /**
1116
+ * @override
1117
+ * @inheritDoc
1118
+ */
1119
+ Cutoff.prototype.getColor = function () {
1120
+ return this.fabricObject.fill;
1121
+ };
1122
+ /**
1123
+ * @override
1124
+ * @inheritDoc
1125
+ */
1126
+ Cutoff.prototype.setColor = function (color) {
1127
+ this.fabricObject.set({ fill: color, stroke: color });
1128
+ this.data.color = color;
1129
+ this.redraw();
1130
+ };
1131
+ /**
1132
+ * @override
1133
+ * @inheritDoc
1134
+ */
1135
+ Cutoff.prototype.getStrokeWidth = function () {
1136
+ // noinspection JSSuspiciousNameCombination
1137
+ return this.fabricObject.height;
1138
+ };
1139
+ /**
1140
+ * @override
1141
+ * @inheritDoc
1142
+ */
1143
+ Cutoff.prototype.getStrokeWidth$ = function () {
1144
+ return this.strokeWidth$;
1145
+ };
1146
+ /**
1147
+ * @override
1148
+ * @inheritDoc
1149
+ */
1150
+ Cutoff.prototype.setStrokeWidth = function (width) {
1151
+ this.strokeWidth$.next(width);
1152
+ this.data.strokeWidth = width;
1153
+ this.updatePosition();
1154
+ this.canvas.notifyMarginChanged();
1155
+ this.redraw();
1156
+ };
1157
+ Cutoff.prototype.updatePosition = function () {
1158
+ this.fabricObject.set({
1159
+ top: this.canvas.getDimensions().heightPx - this.strokeWidth$.value,
1160
+ left: 0,
1161
+ width: this.canvas.getDimensions().widthPx,
1162
+ height: this.strokeWidth$.value
1163
+ });
1164
+ };
1165
+ /**
1166
+ * @override
1167
+ * @inheritDoc
1168
+ */
1169
+ Cutoff.prototype.updateFabricObjectBehavior = function () {
1170
+ this.fabricObject.set({
1171
+ lockMovementX: true,
1172
+ lockMovementY: true,
1173
+ lockScalingX: true,
1174
+ lockScalingY: true,
1175
+ lockScalingFlip: true
1176
+ });
1177
+ this.fabricObject.setControlsVisibility({
1178
+ tl: false,
1179
+ tr: false,
1180
+ br: false,
1181
+ bl: false,
1182
+ ml: false,
1183
+ mt: false,
1184
+ mr: false,
1185
+ mb: false,
1186
+ mtr: false
1187
+ });
1188
+ this.redraw();
1189
+ };
1190
+ return Cutoff;
1191
+ }(AbstractCanvasObject));
1192
+
1193
+ var HorizontalRule = /** @class */ (function (_super) {
1194
+ __extends(HorizontalRule, _super);
1195
+ function HorizontalRule(canvas, fabricObject, persistedField) {
1196
+ var _this = _super.call(this, exports.ObjectType.HORIZONTAL_RULE, canvas, fabricObject, persistedField) || this;
1197
+ _this.strokeWidth$ = new rxjs.BehaviorSubject(2);
1198
+ _this.canvas = canvas;
1199
+ _this.strokeWidth$.next(_this.getDimensions().height.px);
1200
+ _this.fabricObject.set({ strokeWidth: 0 });
1201
+ return _this;
1202
+ }
1203
+ /**
1204
+ * @override
1205
+ * @inheritDoc
1206
+ */
1207
+ HorizontalRule.prototype.getStrokeWidth = function () {
1208
+ // noinspection JSSuspiciousNameCombination
1209
+ return this.fabricObject.height;
1210
+ };
1211
+ /**
1212
+ * @override
1213
+ * @inheritDoc
1214
+ */
1215
+ HorizontalRule.prototype.getStrokeWidth$ = function () {
1216
+ return this.strokeWidth$;
1217
+ };
1218
+ /**
1219
+ * @override
1220
+ * @inheritDoc
1221
+ */
1222
+ HorizontalRule.prototype.setStrokeWidth = function (value) {
1223
+ this.strokeWidth$.next(value);
1224
+ this.data.strokeWidth = value;
1225
+ this.setPosition({ height: value });
1226
+ this.canvas.notifyObjectListChanged();
1227
+ this.redraw();
1228
+ };
1229
+ /**
1230
+ * @override
1231
+ * @inheritDoc
1232
+ */
1233
+ HorizontalRule.prototype.getColor = function () {
1234
+ return this.fabricObject.fill;
1235
+ };
1236
+ /**
1237
+ * @override
1238
+ * @inheritDoc
1239
+ */
1240
+ HorizontalRule.prototype.setColor = function (color) {
1241
+ this.fabricObject.set({ fill: color, stroke: color });
1242
+ this.data.color = color;
1243
+ this.redraw();
1244
+ };
1245
+ /**
1246
+ * @override
1247
+ * @inheritDoc
1248
+ */
1249
+ HorizontalRule.prototype.centerHorizontally = function () {
1250
+ _super.prototype.centerHorizontallyInternal.call(this);
1251
+ };
1252
+ /**
1253
+ * @override
1254
+ * @inheritDoc
1255
+ */
1256
+ HorizontalRule.prototype.centerVertically = function () {
1257
+ _super.prototype.centerVerticallyInternal.call(this);
1258
+ };
1259
+ /**
1260
+ * @override
1261
+ * @inheritDoc
1262
+ */
1263
+ HorizontalRule.prototype.setHeight = function (height) {
1264
+ this.setPosition({ height: height });
1265
+ this.canvas.notifyObjectListChanged();
1266
+ };
1267
+ /**
1268
+ * @override
1269
+ * @inheritDoc
1270
+ */
1271
+ HorizontalRule.prototype.nudgeUp = function () {
1272
+ _super.prototype.nudgeInternal.call(this, 0, -1);
1273
+ };
1274
+ /**
1275
+ * @override
1276
+ * @inheritDoc
1277
+ */
1278
+ HorizontalRule.prototype.nudgeDown = function () {
1279
+ _super.prototype.nudgeInternal.call(this, 0, +1);
1280
+ };
1281
+ /**
1282
+ * @override
1283
+ * @inheritDoc
1284
+ */
1285
+ HorizontalRule.prototype.nudgeLeft = function () {
1286
+ _super.prototype.nudgeInternal.call(this, -1, 0);
1287
+ };
1288
+ /**
1289
+ * @override
1290
+ * @inheritDoc
1291
+ */
1292
+ HorizontalRule.prototype.nudgeRight = function () {
1293
+ _super.prototype.nudgeInternal.call(this, +1, 0);
1294
+ };
1295
+ return HorizontalRule;
1296
+ }(AbstractCanvasObject));
1297
+
1298
+ var Image = /** @class */ (function (_super) {
1299
+ __extends(Image, _super);
1300
+ function Image(canvas, fabricObject, persistedField) {
1301
+ var _this = _super.call(this, exports.ObjectType.IMAGE, canvas, fabricObject, persistedField) || this;
1302
+ _this.DEFAULT_RESTRICTIONS = {
1303
+ minWidth: 1,
1304
+ minHeight: 1
1305
+ };
1306
+ _this.canvas = canvas;
1307
+ _this.imageUrl$ = new rxjs.BehaviorSubject(_this.fabricObject.getSrc());
1308
+ _this.data.imagePath = _this.imageUrl$.value;
1309
+ _this.layoutWidth = _this.getBoundingBox().width;
1310
+ return _this;
1311
+ }
1312
+ /**
1313
+ * @override
1314
+ * @inheritDoc
1315
+ */
1316
+ Image.prototype.getImageUrl = function () {
1317
+ return this.imageUrl$.value;
1318
+ };
1319
+ /**
1320
+ * @override
1321
+ * @inheritDoc
1322
+ */
1323
+ Image.prototype.getImageUrl$ = function () {
1324
+ return this.imageUrl$;
1325
+ };
1326
+ /**
1327
+ * @override
1328
+ * @inheritDoc
1329
+ */
1330
+ Image.prototype.setImageUrl = function (url) {
1331
+ this.setCanvasImage(url);
1332
+ this.data.imagePath = url;
1333
+ this.imageUrl$.next(url);
1334
+ this.canvas.notifyObjectListChanged();
1335
+ };
1336
+ /**
1337
+ * @override
1338
+ * @inheritDoc
1339
+ */
1340
+ Image.prototype.setImageWidth = function (px, sizeRestrictions) {
1341
+ if (sizeRestrictions === void 0) { sizeRestrictions = this.DEFAULT_RESTRICTIONS; }
1342
+ var minWidth = Math.max(sizeRestrictions.minWidth, this.getMinWidthBasedOnMinHeight(sizeRestrictions.minHeight));
1343
+ var maxWidth = Math.min(sizeRestrictions.maxWidth, this.getMaxWidthBasedOnMaxHeight(sizeRestrictions.maxHeight));
1344
+ if (px < minWidth) {
1345
+ px = minWidth;
1346
+ }
1347
+ else if (px > maxWidth) {
1348
+ px = maxWidth;
1349
+ }
1350
+ var premultipliedWidth = this.fabricObject.width;
1351
+ var newScale = px / premultipliedWidth;
1352
+ this.fabricObject.set({ scaleX: newScale, scaleY: newScale });
1353
+ this.setCoords();
1354
+ this.canvas.notifyObjectListChanged();
1355
+ return px;
1356
+ };
1357
+ /**
1358
+ * @override
1359
+ * @inheritDoc
1360
+ */
1361
+ Image.prototype.centerHorizontally = function () {
1362
+ _super.prototype.centerHorizontallyInternal.call(this);
1363
+ };
1364
+ /**
1365
+ * @override
1366
+ * @inheritDoc
1367
+ */
1368
+ Image.prototype.centerVertically = function () {
1369
+ _super.prototype.centerVerticallyInternal.call(this);
1370
+ };
1371
+ /**
1372
+ * @override
1373
+ * @inheritDoc
1374
+ */
1375
+ Image.prototype.setHeight = function (height) {
1376
+ this.setPosition({ height: height });
1377
+ this.canvas.notifyObjectListChanged();
1378
+ };
1379
+ /**
1380
+ * @override
1381
+ * @inheritDoc
1382
+ */
1383
+ Image.prototype.nudgeUp = function () {
1384
+ _super.prototype.nudgeInternal.call(this, 0, -1);
1385
+ };
1386
+ /**
1387
+ * @override
1388
+ * @inheritDoc
1389
+ */
1390
+ Image.prototype.nudgeDown = function () {
1391
+ _super.prototype.nudgeInternal.call(this, 0, +1);
1392
+ };
1393
+ /**
1394
+ * @override
1395
+ * @inheritDoc
1396
+ */
1397
+ Image.prototype.nudgeLeft = function () {
1398
+ _super.prototype.nudgeInternal.call(this, -1, 0);
1399
+ };
1400
+ /**
1401
+ * @override
1402
+ * @inheritDoc
1403
+ */
1404
+ Image.prototype.nudgeRight = function () {
1405
+ _super.prototype.nudgeInternal.call(this, +1, 0);
1406
+ };
1407
+ /**
1408
+ * @override
1409
+ * @inheritDoc
1410
+ */
1411
+ Image.prototype.setPosition = function (position) {
1412
+ if (this.canvas.getLayoutManager().isEnforcedPositioning) {
1413
+ if (position.top != undefined)
1414
+ this.fabricObject.set({ top: position.top });
1415
+ if (position.width != undefined) {
1416
+ this.layoutWidth = position.width;
1417
+ }
1418
+ if (position.height != undefined) {
1419
+ var premultipliedHeight = this.fabricObject.height;
1420
+ var newScale = position.height / premultipliedHeight;
1421
+ this.fabricObject.set({ scaleX: newScale, scaleY: newScale });
1422
+ this.setCoords();
1423
+ }
1424
+ if (position.left != undefined || position.width != undefined || position.height != undefined) {
1425
+ this.centerHorizontallyInLayoutWidth(position.left || 0);
1426
+ }
1427
+ }
1428
+ else {
1429
+ _super.prototype.setPosition.call(this, position);
1430
+ }
1431
+ };
1432
+ Image.prototype.centerHorizontallyInLayoutWidth = function (left) {
1433
+ var imageWidth = this.getBoundingBox().width;
1434
+ this.fabricObject.set({ left: left + (this.layoutWidth / 2) - (imageWidth / 2) });
1435
+ };
1436
+ Image.prototype.setCanvasImage = function (url) {
1437
+ var _this = this;
1438
+ var imageOptions = { crossOrigin: "anonymous" };
1439
+ //Don't let the image be more than half the canvas in size.
1440
+ var maxSizeScale = 2;
1441
+ var maxWidth = this.canvas.getDimensions().widthPx / maxSizeScale;
1442
+ this.fabricObject.setSrc(url, function (img) {
1443
+ var newScale = 1;
1444
+ var curWidth = newScale * img.width;
1445
+ if (curWidth > maxWidth) {
1446
+ newScale = maxWidth / curWidth;
1447
+ }
1448
+ img.set({
1449
+ scaleX: newScale,
1450
+ scaleY: newScale
1451
+ });
1452
+ img.setCoords();
1453
+ _this.redraw();
1454
+ }, imageOptions);
1455
+ };
1456
+ Image.prototype.getMinWidthBasedOnMinHeight = function (minHeight) {
1457
+ if (!minHeight) {
1458
+ return 0;
1459
+ }
1460
+ var premultipliedHeight = this.fabricObject.height;
1461
+ var newScale = minHeight / premultipliedHeight;
1462
+ return this.getBoundingBox().width * newScale;
1463
+ };
1464
+ Image.prototype.getMaxWidthBasedOnMaxHeight = function (maxHeight) {
1465
+ if (!maxHeight) {
1466
+ return Infinity;
1467
+ }
1468
+ var premultipliedHeight = this.fabricObject.height;
1469
+ var newScale = maxHeight / premultipliedHeight;
1470
+ return this.getBoundingBox().width * newScale;
1471
+ };
1472
+ return Image;
1473
+ }(AbstractCanvasObject));
1474
+
1475
+ var Rectangle = /** @class */ (function (_super) {
1476
+ __extends(Rectangle, _super);
1477
+ function Rectangle(canvas, fabricObject, persistedField) {
1478
+ var _this = _super.call(this, exports.ObjectType.RECTANGLE, canvas, fabricObject, persistedField) || this;
1479
+ _this.canvas = canvas;
1480
+ _this.fabricObject.set({ strokeWidth: 0 });
1481
+ return _this;
1482
+ }
1483
+ /**
1484
+ * @override
1485
+ * @inheritDoc
1486
+ */
1487
+ Rectangle.prototype.getColor = function () {
1488
+ return this.fabricObject.fill;
1489
+ };
1490
+ /**
1491
+ * @override
1492
+ * @inheritDoc
1493
+ */
1494
+ Rectangle.prototype.setColor = function (color) {
1495
+ this.fabricObject.set({ fill: color, stroke: color });
1496
+ this.data.color = color;
1497
+ this.redraw();
1498
+ };
1499
+ /**
1500
+ * @override
1501
+ * @inheritDoc
1502
+ */
1503
+ Rectangle.prototype.centerHorizontally = function () {
1504
+ _super.prototype.centerHorizontallyInternal.call(this);
1505
+ };
1506
+ /**
1507
+ * @override
1508
+ * @inheritDoc
1509
+ */
1510
+ Rectangle.prototype.centerVertically = function () {
1511
+ _super.prototype.centerVerticallyInternal.call(this);
1512
+ };
1513
+ /**
1514
+ * @override
1515
+ * @inheritDoc
1516
+ */
1517
+ Rectangle.prototype.setHeight = function (height) {
1518
+ this.setPosition({ height: height });
1519
+ this.canvas.notifyObjectListChanged();
1520
+ };
1521
+ /**
1522
+ * @override
1523
+ * @inheritDoc
1524
+ */
1525
+ Rectangle.prototype.nudgeUp = function () {
1526
+ _super.prototype.nudgeInternal.call(this, 0, -1);
1527
+ };
1528
+ /**
1529
+ * @override
1530
+ * @inheritDoc
1531
+ */
1532
+ Rectangle.prototype.nudgeDown = function () {
1533
+ _super.prototype.nudgeInternal.call(this, 0, +1);
1534
+ };
1535
+ /**
1536
+ * @override
1537
+ * @inheritDoc
1538
+ */
1539
+ Rectangle.prototype.nudgeLeft = function () {
1540
+ _super.prototype.nudgeInternal.call(this, -1, 0);
1541
+ };
1542
+ /**
1543
+ * @override
1544
+ * @inheritDoc
1545
+ */
1546
+ Rectangle.prototype.nudgeRight = function () {
1547
+ _super.prototype.nudgeInternal.call(this, +1, 0);
1548
+ };
1549
+ return Rectangle;
1550
+ }(AbstractCanvasObject));
1551
+
1552
+ var Text = /** @class */ (function (_super) {
1553
+ __extends(Text, _super);
1554
+ function Text(canvas, fabricObject, persistedField) {
1555
+ var _this = _super.call(this, exports.ObjectType.TEXT, canvas, fabricObject, persistedField) || this;
1556
+ _this.canvas = canvas;
1557
+ _this.fontLibrary = canvas.getFontLibrary();
1558
+ _this.baseComponentHeight = _this.fabricObject.height;
1559
+ _this.text$ = new rxjs.BehaviorSubject(_this.fabricObject.text);
1560
+ _this.data.userText = _this.fabricObject.text;
1561
+ _this.textSelection$ = new rxjs.BehaviorSubject(new TextSelection(_this.fabricObject, _this.fontLibrary));
1562
+ _this.fabricObject.set({ strokeWidth: 0 });
1563
+ _this.fabricObject.on("changed", function () { return _this.onTextChange(); });
1564
+ _this.fabricObject.on("selection:changed", function () { return _this.onSelectionChange(); });
1565
+ _this.applyBulletListMonkeyPatches();
1566
+ return _this;
1567
+ }
1568
+ /**
1569
+ * @override
1570
+ * @inheritDoc
1571
+ */
1572
+ Text.prototype.getText = function () {
1573
+ return this.text$.value;
1574
+ };
1575
+ /**
1576
+ * @override
1577
+ * @inheritDoc
1578
+ */
1579
+ Text.prototype.getText$ = function () {
1580
+ return this.text$;
1581
+ };
1582
+ /**
1583
+ * @override
1584
+ * @inheritDoc
1585
+ */
1586
+ Text.prototype.setText = function (text) {
1587
+ var style = this.fabricObject.getStyleAtPosition(0, true);
1588
+ this.fabricObject.set({ text: text });
1589
+ this.data.userText = this.fabricObject.text;
1590
+ this.text$.next(text);
1591
+ this.fabricObject.setSelectionStyles(style, 0, text.length);
1592
+ this.redraw();
1593
+ };
1594
+ /**
1595
+ * @override
1596
+ * @inheritDoc
1597
+ */
1598
+ Text.prototype.replaceText = function (target, replacement) {
1599
+ var start = this.getText().indexOf(target);
1600
+ this.fabricObject.insertChars(replacement, null, start, start + target.length);
1601
+ this.redraw();
1602
+ this.data.userText = this.fabricObject.text;
1603
+ this.text$.next(this.fabricObject.text);
1604
+ };
1605
+ /**
1606
+ * @override
1607
+ * @inheritDoc
1608
+ */
1609
+ Text.prototype.getColor = function () {
1610
+ return this.textSelection$.value.fill;
1611
+ };
1612
+ /**
1613
+ * @override
1614
+ * @inheritDoc
1615
+ */
1616
+ Text.prototype.setColor = function (color) {
1617
+ if (this.hasTextSelection()) {
1618
+ this.fabricObject.setSelectionStyles({ fill: color });
1619
+ }
1620
+ else {
1621
+ this.fabricObject.set({ fill: color });
1622
+ }
1623
+ this.data.color = color;
1624
+ this.updateTextSelection();
1625
+ this.redraw();
1626
+ };
1627
+ /**
1628
+ * @override
1629
+ * @inheritDoc
1630
+ */
1631
+ Text.prototype.getTextSelection = function () {
1632
+ return this.textSelection$.value;
1633
+ };
1634
+ /**
1635
+ * @override
1636
+ * @inheritDoc
1637
+ */
1638
+ Text.prototype.getTextSelection$ = function () {
1639
+ return this.textSelection$;
1640
+ };
1641
+ /**
1642
+ * @override
1643
+ * @inheritDoc
1644
+ */
1645
+ Text.prototype.setTextAlign = function (alignment) {
1646
+ this.fabricObject.set({ textAlign: alignment });
1647
+ this.redraw();
1648
+ this.updateTextSelection();
1649
+ };
1650
+ /**
1651
+ * @override
1652
+ * @inheritDoc
1653
+ */
1654
+ Text.prototype.setCharSpacing = function (spacing) {
1655
+ this.fabricObject.set({ charSpacing: spacing });
1656
+ this.redraw();
1657
+ this.updateTextSelection();
1658
+ };
1659
+ /**
1660
+ * @override
1661
+ * @inheritDoc
1662
+ */
1663
+ Text.prototype.setLineHeight = function (height) {
1664
+ this.fabricObject.set({ lineHeight: height });
1665
+ this.redraw();
1666
+ this.updateTextSelection();
1667
+ };
1668
+ /**
1669
+ * @override
1670
+ * @inheritDoc
1671
+ */
1672
+ Text.prototype.setBold = function (bold) {
1673
+ if (bold === void 0) { bold = true; }
1674
+ if (this.hasTextSelection()) {
1675
+ var start = this.textSelection$.value.start;
1676
+ for (var i = 0; i < this.textSelection$.value.length; i++) {
1677
+ var style = this.fabricObject.getStyleAtPosition(start + i, true);
1678
+ var font = this.fontLibrary.getFont(style.fontFamily);
1679
+ var fontWeight = bold ? font.boldWeight : font.normalWeight;
1680
+ this.fabricObject.setSelectionStyles({ fontWeight: fontWeight }, start + i, start + i + 1);
1681
+ }
1682
+ }
1683
+ else {
1684
+ var font = this.fontLibrary.getFont(this.fabricObject.fontFamily);
1685
+ var fontWeight = bold ? font.boldWeight : font.normalWeight;
1686
+ this.fabricObject.set({ fontWeight: fontWeight });
1687
+ }
1688
+ this.redraw();
1689
+ this.updateTextSelection();
1690
+ };
1691
+ /**
1692
+ * @override
1693
+ * @inheritDoc
1694
+ */
1695
+ Text.prototype.setBoldRegion = function (start, end, bold) {
1696
+ if (bold === void 0) { bold = true; }
1697
+ if (start > end)
1698
+ throw Error("Bad region specified: [" + start + " - " + end + "]");
1699
+ for (var i = start; i < end; i++) {
1700
+ var style = this.fabricObject.getStyleAtPosition(i, true);
1701
+ var font = this.fontLibrary.getFont(style.fontFamily);
1702
+ style.fontWeight = bold ? font.boldWeight : font.normalWeight;
1703
+ this.fabricObject.setSelectionStyles(style, i, i + 1);
1704
+ }
1705
+ this.redraw();
1706
+ };
1707
+ /**
1708
+ * @override
1709
+ * @inheritDoc
1710
+ */
1711
+ Text.prototype.setItalic = function (italic) {
1712
+ if (italic === void 0) { italic = true; }
1713
+ if (this.hasTextSelection()) {
1714
+ this.fabricObject.setSelectionStyles({ fontStyle: italic ? "italic" : "" });
1715
+ }
1716
+ else {
1717
+ this.fabricObject.set({ fontStyle: italic ? "italic" : "" });
1718
+ }
1719
+ this.redraw();
1720
+ this.updateTextSelection();
1721
+ };
1722
+ /**
1723
+ * @override
1724
+ * @inheritDoc
1725
+ */
1726
+ Text.prototype.setItalicRegion = function (start, end, italic) {
1727
+ if (italic === void 0) { italic = true; }
1728
+ if (start > end)
1729
+ throw Error("Bad region specified: [" + start + " - " + end + "]");
1730
+ this.fabricObject.setSelectionStyles({ fontStyle: italic ? "italic" : "" }, start, end);
1731
+ this.redraw();
1732
+ };
1733
+ /**
1734
+ * @override
1735
+ * @inheritDoc
1736
+ */
1737
+ Text.prototype.setStrikethrough = function (strikethrough) {
1738
+ if (strikethrough === void 0) { strikethrough = true; }
1739
+ if (this.hasTextSelection()) {
1740
+ this.fabricObject.setSelectionStyles({ linethrough: strikethrough });
1741
+ }
1742
+ else {
1743
+ this.fabricObject.set({ linethrough: strikethrough });
1744
+ }
1745
+ this.redraw();
1746
+ this.updateTextSelection();
1747
+ };
1748
+ /**
1749
+ * @override
1750
+ * @inheritDoc
1751
+ */
1752
+ Text.prototype.setUnderline = function (underline) {
1753
+ if (underline === void 0) { underline = true; }
1754
+ this.fabricObject.setSelectionStyles({ underline: underline });
1755
+ this.redraw();
1756
+ this.updateTextSelection();
1757
+ };
1758
+ /**
1759
+ * @override
1760
+ * @inheritDoc
1761
+ */
1762
+ Text.prototype.setFont = function (font) {
1763
+ if (this.hasTextSelection()) {
1764
+ this.fabricObject.setSelectionStyles({ fontFamily: font.family, fontWeight: font.normalWeight });
1765
+ }
1766
+ else {
1767
+ this.fabricObject.set({ fontFamily: font.family, fontWeight: font.normalWeight });
1768
+ }
1769
+ this.redraw();
1770
+ this.updateTextSelection();
1771
+ };
1772
+ /**
1773
+ * @override
1774
+ * @inheritDoc
1775
+ */
1776
+ Text.prototype.setFontSize = function (fontSize) {
1777
+ if (this.hasTextSelection()) {
1778
+ this.fabricObject.setSelectionStyles({ fontSize: fontSize });
1779
+ }
1780
+ else {
1781
+ this.fabricObject.set({ fontSize: fontSize });
1782
+ }
1783
+ this.redraw();
1784
+ this.updateTextSelection();
1785
+ };
1786
+ /**
1787
+ * @override
1788
+ * @inheritDoc
1789
+ */
1790
+ Text.prototype.setTextBackgroundColor = function (color) {
1791
+ if (this.hasTextSelection()) {
1792
+ this.fabricObject.setSelectionStyles({ textBackgroundColor: color });
1793
+ }
1794
+ else {
1795
+ this.fabricObject.set({ textBackgroundColor: color });
1796
+ }
1797
+ this.redraw();
1798
+ this.updateTextSelection();
1799
+ };
1800
+ /**
1801
+ * @override
1802
+ * @inheritDoc
1803
+ */
1804
+ Text.prototype.centerHorizontally = function () {
1805
+ _super.prototype.centerHorizontallyInternal.call(this);
1806
+ };
1807
+ /**
1808
+ * @override
1809
+ * @inheritDoc
1810
+ */
1811
+ Text.prototype.centerVertically = function () {
1812
+ _super.prototype.centerVerticallyInternal.call(this);
1813
+ };
1814
+ /**
1815
+ * @override
1816
+ * @inheritDoc
1817
+ */
1818
+ Text.prototype.setHeight = function (height) {
1819
+ //no-op
1820
+ };
1821
+ /**
1822
+ * @override
1823
+ * @inheritDoc
1824
+ */
1825
+ Text.prototype.nudgeUp = function () {
1826
+ _super.prototype.nudgeInternal.call(this, 0, -1);
1827
+ };
1828
+ /**
1829
+ * @override
1830
+ * @inheritDoc
1831
+ */
1832
+ Text.prototype.nudgeDown = function () {
1833
+ _super.prototype.nudgeInternal.call(this, 0, +1);
1834
+ };
1835
+ /**
1836
+ * @override
1837
+ * @inheritDoc
1838
+ */
1839
+ Text.prototype.nudgeLeft = function () {
1840
+ _super.prototype.nudgeInternal.call(this, -1, 0);
1841
+ };
1842
+ /**
1843
+ * @override
1844
+ * @inheritDoc
1845
+ */
1846
+ Text.prototype.nudgeRight = function () {
1847
+ _super.prototype.nudgeInternal.call(this, +1, 0);
1848
+ };
1849
+ /**
1850
+ * @override
1851
+ * @inheritDoc
1852
+ */
1853
+ Text.prototype.getBackgroundColor = function () {
1854
+ return this.fabricObject.backgroundColor;
1855
+ };
1856
+ /**
1857
+ * @override
1858
+ * @inheritDoc
1859
+ */
1860
+ Text.prototype.setBackgroundColor = function (color) {
1861
+ this.fabricObject.set({ backgroundColor: color });
1862
+ this.redraw();
1863
+ };
1864
+ /**
1865
+ * @override
1866
+ * @inheritDoc
1867
+ */
1868
+ Text.prototype.setPrefillType = function (prefillType) {
1869
+ this.data.prefillType = prefillType;
1870
+ };
1871
+ /**
1872
+ * @override
1873
+ * @inheritDoc
1874
+ */
1875
+ Text.prototype.getPrefillType = function () {
1876
+ return this.data.prefillType;
1877
+ };
1878
+ /**
1879
+ * @override
1880
+ * @inheritDoc
1881
+ */
1882
+ Text.prototype.isResizeCanvas = function () {
1883
+ return this.data.resizeCanvas;
1884
+ };
1885
+ /**
1886
+ * @override
1887
+ * @inheritDoc
1888
+ */
1889
+ Text.prototype.setResizeCanvas = function (value) {
1890
+ this.baseComponentHeight = this.fabricObject.height;
1891
+ this.data.resizeCanvas = value;
1892
+ };
1893
+ /**
1894
+ * @override
1895
+ * @inheritDoc
1896
+ */
1897
+ Text.prototype.focus = function () {
1898
+ this.fabricObject.hiddenTextarea.focus();
1899
+ };
1900
+ /**
1901
+ * @override
1902
+ * @inheritDoc
1903
+ */
1904
+ Text.prototype.isEditing = function () {
1905
+ return this.fabricObject.isEditing;
1906
+ };
1907
+ /**
1908
+ * @override
1909
+ * @inheritDoc
1910
+ */
1911
+ Text.prototype.enterEditing = function () {
1912
+ if (!this.isEditing()) {
1913
+ this.fabricObject.enterEditing();
1914
+ this.focus();
1915
+ this.selectAllText();
1916
+ this.redraw();
1917
+ }
1918
+ };
1919
+ /**
1920
+ * @override
1921
+ * @inheritDoc
1922
+ */
1923
+ Text.prototype.selectAllText = function () {
1924
+ this.fabricObject.selectAll();
1925
+ };
1926
+ /**
1927
+ * @override
1928
+ * @inheritDoc
1929
+ */
1930
+ Text.prototype.isBulleted = function () {
1931
+ return this.data.bulleted || false;
1932
+ };
1933
+ /**
1934
+ * @override
1935
+ * @inheritDoc
1936
+ */
1937
+ Text.prototype.enableBullets = function () {
1938
+ this.fabricObject["objectCaching"] = false;
1939
+ this.fabricObject["_bullets"] = this.fabricObject["_bullets"] || {};
1940
+ this.data.bulleted = true;
1941
+ this.notifyCanvasOfTextChanges();
1942
+ this.redraw();
1943
+ };
1944
+ /**
1945
+ * @override
1946
+ * @inheritDoc
1947
+ */
1948
+ Text.prototype.disableBullets = function () {
1949
+ this.removeBullets();
1950
+ this.data.bulleted = false;
1951
+ this.notifyCanvasOfTextChanges();
1952
+ this.redraw();
1953
+ };
1954
+ Text.prototype.getSizeIncreaseSinceCreation = function () {
1955
+ return Math.max(0, this.fabricObject.height - this.baseComponentHeight);
1956
+ };
1957
+ Text.prototype.removeBullets = function () {
1958
+ var _this = this;
1959
+ if (this.data.bulleted) {
1960
+ var bullets = this.fabricObject["_bullets"];
1961
+ delete this.fabricObject["_bullets"];
1962
+ _.each(bullets, function (bullet) { return _this.canvas.removeFabricObject(bullet); });
1963
+ this.fabricObject["objectCaching"] = true;
1964
+ }
1965
+ };
1966
+ Text.prototype.applyBulletListMonkeyPatches = function () {
1967
+ if (this.data.bulleted)
1968
+ this.enableBullets();
1969
+ var originalRender = this.fabricObject["_render"];
1970
+ var fabric = this.canvas.fabric;
1971
+ this.fabricObject["_render"] = function (ctx) {
1972
+ var fabricText = this;
1973
+ if (fabricText["_bullets"]) {
1974
+ // Determine list of active bullets
1975
+ var currentBullets_1 = fabricText["_bullets"];
1976
+ var activeBullets_1 = {};
1977
+ _.each(fabricText._textLines, function (textLine, lineIndex) {
1978
+ if (textLine.length) {
1979
+ // Start of real lines will have offset 0 in styleMap
1980
+ var styleMap = fabricText._styleMap[lineIndex];
1981
+ if (styleMap.offset === 0) {
1982
+ if (currentBullets_1[lineIndex]) {
1983
+ // Reuse existing bullet for this line
1984
+ activeBullets_1[lineIndex] = currentBullets_1[lineIndex];
1985
+ }
1986
+ else {
1987
+ // Create new bullet for this line
1988
+ var options = {
1989
+ left: 0,
1990
+ top: 0,
1991
+ radius: 2,
1992
+ fill: fabricText.fill,
1993
+ scaleX: fabricText.scaleX,
1994
+ scaleY: fabricText.scaleY,
1995
+ strokeWidth: 0,
1996
+ lockMovementX: true,
1997
+ lockMovementY: true,
1998
+ hasControls: false,
1999
+ selectable: false,
2000
+ excludeFromJson: true
2001
+ };
2002
+ activeBullets_1[lineIndex] = new fabric.Circle(options);
2003
+ }
2004
+ }
2005
+ }
2006
+ });
2007
+ // Add/Remove bullets from canvas
2008
+ var canvas_1 = fabricText.canvas;
2009
+ var canvasDirty_1 = false;
2010
+ canvas_1.renderOnAddRemove = false;
2011
+ _.each(activeBullets_1, function (bullet) {
2012
+ if (!canvas_1.contains(bullet)) {
2013
+ canvas_1.add(bullet);
2014
+ canvasDirty_1 = true;
2015
+ }
2016
+ });
2017
+ _.each(currentBullets_1, function (bullet, key) {
2018
+ if (!activeBullets_1[key]) {
2019
+ canvas_1.remove(bullet);
2020
+ canvasDirty_1 = true;
2021
+ }
2022
+ });
2023
+ canvas_1.renderOnAddRemove = true;
2024
+ fabricText["_bullets"] = activeBullets_1;
2025
+ if (canvasDirty_1) {
2026
+ // Fabric doesn't like it when you add new things within render so use a sneaky timeout to delay render
2027
+ setTimeout(canvas_1.renderAll.bind(canvas_1));
2028
+ }
2029
+ }
2030
+ originalRender.apply(fabricText, [ctx]);
2031
+ };
2032
+ var originalRenderTextLine = this.fabricObject["_renderTextLine"];
2033
+ this.fabricObject["_renderTextLine"] = function (method, ctx, line, left, top, lineIndex) {
2034
+ var fabricText = this;
2035
+ var bullets = fabricText._bullets;
2036
+ if (bullets && bullets[lineIndex]) {
2037
+ var bullet = bullets[lineIndex];
2038
+ var bulletIndent = 10;
2039
+ var bulletLeft = fabricText.left + (left - fabricText._getLeftOffset() - bulletIndent) * fabricText.scaleX;
2040
+ if (bullet.left !== bulletLeft) {
2041
+ bullet.set({ left: bulletLeft });
2042
+ }
2043
+ /**
2044
+ * What an out-and-out mess... this calculation is a joke, and the bulletOffset is just an approximation of values that look ok for
2045
+ * the font sizes we use. The 'top' value provided is actutally the... bottom? of the line... and not the line... the bottom of where
2046
+ * the font is rendered... subtracting the `fabricText.getHeightOfLine(lineIndex)` line hieght doesn't give you the top, because the
2047
+ * line height is actually the height of the font plus the excess line height added via the text line-height property.
2048
+ * I couldn't figure out how to get the actual top of the line in two days of trying to understand this ridiculous library.
2049
+ * So, here... bullets. That sort of work... sometimes.
2050
+ */
2051
+ var textOriginTop = fabricText.top + (fabricText.height / 2);
2052
+ var fontSize = this.getValueOfPropertyAt(lineIndex, 0, "fontSize");
2053
+ var bulletOffset = ((fontSize + 6) / 2);
2054
+ var bulletTop = textOriginTop + top - bulletOffset;
2055
+ if (bullet.top !== bulletTop) {
2056
+ bullet.set({ top: bulletTop });
2057
+ }
2058
+ if (bullet.fill !== fabricText.fill) {
2059
+ bullet.set({ fill: fabricText.fill });
2060
+ }
2061
+ }
2062
+ originalRenderTextLine.apply(fabricText, [method, ctx, line, left, top, lineIndex]);
2063
+ };
2064
+ };
2065
+ /**
2066
+ * @override
2067
+ * @inheritDoc
2068
+ */
2069
+ Text.prototype.updateFabricObjectBehavior = function () {
2070
+ _super.prototype.updateFabricObjectBehavior.call(this);
2071
+ var profile = this.canvas.getProfile();
2072
+ var allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
2073
+ this.fabricObject.set({
2074
+ lockScalingY: true,
2075
+ lockScalingX: this.isPinToBottom(),
2076
+ lockScalingFlip: true
2077
+ });
2078
+ this.fabricObject.setControlsVisibility({
2079
+ tl: false,
2080
+ tr: false,
2081
+ br: false,
2082
+ bl: false,
2083
+ ml: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
2084
+ mt: false,
2085
+ mr: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
2086
+ mb: false
2087
+ });
2088
+ this.redraw();
2089
+ };
2090
+ Text.prototype.onTextChange = function () {
2091
+ this.data.userText = this.fabricObject.text;
2092
+ this.text$.next(this.fabricObject.text);
2093
+ if (this.getBoundingBox().width > this.canvas.getDimensions().widthPx) {
2094
+ this.fabricObject.set({ left: 0, width: this.canvas.getDimensions().widthPx });
2095
+ this.redraw();
2096
+ }
2097
+ };
2098
+ Text.prototype.onDelete = function () {
2099
+ this.removeBullets();
2100
+ };
2101
+ Text.prototype.onSelectionChange = function () {
2102
+ this.updateTextSelection();
2103
+ };
2104
+ Text.prototype.hasTextSelection = function () {
2105
+ return this.canvas.getSelection().isText && this.textSelection$.value.length > 0;
2106
+ };
2107
+ Text.prototype.updateTextSelection = function () {
2108
+ this.textSelection$.next(new TextSelection(this.fabricObject, this.fontLibrary));
2109
+ this.notifyCanvasOfTextChanges();
2110
+ };
2111
+ Text.prototype.notifyCanvasOfTextChanges = function () {
2112
+ this.canvas.notifyTextChanged();
2113
+ };
2114
+ return Text;
2115
+ }(AbstractCanvasObject));
2116
+ var TextSelection = /** @class */ (function () {
2117
+ function TextSelection(fabricObject, fontLibrary) {
2118
+ this.fabricObject = fabricObject;
2119
+ this.fontLibrary = fontLibrary;
2120
+ this.start = this.fabricObject.selectionStart;
2121
+ this.end = this.fabricObject.selectionEnd;
2122
+ this.length = this.end - this.start;
2123
+ var cursorLoc = this.fabricObject.get2DCursorLocation();
2124
+ this.lineIndex = cursorLoc.lineIndex;
2125
+ this.charIndex = cursorLoc.charIndex;
2126
+ var style = this.fabricObject.getCompleteStyleDeclaration(this.lineIndex, this.charIndex);
2127
+ var hasSelection = this.length > 0;
2128
+ this.font = hasSelection ? this.fontLibrary.getFont(style.fontFamily) : this.fontLibrary.getFont(this.fabricObject.fontFamily);
2129
+ this.fontSize = hasSelection ? style.fontSize : this.fabricObject.fontSize;
2130
+ this.fontWeight = hasSelection ? style.fontWeight : this.fabricObject.fontWeight;
2131
+ this.bold = this.font.isBold(this.fontWeight);
2132
+ this.italic = hasSelection ? style.fontStyle === "italic" : this.fabricObject.fontStyle === "italic";
2133
+ this.underline = hasSelection ? style.underline : this.fabricObject.underline;
2134
+ this.strikethrough = hasSelection ? style.linethrough : this.fabricObject.linethrough;
2135
+ this.overline = hasSelection ? style.overline : this.fabricObject.overline;
2136
+ this.textBackgroundColor = hasSelection ? style.textBackgroundColor : this.fabricObject.textBackgroundColor;
2137
+ this.textAlign = this.fabricObject.textAlign;
2138
+ this.charSpacing = this.fabricObject.charSpacing;
2139
+ this.lineHeight = this.fabricObject.lineHeight;
2140
+ this.fill = style.fill;
2141
+ this.stroke = style.stroke;
2142
+ this.strokeWidth = style.strokeWidth;
2143
+ }
2144
+ return TextSelection;
2145
+ }());
2146
+
2147
+ var VerticalRule = /** @class */ (function (_super) {
2148
+ __extends(VerticalRule, _super);
2149
+ function VerticalRule(canvas, fabricObject, persistedField) {
2150
+ var _this = _super.call(this, exports.ObjectType.VERTICAL_RULE, canvas, fabricObject, persistedField) || this;
2151
+ _this.strokeWidth$ = new rxjs.BehaviorSubject(2);
2152
+ _this.canvas = canvas;
2153
+ _this.strokeWidth$.next(_this.getDimensions().width.px);
2154
+ _this.fabricObject.set({ strokeWidth: 0 });
2155
+ return _this;
2156
+ }
2157
+ /**
2158
+ * @override
2159
+ * @inheritDoc
2160
+ */
2161
+ VerticalRule.prototype.getStrokeWidth = function () {
2162
+ return this.fabricObject.width;
2163
+ };
2164
+ /**
2165
+ * @override
2166
+ * @inheritDoc
2167
+ */
2168
+ VerticalRule.prototype.getStrokeWidth$ = function () {
2169
+ return this.strokeWidth$;
2170
+ };
2171
+ /**
2172
+ * @override
2173
+ * @inheritDoc
2174
+ */
2175
+ VerticalRule.prototype.setStrokeWidth = function (width) {
2176
+ this.strokeWidth$.next(width);
2177
+ this.data.strokeWidth = width;
2178
+ this.setPosition({ width: width });
2179
+ this.canvas.notifyObjectListChanged();
2180
+ this.redraw();
2181
+ };
2182
+ /**
2183
+ * @override
2184
+ * @inheritDoc
2185
+ */
2186
+ VerticalRule.prototype.getColor = function () {
2187
+ return this.fabricObject.fill;
2188
+ };
2189
+ /**
2190
+ * @override
2191
+ * @inheritDoc
2192
+ */
2193
+ VerticalRule.prototype.setColor = function (color) {
2194
+ this.fabricObject.set({ fill: color, stroke: color });
2195
+ this.data.color = color;
2196
+ this.redraw();
2197
+ };
2198
+ /**
2199
+ * @override
2200
+ * @inheritDoc
2201
+ */
2202
+ VerticalRule.prototype.centerHorizontally = function () {
2203
+ _super.prototype.centerHorizontallyInternal.call(this);
2204
+ };
2205
+ /**
2206
+ * @override
2207
+ * @inheritDoc
2208
+ */
2209
+ VerticalRule.prototype.centerVertically = function () {
2210
+ _super.prototype.centerVerticallyInternal.call(this);
2211
+ };
2212
+ /**
2213
+ * @override
2214
+ * @inheritDoc
2215
+ */
2216
+ VerticalRule.prototype.setHeight = function (height) {
2217
+ this.setPosition({ height: height });
2218
+ this.canvas.notifyObjectListChanged();
2219
+ };
2220
+ /**
2221
+ * @override
2222
+ * @inheritDoc
2223
+ */
2224
+ VerticalRule.prototype.nudgeUp = function () {
2225
+ _super.prototype.nudgeInternal.call(this, 0, -1);
2226
+ };
2227
+ /**
2228
+ * @override
2229
+ * @inheritDoc
2230
+ */
2231
+ VerticalRule.prototype.nudgeDown = function () {
2232
+ _super.prototype.nudgeInternal.call(this, 0, +1);
2233
+ };
2234
+ /**
2235
+ * @override
2236
+ * @inheritDoc
2237
+ */
2238
+ VerticalRule.prototype.nudgeLeft = function () {
2239
+ _super.prototype.nudgeInternal.call(this, -1, 0);
2240
+ };
2241
+ /**
2242
+ * @override
2243
+ * @inheritDoc
2244
+ */
2245
+ VerticalRule.prototype.nudgeRight = function () {
2246
+ _super.prototype.nudgeInternal.call(this, +1, 0);
2247
+ };
2248
+ return VerticalRule;
2249
+ }(AbstractCanvasObject));
2250
+
2251
+ /**
2252
+ * Profile with as many features disabled as possible.
2253
+ */
2254
+ var DefaultCanvasProfile = /** @class */ (function () {
2255
+ function DefaultCanvasProfile() {
2256
+ this.allowMultiSelect = false;
2257
+ this.enterTextEditImmediatelyOnSelect = true;
2258
+ this.allowObjectsToLeaveCanvas = false;
2259
+ this.allowMove = false;
2260
+ this.allowRotate = false;
2261
+ this.allowScale = false;
2262
+ this.defaultFont = "Lato";
2263
+ this.defaultFontSize = 8;
2264
+ this.defaultFontColor = "#000000";
2265
+ this.defaultLineHeight = 1.8;
2266
+ this.defaultCharacterSpacing = 0;
2267
+ this.defaultTextAlignment = "left";
2268
+ this.defaultBorderColor = "#000000";
2269
+ this.defaultBorderWidth = 1;
2270
+ this.defaultCutoffColor = "#000000";
2271
+ this.defaultCutoffWidth = 1;
2272
+ }
2273
+ return DefaultCanvasProfile;
2274
+ }());
2275
+
2276
+ (function (ImageType) {
2277
+ ImageType["DEFAULT"] = "DEFAULT";
2278
+ ImageType["BACKGROUND"] = "BACKGROUND";
2279
+ ImageType["LOGO"] = "LOGO";
2280
+ ImageType["PHOTO"] = "PHOTO";
2281
+ })(exports.ImageType || (exports.ImageType = {}));
2282
+
2283
+ (function (ObjectType) {
2284
+ ObjectType["TEXT"] = "TEXT";
2285
+ ObjectType["BORDER"] = "BORDER";
2286
+ ObjectType["IMAGE"] = "IMAGE";
2287
+ ObjectType["RECTANGLE"] = "RECTANGLE";
2288
+ ObjectType["LIBRARY_IMAGE"] = "LIBRARY_IMAGE";
2289
+ ObjectType["CUTOFF"] = "CUTOFF";
2290
+ ObjectType["VERTICAL_RULE"] = "VERTICAL_RULE";
2291
+ ObjectType["HORIZONTAL_RULE"] = "HORIZONTAL_RULE";
2292
+ })(exports.ObjectType || (exports.ObjectType = {}));
2293
+
2294
+ var AbstractInteractiveCanvas = /** @class */ (function () {
2295
+ function AbstractInteractiveCanvas(fabric, fabricCanvas, devicePixelRatio) {
2296
+ this.fabric = fabric;
2297
+ this.fabricCanvas = fabricCanvas;
2298
+ this.devicePixelRatio = devicePixelRatio;
2299
+ this.fontLibrary = new FontLibrary();
2300
+ this.dimensionChangeRejections$ = new rxjs.Subject();
2301
+ this.IMAGE_CAPTURE_COEFFICIENT = this.calculateImageCaptureCoefficient();
2302
+ this.baseDimensions = new PixelCanvasDimensions(this.fabricCanvas.width, this.fabricCanvas.height);
2303
+ var baseRestrictions = { width: { min: 1 }, height: { min: 1 } };
2304
+ //Initialize properties
2305
+ this.dimensions$ = new rxjs.BehaviorSubject(this.baseDimensions);
2306
+ this.dimensionRestrictions$ = new rxjs.BehaviorSubject(baseRestrictions);
2307
+ this.zoom$ = new rxjs.BehaviorSubject(1);
2308
+ this.profile$ = new rxjs.BehaviorSubject(new DefaultCanvasProfile());
2309
+ this.layoutManager$ = new rxjs.BehaviorSubject(new AdvancedLayoutManager(this));
2310
+ this.backgroundColor$ = new rxjs.BehaviorSubject(this.fabricCanvas.backgroundColor);
2311
+ this.objects$ = new rxjs.BehaviorSubject([]);
2312
+ this.selection$ = new rxjs.BehaviorSubject(new SelectionData([]));
2313
+ //Configure canvas behaviour
2314
+ this.fabricCanvas.stateful = true;
2315
+ this.fabricCanvas.preserveObjectStacking = true;
2316
+ this.fabricCanvas.perPixelTargetFind = true;
2317
+ this.fabricCanvas.targetFindTolerance = 10;
2318
+ this.setBackgroundColor("#FFFFFF");
2319
+ }
2320
+ /**
2321
+ * @override
2322
+ * @inheritDoc
2323
+ */
2324
+ AbstractInteractiveCanvas.prototype.getFontLibrary = function () {
2325
+ return this.fontLibrary;
2326
+ };
2327
+ /**
2328
+ * @override
2329
+ * @inheritDoc
2330
+ */
2331
+ AbstractInteractiveCanvas.prototype.getProfile = function () {
2332
+ return this.profile$.value;
2333
+ };
2334
+ /**
2335
+ * @override
2336
+ * @inheritDoc
2337
+ */
2338
+ AbstractInteractiveCanvas.prototype.getProfile$ = function () {
2339
+ return this.profile$;
2340
+ };
2341
+ /**
2342
+ * @override
2343
+ * @inheritDoc
2344
+ */
2345
+ AbstractInteractiveCanvas.prototype.setProfile = function (profile) {
2346
+ this.profile$.next(profile);
2347
+ this.onProfileChanged(profile);
2348
+ this.redraw();
2349
+ };
2350
+ /**
2351
+ * @override
2352
+ * @inheritDoc
2353
+ */
2354
+ AbstractInteractiveCanvas.prototype.getLayoutManager = function () {
2355
+ return this.layoutManager$.value;
2356
+ };
2357
+ /**
2358
+ * @override
2359
+ * @inheritDoc
2360
+ */
2361
+ AbstractInteractiveCanvas.prototype.getLayoutManager$ = function () {
2362
+ return this.layoutManager$;
2363
+ };
2364
+ /**
2365
+ * @override
2366
+ * @inheritDoc
2367
+ */
2368
+ AbstractInteractiveCanvas.prototype.setLayoutManager = function (layoutManager) {
2369
+ if (layoutManager === exports.LayoutManager.STANDARD) {
2370
+ this.layoutManager$.next(new StandardLayoutManager(this));
2371
+ }
2372
+ else {
2373
+ this.layoutManager$.next(new AdvancedLayoutManager(this));
2374
+ }
2375
+ this.layoutManager$.value.onInit();
2376
+ };
2377
+ /**
2378
+ * @override
2379
+ * @inheritDoc
2380
+ */
2381
+ AbstractInteractiveCanvas.prototype.getBackgroundColor = function () {
2382
+ return this.backgroundColor$.value;
2383
+ };
2384
+ /**
2385
+ * @override
2386
+ * @inheritDoc
2387
+ */
2388
+ AbstractInteractiveCanvas.prototype.getBackgroundColor$ = function () {
2389
+ return this.backgroundColor$;
2390
+ };
2391
+ /**
2392
+ * @override
2393
+ * @inheritDoc
2394
+ */
2395
+ AbstractInteractiveCanvas.prototype.setBackgroundColor = function (color) {
2396
+ if (color === void 0) { color = "White"; }
2397
+ this.fabricCanvas.setBackgroundColor(color, function () {
2398
+ });
2399
+ this.fabricCanvas.renderAll();
2400
+ this.backgroundColor$.next(color);
2401
+ };
2402
+ /**
2403
+ * @override
2404
+ * @inheritDoc
2405
+ */
2406
+ AbstractInteractiveCanvas.prototype.getDimensions = function () {
2407
+ return this.dimensions$.value;
2408
+ };
2409
+ /**
2410
+ * @override
2411
+ * @inheritDoc
2412
+ */
2413
+ AbstractInteractiveCanvas.prototype.getBaseDimensions = function () {
2414
+ return this.baseDimensions;
2415
+ };
2416
+ /**
2417
+ * @override
2418
+ * @inheritDoc
2419
+ */
2420
+ AbstractInteractiveCanvas.prototype.getDimensions$ = function () {
2421
+ return this.dimensions$;
2422
+ };
2423
+ /**
2424
+ * @override
2425
+ * @inheritDoc
2426
+ */
2427
+ AbstractInteractiveCanvas.prototype.setDimensions = function (dimensions) {
2428
+ if (this.dimensionsExceedRestrictions(dimensions)) {
2429
+ console.debug("Requested canvas dimensions exceed current restrictions", dimensions, this.dimensionRestrictions$.value);
2430
+ this.dimensionChangeRejections$.next(dimensions);
2431
+ return;
2432
+ }
2433
+ this.updateCanvasDimensions(dimensions, this.zoom$.value);
2434
+ this.dimensions$.next(dimensions);
2435
+ this.onDimensionsChange();
2436
+ this.notifyObjectListChanged();
2437
+ };
2438
+ /**
2439
+ * @override
2440
+ * @inheritDoc
2441
+ */
2442
+ AbstractInteractiveCanvas.prototype.setBaseDimensions = function (dimensions) {
2443
+ this.baseDimensions = dimensions;
2444
+ this.setDimensions(dimensions);
2445
+ this.notifyObjectListChanged();
2446
+ };
2447
+ /**
2448
+ * @override
2449
+ * @inheritDoc
2450
+ */
2451
+ AbstractInteractiveCanvas.prototype.getDimensionChangeRejections$ = function () {
2452
+ return this.dimensionChangeRejections$;
2453
+ };
2454
+ /**
2455
+ * @override
2456
+ * @inheritDoc
2457
+ */
2458
+ AbstractInteractiveCanvas.prototype.getDimensionsRestrictions = function () {
2459
+ return this.dimensionRestrictions$.value;
2460
+ };
2461
+ /**
2462
+ * @override
2463
+ * @inheritDoc
2464
+ */
2465
+ AbstractInteractiveCanvas.prototype.getDimensionsRestrictions$ = function () {
2466
+ return this.dimensionRestrictions$;
2467
+ };
2468
+ /**
2469
+ * @override
2470
+ * @inheritDoc
2471
+ */
2472
+ AbstractInteractiveCanvas.prototype.setDimensionRestrictions = function (restrictions) {
2473
+ this.dimensionRestrictions$.next(restrictions);
2474
+ };
2475
+ AbstractInteractiveCanvas.prototype.getMargin = function () {
2476
+ var borderWidth = this.getObjectsByTypeInternal(exports.ObjectType.BORDER)
2477
+ .map(function (border) { return border.getStrokeWidth(); })
2478
+ .reduce(function (current, next) { return Math.max(current, next); }, 0);
2479
+ var borderPadding = this.getObjectsByTypeInternal(exports.ObjectType.BORDER)
2480
+ .map(function (border) { return border.getPadding(); })
2481
+ .reduce(function (current, next) {
2482
+ return {
2483
+ top: Math.max(current.top, next.top),
2484
+ right: Math.max(current.right, next.right),
2485
+ bottom: Math.max(current.bottom, next.bottom),
2486
+ left: Math.max(current.bottom, next.bottom)
2487
+ };
2488
+ }, { top: 0, right: 0, bottom: 0, left: 0 });
2489
+ var cutoffWidth = this.getObjectsByTypeInternal(exports.ObjectType.CUTOFF)
2490
+ .map(function (border) { return border.getStrokeWidth(); })
2491
+ .reduce(function (current, next) { return Math.max(current, next); }, 0);
2492
+ // noinspection JSSuspiciousNameCombination
2493
+ return {
2494
+ top: borderWidth + borderPadding.top,
2495
+ right: borderWidth + borderPadding.right,
2496
+ bottom: Math.max(cutoffWidth, borderWidth) + borderPadding.bottom,
2497
+ left: borderWidth + borderPadding.left
2498
+ };
2499
+ };
2500
+ /**
2501
+ * @override
2502
+ * @inheritDoc
2503
+ */
2504
+ AbstractInteractiveCanvas.prototype.getZoom = function () {
2505
+ return this.zoom$.value;
2506
+ };
2507
+ /**
2508
+ * @override
2509
+ * @inheritDoc
2510
+ */
2511
+ AbstractInteractiveCanvas.prototype.getZoom$ = function () {
2512
+ return this.zoom$;
2513
+ };
2514
+ /**
2515
+ * @override
2516
+ * @inheritDoc
2517
+ */
2518
+ AbstractInteractiveCanvas.prototype.setZoom = function (zoom) {
2519
+ this.updateCanvasDimensions(this.dimensions$.value, zoom);
2520
+ this.zoom$.next(zoom);
2521
+ };
2522
+ /**
2523
+ * @override
2524
+ * @inheritDoc
2525
+ */
2526
+ AbstractInteractiveCanvas.prototype.getObjects = function () {
2527
+ return this.objects$.value;
2528
+ };
2529
+ /**
2530
+ * Get the list of objects directly.
2531
+ */
2532
+ AbstractInteractiveCanvas.prototype.getObjectsInternal = function () {
2533
+ return this.objects$.value;
2534
+ };
2535
+ /**
2536
+ * @override
2537
+ * @inheritDoc
2538
+ */
2539
+ AbstractInteractiveCanvas.prototype.getObjectsByTypeInternal = function (type) {
2540
+ return _(this.getObjectsInternal())
2541
+ .filter(function (object) { return object.getType() === type; })
2542
+ .value();
2543
+ };
2544
+ /**
2545
+ * @override
2546
+ * @inheritDoc
2547
+ */
2548
+ AbstractInteractiveCanvas.prototype.getObjectsByTypesInternal = function () {
2549
+ var types = [];
2550
+ for (var _i = 0; _i < arguments.length; _i++) {
2551
+ types[_i] = arguments[_i];
2552
+ }
2553
+ return _(this.getObjectsInternal())
2554
+ .filter(function (object) { return _(types).includes(object.getType()); })
2555
+ .value();
2556
+ };
2557
+ /**
2558
+ * @override
2559
+ * @inheritDoc
2560
+ */
2561
+ AbstractInteractiveCanvas.prototype.getObjects$ = function () {
2562
+ return this.objects$;
2563
+ };
2564
+ /**
2565
+ * @override
2566
+ * @inheritDoc
2567
+ */
2568
+ AbstractInteractiveCanvas.prototype.removeObject = function (target) {
2569
+ var concreteObject = this.findFabricObject(target.getId());
2570
+ this.fabricCanvas.remove(concreteObject);
2571
+ this.objects$.next(_(this.objects$.value)
2572
+ .filter(function (object) { return object.getId() !== target.getId(); })
2573
+ .value());
2574
+ this.onObjectListChange();
2575
+ };
2576
+ /**
2577
+ * @override
2578
+ * @inheritDoc
2579
+ */
2580
+ AbstractInteractiveCanvas.prototype.addImageObject = function (imageUrl) {
2581
+ return __awaiter(this, void 0, void 0, function () {
2582
+ var maxSizeScale, maxWidth, options;
2583
+ var _this = this;
2584
+ return __generator(this, function (_a) {
2585
+ switch (_a.label) {
2586
+ case 0:
2587
+ maxSizeScale = 2;
2588
+ maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
2589
+ options = { crossOrigin: "anonymous" };
2590
+ return [4 /*yield*/, new Promise(function (resolve) {
2591
+ _this.fabric.Image.fromURL(imageUrl, function (fabricImage) {
2592
+ var id = _this.randomId();
2593
+ var newScale = 1;
2594
+ var curWidth = newScale * fabricImage.width;
2595
+ if (curWidth > maxWidth) {
2596
+ newScale = maxWidth / curWidth;
2597
+ }
2598
+ fabricImage.set({
2599
+ id: id,
2600
+ scaleX: newScale,
2601
+ scaleY: newScale
2602
+ });
2603
+ _this.fabricCanvas.add(fabricImage);
2604
+ var object = new Image(_this, fabricImage);
2605
+ _this.trackNewObject(object);
2606
+ _this.selectFabricObject(fabricImage);
2607
+ _this.syncObjectList();
2608
+ resolve(object);
2609
+ }, options);
2610
+ })];
2611
+ case 1: return [2 /*return*/, _a.sent()];
2612
+ }
2613
+ });
2614
+ });
2615
+ };
2616
+ /**
2617
+ * @override
2618
+ * @inheritDoc
2619
+ */
2620
+ AbstractInteractiveCanvas.prototype.addTextObject = function () {
2621
+ return __awaiter(this, void 0, void 0, function () {
2622
+ var profile, id, fontSizePx, canvasWidthPx, lowestTextPointPx, topPx, textOptions, fabricTextbox, object;
2623
+ return __generator(this, function (_a) {
2624
+ profile = this.profile$.value;
2625
+ id = this.randomId();
2626
+ fontSizePx = profile.defaultFontSize;
2627
+ canvasWidthPx = this.getDimensions().widthPx;
2628
+ lowestTextPointPx = this.getLowestTextPoint();
2629
+ topPx = Math.min(lowestTextPointPx, this.getDimensions().heightPx - fontSizePx);
2630
+ textOptions = {
2631
+ id: id,
2632
+ top: topPx,
2633
+ left: 5,
2634
+ width: canvasWidthPx - 10,
2635
+ fill: profile.defaultFontColor,
2636
+ fontSize: fontSizePx,
2637
+ fontFamily: profile.defaultFont,
2638
+ textAlign: profile.defaultTextAlignment,
2639
+ multiLine: true,
2640
+ lineHeight: profile.defaultLineHeight,
2641
+ charSpacing: profile.defaultCharacterSpacing
2642
+ };
2643
+ fabricTextbox = new this.fabric.Textbox("Text goes here", textOptions);
2644
+ this.fabricCanvas.add(fabricTextbox);
2645
+ object = new Text(this, fabricTextbox);
2646
+ this.trackNewObject(object);
2647
+ this.selectFabricObject(fabricTextbox);
2648
+ this.syncObjectList();
2649
+ return [2 /*return*/, object];
2650
+ });
2651
+ });
2652
+ };
2653
+ /**
2654
+ * @override
2655
+ * @inheritDoc
2656
+ */
2657
+ AbstractInteractiveCanvas.prototype.addRectangleObject = function () {
2658
+ return __awaiter(this, void 0, void 0, function () {
2659
+ var canvasWidth, canvasHeight, rectWidth, rectHeight, rectangleOptions, fabricRect, object;
2660
+ return __generator(this, function (_a) {
2661
+ canvasWidth = this.getDimensions().widthPx;
2662
+ canvasHeight = this.getDimensions().heightPx;
2663
+ rectWidth = canvasWidth / 2;
2664
+ rectHeight = canvasHeight / 2;
2665
+ rectangleOptions = {
2666
+ id: this.randomId(),
2667
+ width: canvasWidth / 2,
2668
+ height: 2,
2669
+ top: canvasHeight / 2 - rectHeight / 2,
2670
+ left: canvasWidth / 2 - rectWidth / 2,
2671
+ fill: "#000000"
2672
+ };
2673
+ fabricRect = new this.fabric.Rect(rectangleOptions);
2674
+ this.fabricCanvas.add(fabricRect);
2675
+ object = new Rectangle(this, fabricRect);
2676
+ this.trackNewObject(object);
2677
+ this.selectFabricObject(fabricRect);
2678
+ this.syncObjectList();
2679
+ return [2 /*return*/, object];
2680
+ });
2681
+ });
2682
+ };
2683
+ /**
2684
+ * @override
2685
+ * @inheritDoc
2686
+ */
2687
+ AbstractInteractiveCanvas.prototype.addCutoffObject = function () {
2688
+ return __awaiter(this, void 0, void 0, function () {
2689
+ var profile, initialThickness, canvasWidth, canvasHeight, rectangleOptions, fabricRect, object;
2690
+ return __generator(this, function (_a) {
2691
+ profile = this.profile$.value;
2692
+ initialThickness = profile.defaultCutoffWidth;
2693
+ canvasWidth = this.getDimensions().widthPx;
2694
+ canvasHeight = this.getDimensions().heightPx;
2695
+ rectangleOptions = {
2696
+ id: this.randomId(),
2697
+ width: canvasWidth,
2698
+ height: initialThickness,
2699
+ top: canvasHeight - initialThickness,
2700
+ left: 0,
2701
+ fill: profile.defaultCutoffColor
2702
+ };
2703
+ fabricRect = new this.fabric.Rect(rectangleOptions);
2704
+ this.fabricCanvas.add(fabricRect);
2705
+ object = new Cutoff(this, fabricRect);
2706
+ this.trackNewObject(object);
2707
+ this.selectFabricObject(fabricRect);
2708
+ this.syncObjectList();
2709
+ return [2 /*return*/, object];
2710
+ });
2711
+ });
2712
+ };
2713
+ /**
2714
+ * @override
2715
+ * @inheritDoc
2716
+ */
2717
+ AbstractInteractiveCanvas.prototype.addBorderObject = function () {
2718
+ return __awaiter(this, void 0, void 0, function () {
2719
+ var profile, initialThickness, rectangleOptions, fabricRect, object;
2720
+ return __generator(this, function (_a) {
2721
+ profile = this.profile$.value;
2722
+ initialThickness = profile.defaultBorderWidth;
2723
+ rectangleOptions = {
2724
+ id: this.randomId(),
2725
+ fill: null,
2726
+ stroke: profile.defaultBorderColor,
2727
+ strokeWidth: initialThickness
2728
+ };
2729
+ fabricRect = new this.fabric.Rect(rectangleOptions);
2730
+ this.fabricCanvas.add(fabricRect);
2731
+ object = new Border(this, fabricRect);
2732
+ this.trackNewObject(object);
2733
+ this.selectFabricObject(fabricRect);
2734
+ this.syncObjectList();
2735
+ return [2 /*return*/, object];
2736
+ });
2737
+ });
2738
+ };
2739
+ /**
2740
+ * @override
2741
+ * @inheritDoc
2742
+ */
2743
+ AbstractInteractiveCanvas.prototype.addVerticalRuleObject = function () {
2744
+ return __awaiter(this, void 0, void 0, function () {
2745
+ var rectOptions, fabricRect, object;
2746
+ return __generator(this, function (_a) {
2747
+ rectOptions = {
2748
+ id: this.randomId(),
2749
+ width: 2,
2750
+ height: 10,
2751
+ top: 0,
2752
+ left: 0,
2753
+ fill: "#000000"
2754
+ };
2755
+ fabricRect = new this.fabric.Rect(rectOptions);
2756
+ this.fabricCanvas.add(fabricRect);
2757
+ object = new VerticalRule(this, fabricRect);
2758
+ this.trackNewObject(object);
2759
+ this.selectFabricObject(fabricRect);
2760
+ this.syncObjectList();
2761
+ return [2 /*return*/, object];
2762
+ });
2763
+ });
2764
+ };
2765
+ /**
2766
+ * @override
2767
+ * @inheritDoc
2768
+ */
2769
+ AbstractInteractiveCanvas.prototype.addHorizontalRuleObject = function () {
2770
+ return __awaiter(this, void 0, void 0, function () {
2771
+ var rectOptions, fabricRect, object;
2772
+ return __generator(this, function (_a) {
2773
+ rectOptions = {
2774
+ id: this.randomId(),
2775
+ width: 10,
2776
+ height: 2,
2777
+ top: 0,
2778
+ left: 0,
2779
+ fill: "#000000"
2780
+ };
2781
+ fabricRect = new this.fabric.Rect(rectOptions);
2782
+ this.fabricCanvas.add(fabricRect);
2783
+ object = new HorizontalRule(this, fabricRect);
2784
+ this.trackNewObject(object);
2785
+ this.selectFabricObject(fabricRect);
2786
+ this.syncObjectList();
2787
+ return [2 /*return*/, object];
2788
+ });
2789
+ });
2790
+ };
2791
+ /**
2792
+ * @override
2793
+ * @inheritDoc
2794
+ */
2795
+ AbstractInteractiveCanvas.prototype.setPrefillData = function (data) {
2796
+ _(this.getObjectsByTypeInternal(exports.ObjectType.TEXT)).each(function (object) {
2797
+ var prefillType = object.getPrefillType();
2798
+ if (prefillType !== null) {
2799
+ object.setText(data[prefillType] || "");
2800
+ }
2801
+ });
2802
+ };
2803
+ /**
2804
+ * @override
2805
+ * @inheritDoc
2806
+ */
2807
+ AbstractInteractiveCanvas.prototype.distributeObjectsVertically = function () {
2808
+ var margin = this.getMargin();
2809
+ var canvasHeight = this.getDimensions().heightPx;
2810
+ var objectsToLayout = _(this.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.IMAGE))
2811
+ .sortBy(function (x) { return x.getBoundingBox().top; })
2812
+ .value();
2813
+ var objectsHeight = _.reduce(objectsToLayout, function (total, element) { return total + element.getBoundingBox().height; }, 0);
2814
+ var workableHeight = canvasHeight - margin.top - margin.bottom;
2815
+ var requiredPadding = workableHeight - objectsHeight;
2816
+ var spaceBetween = requiredPadding / (objectsToLayout.length - 1);
2817
+ var nextElementTop = margin.top;
2818
+ for (var _i = 0, objectsToLayout_1 = objectsToLayout; _i < objectsToLayout_1.length; _i++) {
2819
+ var element = objectsToLayout_1[_i];
2820
+ var elementHeight = element.getBoundingBox().height;
2821
+ element.setPosition({
2822
+ top: nextElementTop
2823
+ });
2824
+ element.setCoords();
2825
+ nextElementTop += elementHeight + spaceBetween;
2826
+ }
2827
+ this.redraw();
2828
+ };
2829
+ /**
2830
+ * @override
2831
+ * @inheritDoc
2832
+ */
2833
+ AbstractInteractiveCanvas.prototype.getSelection = function () {
2834
+ return this.selection$.value;
2835
+ };
2836
+ /**
2837
+ * @override
2838
+ * @inheritDoc
2839
+ */
2840
+ AbstractInteractiveCanvas.prototype.getSelection$ = function () {
2841
+ return this.selection$;
2842
+ };
2843
+ /**
2844
+ * @override
2845
+ * @inheritDoc
2846
+ */
2847
+ AbstractInteractiveCanvas.prototype.select = function (object) {
2848
+ var concreteField = this.findObject(object.getId());
2849
+ if (!concreteField) {
2850
+ console.error("Attempted to select unknown object", object);
2851
+ return;
2852
+ }
2853
+ this.selectFabricObject(concreteField.getFabricObjectInternal());
2854
+ this.fabricCanvas.renderAll();
2855
+ };
2856
+ /**
2857
+ * @override
2858
+ * @inheritDoc
2859
+ */
2860
+ AbstractInteractiveCanvas.prototype.clearSelection = function () {
2861
+ this.fabricCanvas.discardActiveObject();
2862
+ this.fabricCanvas.renderAll();
2863
+ };
2864
+ AbstractInteractiveCanvas.prototype.setMultiSelect = function (value) {
2865
+ this.fabricCanvas.selection = value;
2866
+ this.fabricCanvas.selectionKey = value ? "shiftKey" : null;
2867
+ };
2868
+ /**
2869
+ * @override
2870
+ * @inheritDoc
2871
+ */
2872
+ AbstractInteractiveCanvas.prototype.clear = function () {
2873
+ this.fabricCanvas.clear();
2874
+ this.setBackgroundColor("#FFFFFF");
2875
+ this.objects$.next([]);
2876
+ };
2877
+ /**
2878
+ * @override
2879
+ * @inheritDoc
2880
+ */
2881
+ AbstractInteractiveCanvas.prototype.save = function () {
2882
+ var objects = _(this.objects$.value)
2883
+ .map(function (x) { return x.persist(); })
2884
+ .value();
2885
+ var includedProperties = ["id"];
2886
+ var json = this.fabricCanvas.toJSON(includedProperties);
2887
+ var state = {
2888
+ dimensions: this.dimensions$.value,
2889
+ canvasJson: JSON.stringify(json),
2890
+ objects: objects,
2891
+ backgroundColor: this.backgroundColor$.value
2892
+ };
2893
+ console.debug("Saving canvas state", state);
2894
+ return state;
2895
+ };
2896
+ /**
2897
+ * @override
2898
+ * @inheritDoc
2899
+ */
2900
+ AbstractInteractiveCanvas.prototype.load = function (canvasState) {
2901
+ return __awaiter(this, void 0, void 0, function () {
2902
+ var json_1;
2903
+ var _this = this;
2904
+ return __generator(this, function (_a) {
2905
+ switch (_a.label) {
2906
+ case 0:
2907
+ console.debug("Loading canvas state", canvasState);
2908
+ this.setBaseDimensions(canvasState.dimensions);
2909
+ if (!(canvasState.canvasJson != undefined)) return [3 /*break*/, 2];
2910
+ json_1 = JSON.parse(canvasState.canvasJson);
2911
+ return [4 /*yield*/, new Promise(function (resolve) {
2912
+ _this.fabricCanvas.loadFromJSON(json_1, function () { return resolve(); });
2913
+ })];
2914
+ case 1:
2915
+ _a.sent();
2916
+ _a.label = 2;
2917
+ case 2:
2918
+ this.setBackgroundColor(canvasState.backgroundColor);
2919
+ this.bindFields(canvasState.objects);
2920
+ this.removePersistedBullets();
2921
+ this.layoutManager$.value.onInit();
2922
+ return [2 /*return*/];
2923
+ }
2924
+ });
2925
+ });
2926
+ };
2927
+ /**
2928
+ * Another hack for bullet points... because they use canvas objects to render the bullets, they get saved when the canvas is persisted... and then loaded into a new canvas, but there's
2929
+ * nothing linking them to the field that needs bullets, so they end up duplicating every time the canvas is saved/loaded. Since we don't use circles for anything else, this just
2930
+ * deletes all circles on canvas load.
2931
+ */
2932
+ AbstractInteractiveCanvas.prototype.removePersistedBullets = function () {
2933
+ var _this = this;
2934
+ var objects = this.fabricCanvas.getObjects();
2935
+ _.each(objects, function (object) {
2936
+ if (object.type === "circle")
2937
+ _this.removeFabricObject(object);
2938
+ });
2939
+ };
2940
+ /**
2941
+ * @override
2942
+ * @inheritDoc
2943
+ */
2944
+ AbstractInteractiveCanvas.prototype.toSvg = function () {
2945
+ var _this = this;
2946
+ var widthInMm = _.round(this.dimensions$.value.widthMm, 1) + "mm";
2947
+ var heightInMm = _.round(this.dimensions$.value.heightMm, 1) + "mm";
2948
+ var options = {
2949
+ width: widthInMm,
2950
+ height: heightInMm,
2951
+ suppressPreamble: true,
2952
+ encoding: null
2953
+ };
2954
+ var svg = this.executeWithNormalizedCanvas(function () { return _this.fabricCanvas.toSVG(options); });
2955
+ this.redraw();
2956
+ return svg;
2957
+ };
2958
+ /**
2959
+ * @override
2960
+ * @inheritDoc
2961
+ */
2962
+ AbstractInteractiveCanvas.prototype.toImage = function () {
2963
+ var _this = this;
2964
+ var options = {
2965
+ format: "png",
2966
+ multiplier: this.IMAGE_CAPTURE_COEFFICIENT,
2967
+ enableRetinaScaling: true
2968
+ };
2969
+ console.debug("Capturing canvas image", options);
2970
+ var base64 = this.executeWithNormalizedCanvas(function () { return _this.fabricCanvas.toDataURL(options); });
2971
+ return _.replace(base64, /^data:.*;base64,/, "");
2972
+ };
2973
+ /**
2974
+ * @override
2975
+ * @inheritDoc
2976
+ */
2977
+ AbstractInteractiveCanvas.prototype.createPNGStream = function () {
2978
+ return this.fabricCanvas.createPNGStream();
2979
+ };
2980
+ /**
2981
+ * Redraw the canvas.
2982
+ */
2983
+ AbstractInteractiveCanvas.prototype.redraw = function () {
2984
+ this.fabricCanvas.renderAll();
2985
+ };
2986
+ AbstractInteractiveCanvas.prototype.syncObjectList = function () {
2987
+ var _this = this;
2988
+ var newObjectList = _(this.fabricCanvas.getObjects())
2989
+ .map(function (obj) { return _this.findObject(obj.id); })
2990
+ .filter(function (x) { return x !== undefined; })
2991
+ .value();
2992
+ this.objects$.next(newObjectList);
2993
+ this.onObjectListChange();
2994
+ };
2995
+ /**
2996
+ * @override
2997
+ * @inheritDoc
2998
+ */
2999
+ AbstractInteractiveCanvas.prototype.notifyObjectListChanged = function () {
3000
+ this.onObjectListChange();
3001
+ };
3002
+ /**
3003
+ * @override
3004
+ * @inheritDoc
3005
+ */
3006
+ AbstractInteractiveCanvas.prototype.notifyTextChanged = function () {
3007
+ this.onTextChange();
3008
+ };
3009
+ /**
3010
+ * @override
3011
+ * @inheritDoc
3012
+ */
3013
+ AbstractInteractiveCanvas.prototype.notifyMarginChanged = function () {
3014
+ this.onMarginChange();
3015
+ };
3016
+ AbstractInteractiveCanvas.prototype.removeFabricObject = function (obj) {
3017
+ this.fabricCanvas.remove(obj);
3018
+ };
3019
+ AbstractInteractiveCanvas.prototype.selectFabricObject = function (object) {
3020
+ this.fabricCanvas.setActiveObject(object);
3021
+ };
3022
+ AbstractInteractiveCanvas.prototype.onTextChange = function () {
3023
+ this.layoutManager$.value.onTextChange();
3024
+ };
3025
+ AbstractInteractiveCanvas.prototype.onObjectListChange = function () {
3026
+ this.layoutManager$.value.onObjectListChange();
3027
+ };
3028
+ AbstractInteractiveCanvas.prototype.onDimensionsChange = function () {
3029
+ this.layoutManager$.value.onCanvasDimensionsChange();
3030
+ };
3031
+ AbstractInteractiveCanvas.prototype.onMarginChange = function () {
3032
+ this.layoutManager$.value.onMarginChange();
3033
+ };
3034
+ AbstractInteractiveCanvas.prototype.bindFields = function (persistedFields) {
3035
+ var _this = this;
3036
+ console.debug("Binding fields", persistedFields);
3037
+ var bound = _(persistedFields)
3038
+ .flatMap(function (field) {
3039
+ try {
3040
+ return [_this.bindField(field)];
3041
+ }
3042
+ catch (e) {
3043
+ console.error("Could not bind field", e, field);
3044
+ return []; //skip
3045
+ }
3046
+ })
3047
+ .value();
3048
+ console.debug("Bound fields", bound);
3049
+ this.objects$.next(bound);
3050
+ };
3051
+ AbstractInteractiveCanvas.prototype.bindField = function (persistedField) {
3052
+ console.debug("Binding field", persistedField);
3053
+ var fabricObject = this.findFabricObject(persistedField.id);
3054
+ switch (persistedField.type) {
3055
+ case exports.ObjectType.TEXT:
3056
+ return new Text(this, fabricObject, persistedField);
3057
+ case exports.ObjectType.RECTANGLE:
3058
+ return new Rectangle(this, fabricObject, persistedField);
3059
+ case exports.ObjectType.BORDER:
3060
+ return new Border(this, fabricObject, persistedField);
3061
+ case exports.ObjectType.CUTOFF:
3062
+ return new Cutoff(this, fabricObject, persistedField);
3063
+ case exports.ObjectType.IMAGE:
3064
+ case exports.ObjectType.LIBRARY_IMAGE:
3065
+ return new Image(this, fabricObject, persistedField);
3066
+ case exports.ObjectType.HORIZONTAL_RULE:
3067
+ return new HorizontalRule(this, fabricObject, persistedField);
3068
+ case exports.ObjectType.VERTICAL_RULE:
3069
+ return new VerticalRule(this, fabricObject, persistedField);
3070
+ default:
3071
+ throw new Error("Unknown field type: [" + persistedField.type + "]");
3072
+ }
3073
+ };
3074
+ AbstractInteractiveCanvas.prototype.findFabricObject = function (id) {
3075
+ var objects = this.fabricCanvas.getObjects();
3076
+ var fabricObject = _.find(objects, function (o) { return o.id == id; });
3077
+ if (!fabricObject) {
3078
+ throw new Error("Cannot find fabric object with id [" + id + "]");
3079
+ }
3080
+ return fabricObject;
3081
+ };
3082
+ AbstractInteractiveCanvas.prototype.findObject = function (id) {
3083
+ //Don't use strict compare here. fabric ids are numbers while ad builder ids are strings... mostly.
3084
+ return _.find(this.objects$.value, function (object) { return object.getId() == id; });
3085
+ };
3086
+ /**
3087
+ * Reset zoom and canvas dimensions to 1:1 scale, execute a function, then return the canvas to
3088
+ * the previous values.
3089
+ * @param func Function to execute.
3090
+ */
3091
+ AbstractInteractiveCanvas.prototype.executeWithNormalizedCanvas = function (func) {
3092
+ this.updateCanvasDimensions(this.dimensions$.value, 1);
3093
+ var response;
3094
+ try {
3095
+ response = func();
3096
+ }
3097
+ finally {
3098
+ this.updateCanvasDimensions(this.dimensions$.value, this.zoom$.value);
3099
+ }
3100
+ return response;
3101
+ };
3102
+ /**
3103
+ * Update the actual dimensions of the canvas by multiplying the requested dimensions by the current zoom factor.
3104
+ */
3105
+ AbstractInteractiveCanvas.prototype.updateCanvasDimensions = function (dims, zoom) {
3106
+ var width = dims.widthPx * zoom;
3107
+ var height = dims.heightPx * zoom;
3108
+ console.debug("Updating canvas dimensions: zoom: " + zoom + ", width: " + width + ", height: " + height);
3109
+ this.fabricCanvas.setZoom(zoom);
3110
+ this.fabricCanvas.setDimensions({
3111
+ width: width,
3112
+ height: height
3113
+ });
3114
+ };
3115
+ AbstractInteractiveCanvas.prototype.onProfileChanged = function (profile) {
3116
+ this.setMultiSelect(profile.allowMultiSelect);
3117
+ this.layoutManager$.value.onProfileChange(profile);
3118
+ console.debug("Canvas profile set", profile);
3119
+ };
3120
+ AbstractInteractiveCanvas.prototype.getFieldByCanvasObject = function (object) {
3121
+ if (!object) {
3122
+ return null;
3123
+ }
3124
+ return _.find(this.objects$.value, function (field) { return field.getId() == object.id; });
3125
+ };
3126
+ AbstractInteractiveCanvas.prototype.getFieldsByCanvasObject = function (objects) {
3127
+ var _this = this;
3128
+ return _(objects)
3129
+ .map(function (obj) { return _this.getFieldByCanvasObject(obj); })
3130
+ .reject(function (x) { return !x; })
3131
+ .value();
3132
+ };
3133
+ AbstractInteractiveCanvas.prototype.calculateImageCaptureCoefficient = function () {
3134
+ var precision = 3;
3135
+ var devicePixelRatio = this.devicePixelRatio || 1;
3136
+ return _.round(2 / devicePixelRatio, precision);
3137
+ };
3138
+ AbstractInteractiveCanvas.prototype.randomId = function () {
3139
+ var min = 0;
3140
+ var max = 999;
3141
+ var id = Math.floor(Math.random() * (max - min)) + min;
3142
+ return (new Date()).getTime() + "" + id;
3143
+ };
3144
+ AbstractInteractiveCanvas.prototype.getLowestTextPoint = function () {
3145
+ return _(this.objects$.value)
3146
+ .filter(function (object) { return object.getType() === exports.ObjectType.TEXT; })
3147
+ .map(function (text) { return text.getDimensions().top.px + text.getDimensions().height.px; })
3148
+ .reduce(function (x, y) { return Math.max(x, y); }, 0);
3149
+ };
3150
+ AbstractInteractiveCanvas.prototype.trackNewObject = function (object) {
3151
+ this.objects$.next(__spreadArrays(this.objects$.value, [object]));
3152
+ };
3153
+ AbstractInteractiveCanvas.prototype.dimensionsExceedRestrictions = function (dimensions) {
3154
+ var restrictions = this.dimensionRestrictions$.value;
3155
+ return tsOptchain.oc(restrictions).height.min() != undefined && dimensions.height < tsOptchain.oc(restrictions).height.min()
3156
+ || tsOptchain.oc(restrictions).height.max() != undefined && dimensions.height > tsOptchain.oc(restrictions).height.max()
3157
+ || tsOptchain.oc(restrictions).width.min() != undefined && dimensions.width < tsOptchain.oc(restrictions).width.min()
3158
+ || tsOptchain.oc(restrictions).width.max() != undefined && dimensions.width > tsOptchain.oc(restrictions).width.max()
3159
+ || tsOptchain.oc(restrictions).volume.min() != undefined && dimensions.height * dimensions.width < tsOptchain.oc(restrictions).volume.min()
3160
+ || tsOptchain.oc(restrictions).volume.max() != undefined && dimensions.height * dimensions.width > tsOptchain.oc(restrictions).volume.max();
3161
+ };
3162
+ return AbstractInteractiveCanvas;
3163
+ }());
3164
+ var SelectionData = /** @class */ (function () {
3165
+ function SelectionData(objects) {
3166
+ this.objects = objects;
3167
+ this.empty = this.objects.length < 1;
3168
+ var selectedObject = this.objects[0];
3169
+ this.isText = selectedObject
3170
+ && selectedObject.getType() === exports.ObjectType.TEXT
3171
+ && selectedObject.isEditing();
3172
+ }
3173
+ return SelectionData;
3174
+ }());
3175
+
3176
+ var HeadlessInteractiveCanvas = /** @class */ (function (_super) {
3177
+ __extends(HeadlessInteractiveCanvas, _super);
3178
+ function HeadlessInteractiveCanvas() {
3179
+ return _super.call(this, fabric.fabric, new fabric.fabric.StaticCanvas(null, { width: 640, height: 480 }), null) || this;
3180
+ }
3181
+ /**
3182
+ * @override
3183
+ */
3184
+ HeadlessInteractiveCanvas.prototype.selectFabricObject = function (object) {
3185
+ //no-op
3186
+ };
3187
+ return HeadlessInteractiveCanvas;
3188
+ }(AbstractInteractiveCanvas));
3189
+
3190
+ var InteractiveCanvas = /** @class */ (function (_super) {
3191
+ __extends(InteractiveCanvas, _super);
3192
+ function InteractiveCanvas(elementId, devicePixelRatio) {
3193
+ var _this = _super.call(this, window['fabric'], new window['fabric'].Canvas(elementId), devicePixelRatio) || this;
3194
+ _this.devicePixelRatio = devicePixelRatio;
3195
+ //Initialize watchers
3196
+ _this.fabricCanvas.on("selection:updated", function () { return _this.onFabricSelectionChanged(); });
3197
+ _this.fabricCanvas.on("selection:created", function () { return _this.onFabricSelectionChanged(); });
3198
+ _this.fabricCanvas.on("selection:cleared", function () { return _this.onFabricSelectionChanged(); });
3199
+ _this.fabricCanvas.on("text:editing:entered", function () { return _this.onTextEditing(); });
3200
+ _this.fabricCanvas.on("text:editing:exited", function () { return _this.onTextEditing(); });
3201
+ _this.fabricCanvas.on("text:changed", function () { return _this.onTextChange(); });
3202
+ return _this;
3203
+ }
3204
+ InteractiveCanvas.prototype.onFabricSelectionChanged = function () {
3205
+ var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
3206
+ console.debug("Selection changed", selected);
3207
+ this.selection$.next(new SelectionData(selected));
3208
+ this.enterTextSelectionModeIfRequired();
3209
+ };
3210
+ InteractiveCanvas.prototype.enterTextSelectionModeIfRequired = function () {
3211
+ if (!this.profile$.value.enterTextEditImmediatelyOnSelect && !this.layoutManager$.value.enterTextEditImmediatelyOnSelect)
3212
+ return;
3213
+ if (!this.selection$.value || !this.selection$.value.objects[0] || this.selection$.value.objects[0].getType() !== exports.ObjectType.TEXT)
3214
+ return;
3215
+ var text = this.selection$.value.objects[0];
3216
+ text.enterEditing();
3217
+ };
3218
+ InteractiveCanvas.prototype.onTextEditing = function () {
3219
+ var selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
3220
+ this.selection$.next(new SelectionData(selected));
3221
+ };
3222
+ return InteractiveCanvas;
3223
+ }(AbstractInteractiveCanvas));
3224
+
3225
+ exports.AbstractCanvasObject = AbstractCanvasObject;
3226
+ exports.AbstractInteractiveCanvas = AbstractInteractiveCanvas;
3227
+ exports.AbstractLayoutManager = AbstractLayoutManager;
3228
+ exports.AdvancedLayoutManager = AdvancedLayoutManager;
3229
+ exports.Border = Border;
3230
+ exports.CanvasObjectData = CanvasObjectData;
3231
+ exports.Cutoff = Cutoff;
3232
+ exports.DefaultCanvasProfile = DefaultCanvasProfile;
3233
+ exports.Font = Font;
3234
+ exports.FontLibrary = FontLibrary;
3235
+ exports.HeadlessInteractiveCanvas = HeadlessInteractiveCanvas;
3236
+ exports.HorizontalRule = HorizontalRule;
3237
+ exports.Image = Image;
3238
+ exports.InteractiveCanvas = InteractiveCanvas;
3239
+ exports.PixelCanvasDimensions = PixelCanvasDimensions;
3240
+ exports.Print6ColCanvasDimensions = Print6ColCanvasDimensions;
3241
+ exports.Print8ColCanvasDimensions = Print8ColCanvasDimensions;
3242
+ exports.Rectangle = Rectangle;
3243
+ exports.SelectionData = SelectionData;
3244
+ exports.StandardLayoutManager = StandardLayoutManager;
3245
+ exports.Text = Text;
3246
+ exports.UNKNOWN_FONT = UNKNOWN_FONT;
3247
+ exports.UnknownFont = UnknownFont;
3248
+ exports.VerticalRule = VerticalRule;
3249
+ exports.isMutableBackgroundColor = isMutableBackgroundColor;
3250
+ exports.isMutableColor = isMutableColor;
3251
+ exports.isMutableImage = isMutableImage;
3252
+ exports.isMutablePosition = isMutablePosition;
3253
+ exports.isMutableText = isMutableText;
3254
+ exports.isMutableTextStyle = isMutableTextStyle;