@leapfrog/interactive-canvas 2.0.25-beta-11 → 2.0.25-beta-13
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.
- package/dist/abstract-interactive-canvas.d.ts +0 -2
- package/dist/interactive-canvas.d.ts +1 -0
- package/dist/interactive-canvas.es.js +85 -126
- package/dist/interactive-canvas.js +85 -126
- package/dist/layout/advanced-layout-manager.d.ts +0 -1
- package/dist/layout/standard-layout-manager.d.ts +0 -1
- package/dist/object/impl/text.d.ts +0 -2
- package/package.json +1 -1
|
@@ -340,10 +340,8 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
|
|
|
340
340
|
* @inheritDoc
|
|
341
341
|
*/
|
|
342
342
|
cloneObject(sourceObject: FabricObject, objectData: CanvasObjectData): Promise<void>;
|
|
343
|
-
private redrawScheduled;
|
|
344
343
|
/**
|
|
345
344
|
* Redraw the canvas.
|
|
346
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
347
345
|
*/
|
|
348
346
|
redraw(): void;
|
|
349
347
|
syncObjectList(): void;
|
|
@@ -232,15 +232,9 @@ class ResizeCanvasLayoutFunction {
|
|
|
232
232
|
const targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
|
|
233
233
|
if (currentDimensions.height !== targetHeight.height) {
|
|
234
234
|
canvas.setDimensions(targetHeight);
|
|
235
|
-
canvas.getObjectsInternal().forEach((object) => {
|
|
236
|
-
var _a;
|
|
237
|
-
const canvasObj = canvas.getObjectsByTypeInternal(object.type).find(o => o.getId() === object.getId());
|
|
238
|
-
if (canvasObj && (((_a = canvasObj.isPinToBottom) === null || _a === void 0 ? void 0 : _a.call(canvasObj)) || object.top > currentDimensions.heightPx * 0.5)) {
|
|
239
|
-
object.setCoords();
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
canvas.redraw();
|
|
243
235
|
}
|
|
236
|
+
canvas.getObjectsInternal().forEach((object) => object.setCoords());
|
|
237
|
+
canvas.redraw();
|
|
244
238
|
}
|
|
245
239
|
}
|
|
246
240
|
|
|
@@ -268,21 +262,13 @@ class AdvancedLayoutManager extends AbstractLayoutManager {
|
|
|
268
262
|
this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
|
|
269
263
|
this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
|
|
270
264
|
this.resizeCanvas = new ResizeCanvasLayoutFunction();
|
|
271
|
-
this.dimensionsLayoutScheduled = false;
|
|
272
265
|
}
|
|
273
266
|
onCanvasDimensionsChange() {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
this.
|
|
278
|
-
|
|
279
|
-
this.pinToBottom.execute(this.canvas);
|
|
280
|
-
this.repositionCutoffs.execute(this.canvas);
|
|
281
|
-
this.repositionBorders.execute(this.canvas);
|
|
282
|
-
this.repositionBackgrounds.execute(this.canvas);
|
|
283
|
-
this.redrawAll.execute(this.canvas);
|
|
284
|
-
this.dimensionsLayoutScheduled = false;
|
|
285
|
-
});
|
|
267
|
+
this.pinToBottom.execute(this.canvas);
|
|
268
|
+
this.repositionCutoffs.execute(this.canvas);
|
|
269
|
+
this.repositionBorders.execute(this.canvas);
|
|
270
|
+
this.repositionBackgrounds.execute(this.canvas);
|
|
271
|
+
this.redrawAll.execute(this.canvas);
|
|
286
272
|
}
|
|
287
273
|
onTextChange() {
|
|
288
274
|
this.resizeCanvas.execute(this.canvas);
|
|
@@ -310,6 +296,7 @@ class StackObjectsLayoutFunction {
|
|
|
310
296
|
const footerObjects = objects[0];
|
|
311
297
|
const bodyObjects = objects[1];
|
|
312
298
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
299
|
+
canvas.redraw();
|
|
313
300
|
//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.
|
|
314
301
|
this.applyWidths(allObjects, bodyWidth);
|
|
315
302
|
const bodyRows = this.getRows(bodyObjects);
|
|
@@ -396,11 +383,7 @@ class StackObjectsLayoutFunction {
|
|
|
396
383
|
object.setPosition({
|
|
397
384
|
width: actualWidth
|
|
398
385
|
});
|
|
399
|
-
|
|
400
|
-
_(objects).forEach((object) => {
|
|
401
|
-
if (object.getType() !== ObjectType.VERTICAL_RULE) {
|
|
402
|
-
object.updateDimensions();
|
|
403
|
-
}
|
|
386
|
+
object.updateDimensions();
|
|
404
387
|
});
|
|
405
388
|
}
|
|
406
389
|
adjustCanvasSize(canvas, requiredHeight) {
|
|
@@ -473,7 +456,6 @@ class StandardLayoutManager extends AbstractLayoutManager {
|
|
|
473
456
|
this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
|
|
474
457
|
this.stackObjects = new StackObjectsLayoutFunction();
|
|
475
458
|
this.updateObjectDimensions = new UpdateObjectDimensionsLayoutFunction();
|
|
476
|
-
this.layoutBatchScheduled = false;
|
|
477
459
|
}
|
|
478
460
|
/**
|
|
479
461
|
* @override
|
|
@@ -515,19 +497,12 @@ class StandardLayoutManager extends AbstractLayoutManager {
|
|
|
515
497
|
this.stackAndRedraw();
|
|
516
498
|
}
|
|
517
499
|
stackAndRedraw() {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
this.
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
this.repositionCutoffs.execute(this.canvas);
|
|
525
|
-
this.repositionBorders.execute(this.canvas);
|
|
526
|
-
this.repositionBackgrounds.execute(this.canvas);
|
|
527
|
-
this.updateObjectDimensions.execute(this.canvas);
|
|
528
|
-
this.redrawAll.execute(this.canvas);
|
|
529
|
-
this.layoutBatchScheduled = false;
|
|
530
|
-
});
|
|
500
|
+
this.stackObjects.execute(this.canvas);
|
|
501
|
+
this.repositionCutoffs.execute(this.canvas);
|
|
502
|
+
this.repositionBorders.execute(this.canvas);
|
|
503
|
+
this.repositionBackgrounds.execute(this.canvas);
|
|
504
|
+
this.updateObjectDimensions.execute(this.canvas);
|
|
505
|
+
this.redrawAll.execute(this.canvas);
|
|
531
506
|
}
|
|
532
507
|
}
|
|
533
508
|
|
|
@@ -1067,8 +1042,7 @@ class AbstractCanvasObject {
|
|
|
1067
1042
|
mt: options.allowScale,
|
|
1068
1043
|
mr: options.allowScale,
|
|
1069
1044
|
mb: options.allowScale,
|
|
1070
|
-
mtr: options.allowRotate
|
|
1071
|
-
// dragControl: options.allowMove // Show drag control when movement is allowed
|
|
1045
|
+
mtr: options.allowRotate
|
|
1072
1046
|
});
|
|
1073
1047
|
}
|
|
1074
1048
|
}
|
|
@@ -1806,42 +1780,15 @@ var ObjectType;
|
|
|
1806
1780
|
class Text extends AbstractCanvasObject {
|
|
1807
1781
|
constructor(canvas, fabricObject, persistedField) {
|
|
1808
1782
|
super(ObjectType.TEXT, canvas, fabricObject, persistedField);
|
|
1809
|
-
this.notifyCanvasTimeout = null;
|
|
1810
|
-
this.NOTIFY_DELAY_MS = 150; // Debounce canvas notifications
|
|
1811
1783
|
this.canvas = canvas;
|
|
1812
1784
|
this.fontLibrary = canvas.getFontLibrary();
|
|
1813
1785
|
this.baseComponentHeight = this.fabricObject.height;
|
|
1814
1786
|
this.text$ = new BehaviorSubject(this.fabricObject.text);
|
|
1815
1787
|
this.data.userText = this.fabricObject.text;
|
|
1816
1788
|
this.textSelection$ = new BehaviorSubject(new TextSelection(this.fabricObject, this.fontLibrary));
|
|
1817
|
-
this.fabricObject.set({
|
|
1818
|
-
strokeWidth: 0,
|
|
1819
|
-
perPixelTargetFind: false // Disable per-pixel detection for this object
|
|
1820
|
-
});
|
|
1789
|
+
this.fabricObject.set({ strokeWidth: 0 });
|
|
1821
1790
|
this.fabricObject.on("changed", () => this.onTextChange());
|
|
1822
1791
|
this.fabricObject.on("selection:changed", () => this.onSelectionChange());
|
|
1823
|
-
this.fabricObject.containsPoint.bind(this.fabricObject);
|
|
1824
|
-
this.fabricObject.containsPoint = function (point) {
|
|
1825
|
-
const coords = this.getCoords();
|
|
1826
|
-
if (coords.length !== 4)
|
|
1827
|
-
return false;
|
|
1828
|
-
let inside = false;
|
|
1829
|
-
for (let i = 0, j = coords.length - 1; i < coords.length; j = i++) {
|
|
1830
|
-
const xi = coords[i].x, yi = coords[i].y;
|
|
1831
|
-
const xj = coords[j].x, yj = coords[j].y;
|
|
1832
|
-
const intersect = ((yi > point.y) !== (yj > point.y))
|
|
1833
|
-
&& (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi);
|
|
1834
|
-
if (intersect)
|
|
1835
|
-
inside = !inside;
|
|
1836
|
-
}
|
|
1837
|
-
return inside;
|
|
1838
|
-
};
|
|
1839
|
-
this.fabricObject.on("mousedown", (e) => {
|
|
1840
|
-
var _a;
|
|
1841
|
-
if (!this.fabricObject.isEditing) {
|
|
1842
|
-
(_a = e.e) === null || _a === void 0 ? void 0 : _a.preventDefault();
|
|
1843
|
-
}
|
|
1844
|
-
});
|
|
1845
1792
|
this.applyBulletListMonkeyPatches();
|
|
1846
1793
|
}
|
|
1847
1794
|
/**
|
|
@@ -2451,7 +2398,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2451
2398
|
lockMovementY: true,
|
|
2452
2399
|
hasControls: false,
|
|
2453
2400
|
selectable: false,
|
|
2454
|
-
// evented: false, // Don't capture mouse events - allows clicks to pass through to textbox
|
|
2455
2401
|
originX: "left",
|
|
2456
2402
|
originY: "top"
|
|
2457
2403
|
});
|
|
@@ -2546,7 +2492,7 @@ class Text extends AbstractCanvasObject {
|
|
|
2546
2492
|
text: `${lineNumber}.`
|
|
2547
2493
|
});
|
|
2548
2494
|
}
|
|
2549
|
-
if (method === "fillText" && this.
|
|
2495
|
+
if (method === "fillText" && this.fabricObject.left <= 3) {
|
|
2550
2496
|
left = left + this.getOrderedListMargin();
|
|
2551
2497
|
}
|
|
2552
2498
|
this.fabricObject.dirty = true;
|
|
@@ -2558,24 +2504,13 @@ class Text extends AbstractCanvasObject {
|
|
|
2558
2504
|
* @inheritDoc
|
|
2559
2505
|
*/
|
|
2560
2506
|
updateFabricObjectBehavior() {
|
|
2561
|
-
// DON'T call super.updateFabricObjectBehavior() for textboxes
|
|
2562
|
-
// because it locks movement which interferes with text editing in Fabric v7
|
|
2563
2507
|
super.updateFabricObjectBehavior();
|
|
2564
2508
|
const profile = this.canvas.getProfile();
|
|
2565
2509
|
const allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
|
|
2566
|
-
// For textboxes, we keep them moveable but hide all controls except drag control
|
|
2567
|
-
// This allows text editing to work properly while still supporting drag via the icon
|
|
2568
2510
|
this.fabricObject.set({
|
|
2569
|
-
lockMovementX: false, // Allow dragging
|
|
2570
|
-
lockMovementY: false, // Allow dragging
|
|
2571
2511
|
lockScalingY: true,
|
|
2572
2512
|
lockScalingX: this.isPinToBottom(),
|
|
2573
|
-
lockScalingFlip: true
|
|
2574
|
-
lockRotation: true,
|
|
2575
|
-
selectable: true,
|
|
2576
|
-
editable: false, // Only enable on double-click
|
|
2577
|
-
hoverCursor: "move", // Show move cursor by default
|
|
2578
|
-
moveCursor: "move",
|
|
2513
|
+
lockScalingFlip: true
|
|
2579
2514
|
});
|
|
2580
2515
|
this.fabricObject.setControlsVisibility({
|
|
2581
2516
|
tl: false,
|
|
@@ -2585,50 +2520,35 @@ class Text extends AbstractCanvasObject {
|
|
|
2585
2520
|
ml: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
|
|
2586
2521
|
mt: false,
|
|
2587
2522
|
mr: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
|
|
2588
|
-
mb: false
|
|
2589
|
-
mtr: false,
|
|
2523
|
+
mb: false
|
|
2590
2524
|
});
|
|
2591
2525
|
this.redraw();
|
|
2592
2526
|
}
|
|
2593
2527
|
onTextChange() {
|
|
2594
2528
|
this.data.userText = this.fabricObject.text;
|
|
2595
2529
|
this.text$.next(this.fabricObject.text);
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
// Skip expensive getBoundingBox if object is clearly within bounds
|
|
2600
|
-
if (currentLeft + (this.fabricObject.width || 0) > canvasWidth * 0.9) {
|
|
2601
|
-
if (this.getBoundingBox().width > canvasWidth) {
|
|
2602
|
-
this.fabricObject.set({ left: 0, width: canvasWidth });
|
|
2603
|
-
this.redraw();
|
|
2604
|
-
}
|
|
2530
|
+
if (this.getBoundingBox().width > this.canvas.getDimensions().widthPx) {
|
|
2531
|
+
this.fabricObject.set({ left: 0, width: this.canvas.getDimensions().widthPx });
|
|
2532
|
+
this.redraw();
|
|
2605
2533
|
}
|
|
2606
2534
|
}
|
|
2607
2535
|
onDelete() {
|
|
2608
2536
|
this.removeBullets();
|
|
2609
2537
|
}
|
|
2610
2538
|
onSelectionChange() {
|
|
2611
|
-
this.updateTextSelection(
|
|
2539
|
+
this.updateTextSelection();
|
|
2612
2540
|
}
|
|
2613
2541
|
hasTextSelection() {
|
|
2614
2542
|
return this.canvas.getSelection().isText && this.textSelection$.value.length > 0;
|
|
2615
2543
|
}
|
|
2616
|
-
updateTextSelection(
|
|
2544
|
+
updateTextSelection() {
|
|
2617
2545
|
if (this.canvas.headless)
|
|
2618
2546
|
return;
|
|
2619
2547
|
this.textSelection$.next(new TextSelection(this.fabricObject, this.fontLibrary));
|
|
2620
|
-
|
|
2621
|
-
this.notifyCanvasOfTextChanges();
|
|
2622
|
-
}
|
|
2548
|
+
this.notifyCanvasOfTextChanges();
|
|
2623
2549
|
}
|
|
2624
2550
|
notifyCanvasOfTextChanges() {
|
|
2625
|
-
|
|
2626
|
-
clearTimeout(this.notifyCanvasTimeout);
|
|
2627
|
-
}
|
|
2628
|
-
this.notifyCanvasTimeout = setTimeout(() => {
|
|
2629
|
-
this.canvas.notifyTextChanged();
|
|
2630
|
-
this.notifyCanvasTimeout = null;
|
|
2631
|
-
}, this.NOTIFY_DELAY_MS);
|
|
2551
|
+
this.canvas.notifyTextChanged();
|
|
2632
2552
|
}
|
|
2633
2553
|
}
|
|
2634
2554
|
Text.NEW_LINE = "\n";
|
|
@@ -2794,7 +2714,6 @@ class AbstractInteractiveCanvas {
|
|
|
2794
2714
|
this.devicePixelRatio = devicePixelRatio;
|
|
2795
2715
|
this.fontLibrary = new FontLibrary();
|
|
2796
2716
|
this.dimensionChangeRejections$ = new Subject();
|
|
2797
|
-
this.redrawScheduled = false;
|
|
2798
2717
|
this.IMAGE_CAPTURE_COEFFICIENT = this.calculateImageCaptureCoefficient();
|
|
2799
2718
|
/**
|
|
2800
2719
|
* Fabric defaults to only 2 decimal places when saving, which causes havoc on the scaling of large images.
|
|
@@ -2817,7 +2736,7 @@ class AbstractInteractiveCanvas {
|
|
|
2817
2736
|
this.fabricCanvas.stateful = true;
|
|
2818
2737
|
this.fabricCanvas.preserveObjectStacking = true;
|
|
2819
2738
|
this.fabricCanvas.perPixelTargetFind = true;
|
|
2820
|
-
this.fabricCanvas.targetFindTolerance = 4;
|
|
2739
|
+
this.fabricCanvas.targetFindTolerance = 4;
|
|
2821
2740
|
this.setBackgroundColor("#FFFFFF");
|
|
2822
2741
|
}
|
|
2823
2742
|
/**
|
|
@@ -3121,6 +3040,7 @@ class AbstractInteractiveCanvas {
|
|
|
3121
3040
|
*/
|
|
3122
3041
|
addImageObject(imageUrl) {
|
|
3123
3042
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3043
|
+
// Don't let the image be more than half the canvas in size.
|
|
3124
3044
|
const maxSizeScale = 2;
|
|
3125
3045
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3126
3046
|
const options = { crossOrigin: "anonymous" };
|
|
@@ -3132,6 +3052,7 @@ class AbstractInteractiveCanvas {
|
|
|
3132
3052
|
if (curWidth > maxWidth) {
|
|
3133
3053
|
newScale = maxWidth / curWidth;
|
|
3134
3054
|
}
|
|
3055
|
+
// Set image properties and add to the canvas
|
|
3135
3056
|
const fabricImage = new this.fabric.Image(image, {
|
|
3136
3057
|
id: id,
|
|
3137
3058
|
scaleX: newScale,
|
|
@@ -3151,6 +3072,7 @@ class AbstractInteractiveCanvas {
|
|
|
3151
3072
|
return object;
|
|
3152
3073
|
}
|
|
3153
3074
|
else {
|
|
3075
|
+
// Browser-side logic
|
|
3154
3076
|
return yield new Promise((resolve) => {
|
|
3155
3077
|
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3156
3078
|
const id = this.randomId();
|
|
@@ -3202,13 +3124,14 @@ class AbstractInteractiveCanvas {
|
|
|
3202
3124
|
fontFamily: profile.defaultFont,
|
|
3203
3125
|
textAlign: profile.defaultTextAlignment,
|
|
3204
3126
|
hoverCursor: "move",
|
|
3205
|
-
moveCursor:
|
|
3206
|
-
editable: false,
|
|
3207
|
-
editingBorderColor: '#2196F3',
|
|
3127
|
+
moveCursor: 'move',
|
|
3208
3128
|
multiLine: true,
|
|
3209
3129
|
lineHeight: profile.defaultLineHeight,
|
|
3210
3130
|
charSpacing: profile.defaultCharacterSpacing,
|
|
3131
|
+
perPixelTargetFind: false,
|
|
3132
|
+
targetFindTolerance: 4,
|
|
3211
3133
|
splitByGrapheme: true,
|
|
3134
|
+
editable: false, // Only enable on double-click
|
|
3212
3135
|
padding: 0,
|
|
3213
3136
|
cornerSize: 8,
|
|
3214
3137
|
touchCornerSize: 12
|
|
@@ -3658,17 +3581,9 @@ class AbstractInteractiveCanvas {
|
|
|
3658
3581
|
}
|
|
3659
3582
|
/**
|
|
3660
3583
|
* Redraw the canvas.
|
|
3661
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
3662
3584
|
*/
|
|
3663
3585
|
redraw() {
|
|
3664
|
-
|
|
3665
|
-
return;
|
|
3666
|
-
}
|
|
3667
|
-
this.redrawScheduled = true;
|
|
3668
|
-
requestAnimationFrame(() => {
|
|
3669
|
-
this.fabricCanvas.requestRenderAll();
|
|
3670
|
-
this.redrawScheduled = false;
|
|
3671
|
-
});
|
|
3586
|
+
this.fabricCanvas.requestRenderAll();
|
|
3672
3587
|
}
|
|
3673
3588
|
syncObjectList() {
|
|
3674
3589
|
const newObjectList = _(this.fabricCanvas.getObjects())
|
|
@@ -3794,6 +3709,7 @@ class AbstractInteractiveCanvas {
|
|
|
3794
3709
|
* Update the actual dimensions of the canvas by multiplying the requested dimensions by the current zoom factor.
|
|
3795
3710
|
*/
|
|
3796
3711
|
updateCanvasDimensions(dims, zoom) {
|
|
3712
|
+
this.fabricCanvas.getWidth();
|
|
3797
3713
|
const width = dims.widthPx * zoom;
|
|
3798
3714
|
const height = dims.heightPx * zoom;
|
|
3799
3715
|
this.fabricCanvas.setZoom(zoom);
|
|
@@ -3801,6 +3717,37 @@ class AbstractInteractiveCanvas {
|
|
|
3801
3717
|
width,
|
|
3802
3718
|
height
|
|
3803
3719
|
});
|
|
3720
|
+
/* if (this.layoutManager$.value instanceof AdvancedLayoutManager) {
|
|
3721
|
+
const scaleFactor = width / oldWidth;
|
|
3722
|
+
this.fabricCanvas.calcOffset();
|
|
3723
|
+
const objects = this.fabricCanvas.getObjects();
|
|
3724
|
+
objects.forEach((obj: any) => {
|
|
3725
|
+
obj.set({
|
|
3726
|
+
left: obj.left * scaleFactor,
|
|
3727
|
+
});
|
|
3728
|
+
if (obj.type === "textbox" || obj.type === "text") {
|
|
3729
|
+
obj.set({
|
|
3730
|
+
scaleX: 1,
|
|
3731
|
+
scaleY: 1,
|
|
3732
|
+
width: obj.width * scaleFactor,
|
|
3733
|
+
});
|
|
3734
|
+
obj.initDimensions();
|
|
3735
|
+
} else if (obj.type === "border" || obj.type === "rect") {
|
|
3736
|
+
obj.set({
|
|
3737
|
+
width: obj.width * scaleFactor,
|
|
3738
|
+
scaleX: 1,
|
|
3739
|
+
strokeUniform: true,
|
|
3740
|
+
strokeAlign: "inner",
|
|
3741
|
+
});
|
|
3742
|
+
} else {
|
|
3743
|
+
obj.set({
|
|
3744
|
+
scaleX: obj.scaleX * scaleFactor,
|
|
3745
|
+
});
|
|
3746
|
+
}
|
|
3747
|
+
obj.setCoords();
|
|
3748
|
+
});
|
|
3749
|
+
this.fabricCanvas.requestRenderAll();
|
|
3750
|
+
}*/
|
|
3804
3751
|
}
|
|
3805
3752
|
onProfileChanged(profile) {
|
|
3806
3753
|
this.setMultiSelect(profile.allowMultiSelect);
|
|
@@ -3955,6 +3902,7 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
3955
3902
|
this.fabricCanvas.on("selection:created", (event) => this.onFabricSelectionChanged(event));
|
|
3956
3903
|
this.fabricCanvas.on("selection:cleared", (event) => this.onFabricSelectionChanged(event));
|
|
3957
3904
|
this.fabricCanvas.on("text:editing:entered", () => this.onTextEditing());
|
|
3905
|
+
this.fabricCanvas.on("text:editing:exited", () => this.onTextEditing());
|
|
3958
3906
|
this.fabricCanvas.on("text:editing:exited", (event) => {
|
|
3959
3907
|
this.onTextEditing();
|
|
3960
3908
|
const target = event.target;
|
|
@@ -3963,6 +3911,8 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
3963
3911
|
}
|
|
3964
3912
|
});
|
|
3965
3913
|
this.fabricCanvas.on("text:changed", () => this.onTextChange());
|
|
3914
|
+
// Handle double-click on textbox to enter editing mode
|
|
3915
|
+
// @ts-ignore
|
|
3966
3916
|
this.fabricCanvas.on("mouse:dblclick", (event) => this.onDoubleClick(event));
|
|
3967
3917
|
}
|
|
3968
3918
|
/**
|
|
@@ -3997,20 +3947,29 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
3997
3947
|
selection.setEvent(event);
|
|
3998
3948
|
}
|
|
3999
3949
|
this.selection$.next(selection);
|
|
3950
|
+
this.enterTextSelectionModeIfRequired();
|
|
3951
|
+
}
|
|
3952
|
+
enterTextSelectionModeIfRequired() {
|
|
3953
|
+
var _a, _b;
|
|
3954
|
+
if (!this.profile$.value.enterTextEditImmediatelyOnSelect && !this.layoutManager$.value.enterTextEditImmediatelyOnSelect)
|
|
3955
|
+
return;
|
|
3956
|
+
if (((_b = (_a = this.selection$.value) === null || _a === void 0 ? void 0 : _a.objects[0]) === null || _b === void 0 ? void 0 : _b.getType()) !== ObjectType.TEXT)
|
|
3957
|
+
return;
|
|
3958
|
+
const text = this.selection$.value.objects[0];
|
|
3959
|
+
text.enterEditing();
|
|
4000
3960
|
}
|
|
4001
3961
|
onTextEditing() {
|
|
4002
3962
|
const selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|
|
4003
3963
|
this.selection$.next(new SelectionData(selected));
|
|
4004
3964
|
}
|
|
4005
3965
|
onDoubleClick(event) {
|
|
4006
|
-
var _a, _b;
|
|
4007
3966
|
const target = event.target;
|
|
4008
3967
|
if (target && (target.type === 'textbox' || target.type === 'i-text')) {
|
|
4009
|
-
|
|
4010
|
-
if (!targetIText.isEditing) {
|
|
3968
|
+
if (!target.isEditing) {
|
|
4011
3969
|
target.set({ editable: true, hoverCursor: 'text' });
|
|
4012
|
-
|
|
4013
|
-
|
|
3970
|
+
// target.enterEditing();
|
|
3971
|
+
// target.hiddenTextarea?.focus();
|
|
3972
|
+
this.enterTextSelectionModeIfRequired();
|
|
4014
3973
|
}
|
|
4015
3974
|
}
|
|
4016
3975
|
}
|
|
@@ -253,15 +253,9 @@ class ResizeCanvasLayoutFunction {
|
|
|
253
253
|
const targetHeight = increase.withSize(increase.width, baseDimensions.height + increase.height);
|
|
254
254
|
if (currentDimensions.height !== targetHeight.height) {
|
|
255
255
|
canvas.setDimensions(targetHeight);
|
|
256
|
-
canvas.getObjectsInternal().forEach((object) => {
|
|
257
|
-
var _a;
|
|
258
|
-
const canvasObj = canvas.getObjectsByTypeInternal(object.type).find(o => o.getId() === object.getId());
|
|
259
|
-
if (canvasObj && (((_a = canvasObj.isPinToBottom) === null || _a === void 0 ? void 0 : _a.call(canvasObj)) || object.top > currentDimensions.heightPx * 0.5)) {
|
|
260
|
-
object.setCoords();
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
canvas.redraw();
|
|
264
256
|
}
|
|
257
|
+
canvas.getObjectsInternal().forEach((object) => object.setCoords());
|
|
258
|
+
canvas.redraw();
|
|
265
259
|
}
|
|
266
260
|
}
|
|
267
261
|
|
|
@@ -289,21 +283,13 @@ class AdvancedLayoutManager extends AbstractLayoutManager {
|
|
|
289
283
|
this.repositionCutoffs = new RepositionCutoffsLayoutFunction();
|
|
290
284
|
this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
|
|
291
285
|
this.resizeCanvas = new ResizeCanvasLayoutFunction();
|
|
292
|
-
this.dimensionsLayoutScheduled = false;
|
|
293
286
|
}
|
|
294
287
|
onCanvasDimensionsChange() {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
this.
|
|
299
|
-
|
|
300
|
-
this.pinToBottom.execute(this.canvas);
|
|
301
|
-
this.repositionCutoffs.execute(this.canvas);
|
|
302
|
-
this.repositionBorders.execute(this.canvas);
|
|
303
|
-
this.repositionBackgrounds.execute(this.canvas);
|
|
304
|
-
this.redrawAll.execute(this.canvas);
|
|
305
|
-
this.dimensionsLayoutScheduled = false;
|
|
306
|
-
});
|
|
288
|
+
this.pinToBottom.execute(this.canvas);
|
|
289
|
+
this.repositionCutoffs.execute(this.canvas);
|
|
290
|
+
this.repositionBorders.execute(this.canvas);
|
|
291
|
+
this.repositionBackgrounds.execute(this.canvas);
|
|
292
|
+
this.redrawAll.execute(this.canvas);
|
|
307
293
|
}
|
|
308
294
|
onTextChange() {
|
|
309
295
|
this.resizeCanvas.execute(this.canvas);
|
|
@@ -331,6 +317,7 @@ class StackObjectsLayoutFunction {
|
|
|
331
317
|
const footerObjects = objects[0];
|
|
332
318
|
const bodyObjects = objects[1];
|
|
333
319
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
320
|
+
canvas.redraw();
|
|
334
321
|
//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.
|
|
335
322
|
this.applyWidths(allObjects, bodyWidth);
|
|
336
323
|
const bodyRows = this.getRows(bodyObjects);
|
|
@@ -417,11 +404,7 @@ class StackObjectsLayoutFunction {
|
|
|
417
404
|
object.setPosition({
|
|
418
405
|
width: actualWidth
|
|
419
406
|
});
|
|
420
|
-
|
|
421
|
-
_(objects).forEach((object) => {
|
|
422
|
-
if (object.getType() !== exports.ObjectType.VERTICAL_RULE) {
|
|
423
|
-
object.updateDimensions();
|
|
424
|
-
}
|
|
407
|
+
object.updateDimensions();
|
|
425
408
|
});
|
|
426
409
|
}
|
|
427
410
|
adjustCanvasSize(canvas, requiredHeight) {
|
|
@@ -494,7 +477,6 @@ class StandardLayoutManager extends AbstractLayoutManager {
|
|
|
494
477
|
this.repositionBackgrounds = new RepositionBackgroundsLayoutFunction();
|
|
495
478
|
this.stackObjects = new StackObjectsLayoutFunction();
|
|
496
479
|
this.updateObjectDimensions = new UpdateObjectDimensionsLayoutFunction();
|
|
497
|
-
this.layoutBatchScheduled = false;
|
|
498
480
|
}
|
|
499
481
|
/**
|
|
500
482
|
* @override
|
|
@@ -536,19 +518,12 @@ class StandardLayoutManager extends AbstractLayoutManager {
|
|
|
536
518
|
this.stackAndRedraw();
|
|
537
519
|
}
|
|
538
520
|
stackAndRedraw() {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
this.
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
this.repositionCutoffs.execute(this.canvas);
|
|
546
|
-
this.repositionBorders.execute(this.canvas);
|
|
547
|
-
this.repositionBackgrounds.execute(this.canvas);
|
|
548
|
-
this.updateObjectDimensions.execute(this.canvas);
|
|
549
|
-
this.redrawAll.execute(this.canvas);
|
|
550
|
-
this.layoutBatchScheduled = false;
|
|
551
|
-
});
|
|
521
|
+
this.stackObjects.execute(this.canvas);
|
|
522
|
+
this.repositionCutoffs.execute(this.canvas);
|
|
523
|
+
this.repositionBorders.execute(this.canvas);
|
|
524
|
+
this.repositionBackgrounds.execute(this.canvas);
|
|
525
|
+
this.updateObjectDimensions.execute(this.canvas);
|
|
526
|
+
this.redrawAll.execute(this.canvas);
|
|
552
527
|
}
|
|
553
528
|
}
|
|
554
529
|
|
|
@@ -1088,8 +1063,7 @@ class AbstractCanvasObject {
|
|
|
1088
1063
|
mt: options.allowScale,
|
|
1089
1064
|
mr: options.allowScale,
|
|
1090
1065
|
mb: options.allowScale,
|
|
1091
|
-
mtr: options.allowRotate
|
|
1092
|
-
// dragControl: options.allowMove // Show drag control when movement is allowed
|
|
1066
|
+
mtr: options.allowRotate
|
|
1093
1067
|
});
|
|
1094
1068
|
}
|
|
1095
1069
|
}
|
|
@@ -1827,42 +1801,15 @@ exports.ObjectType = void 0;
|
|
|
1827
1801
|
class Text extends AbstractCanvasObject {
|
|
1828
1802
|
constructor(canvas, fabricObject, persistedField) {
|
|
1829
1803
|
super(exports.ObjectType.TEXT, canvas, fabricObject, persistedField);
|
|
1830
|
-
this.notifyCanvasTimeout = null;
|
|
1831
|
-
this.NOTIFY_DELAY_MS = 150; // Debounce canvas notifications
|
|
1832
1804
|
this.canvas = canvas;
|
|
1833
1805
|
this.fontLibrary = canvas.getFontLibrary();
|
|
1834
1806
|
this.baseComponentHeight = this.fabricObject.height;
|
|
1835
1807
|
this.text$ = new rxjs.BehaviorSubject(this.fabricObject.text);
|
|
1836
1808
|
this.data.userText = this.fabricObject.text;
|
|
1837
1809
|
this.textSelection$ = new rxjs.BehaviorSubject(new TextSelection(this.fabricObject, this.fontLibrary));
|
|
1838
|
-
this.fabricObject.set({
|
|
1839
|
-
strokeWidth: 0,
|
|
1840
|
-
perPixelTargetFind: false // Disable per-pixel detection for this object
|
|
1841
|
-
});
|
|
1810
|
+
this.fabricObject.set({ strokeWidth: 0 });
|
|
1842
1811
|
this.fabricObject.on("changed", () => this.onTextChange());
|
|
1843
1812
|
this.fabricObject.on("selection:changed", () => this.onSelectionChange());
|
|
1844
|
-
this.fabricObject.containsPoint.bind(this.fabricObject);
|
|
1845
|
-
this.fabricObject.containsPoint = function (point) {
|
|
1846
|
-
const coords = this.getCoords();
|
|
1847
|
-
if (coords.length !== 4)
|
|
1848
|
-
return false;
|
|
1849
|
-
let inside = false;
|
|
1850
|
-
for (let i = 0, j = coords.length - 1; i < coords.length; j = i++) {
|
|
1851
|
-
const xi = coords[i].x, yi = coords[i].y;
|
|
1852
|
-
const xj = coords[j].x, yj = coords[j].y;
|
|
1853
|
-
const intersect = ((yi > point.y) !== (yj > point.y))
|
|
1854
|
-
&& (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi);
|
|
1855
|
-
if (intersect)
|
|
1856
|
-
inside = !inside;
|
|
1857
|
-
}
|
|
1858
|
-
return inside;
|
|
1859
|
-
};
|
|
1860
|
-
this.fabricObject.on("mousedown", (e) => {
|
|
1861
|
-
var _a;
|
|
1862
|
-
if (!this.fabricObject.isEditing) {
|
|
1863
|
-
(_a = e.e) === null || _a === void 0 ? void 0 : _a.preventDefault();
|
|
1864
|
-
}
|
|
1865
|
-
});
|
|
1866
1813
|
this.applyBulletListMonkeyPatches();
|
|
1867
1814
|
}
|
|
1868
1815
|
/**
|
|
@@ -2472,7 +2419,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2472
2419
|
lockMovementY: true,
|
|
2473
2420
|
hasControls: false,
|
|
2474
2421
|
selectable: false,
|
|
2475
|
-
// evented: false, // Don't capture mouse events - allows clicks to pass through to textbox
|
|
2476
2422
|
originX: "left",
|
|
2477
2423
|
originY: "top"
|
|
2478
2424
|
});
|
|
@@ -2567,7 +2513,7 @@ class Text extends AbstractCanvasObject {
|
|
|
2567
2513
|
text: `${lineNumber}.`
|
|
2568
2514
|
});
|
|
2569
2515
|
}
|
|
2570
|
-
if (method === "fillText" && this.
|
|
2516
|
+
if (method === "fillText" && this.fabricObject.left <= 3) {
|
|
2571
2517
|
left = left + this.getOrderedListMargin();
|
|
2572
2518
|
}
|
|
2573
2519
|
this.fabricObject.dirty = true;
|
|
@@ -2579,24 +2525,13 @@ class Text extends AbstractCanvasObject {
|
|
|
2579
2525
|
* @inheritDoc
|
|
2580
2526
|
*/
|
|
2581
2527
|
updateFabricObjectBehavior() {
|
|
2582
|
-
// DON'T call super.updateFabricObjectBehavior() for textboxes
|
|
2583
|
-
// because it locks movement which interferes with text editing in Fabric v7
|
|
2584
2528
|
super.updateFabricObjectBehavior();
|
|
2585
2529
|
const profile = this.canvas.getProfile();
|
|
2586
2530
|
const allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
|
|
2587
|
-
// For textboxes, we keep them moveable but hide all controls except drag control
|
|
2588
|
-
// This allows text editing to work properly while still supporting drag via the icon
|
|
2589
2531
|
this.fabricObject.set({
|
|
2590
|
-
lockMovementX: false, // Allow dragging
|
|
2591
|
-
lockMovementY: false, // Allow dragging
|
|
2592
2532
|
lockScalingY: true,
|
|
2593
2533
|
lockScalingX: this.isPinToBottom(),
|
|
2594
|
-
lockScalingFlip: true
|
|
2595
|
-
lockRotation: true,
|
|
2596
|
-
selectable: true,
|
|
2597
|
-
editable: false, // Only enable on double-click
|
|
2598
|
-
hoverCursor: "move", // Show move cursor by default
|
|
2599
|
-
moveCursor: "move",
|
|
2534
|
+
lockScalingFlip: true
|
|
2600
2535
|
});
|
|
2601
2536
|
this.fabricObject.setControlsVisibility({
|
|
2602
2537
|
tl: false,
|
|
@@ -2606,50 +2541,35 @@ class Text extends AbstractCanvasObject {
|
|
|
2606
2541
|
ml: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
|
|
2607
2542
|
mt: false,
|
|
2608
2543
|
mr: allowManualPositioning && profile.allowScale && !this.isPinToBottom(),
|
|
2609
|
-
mb: false
|
|
2610
|
-
mtr: false,
|
|
2544
|
+
mb: false
|
|
2611
2545
|
});
|
|
2612
2546
|
this.redraw();
|
|
2613
2547
|
}
|
|
2614
2548
|
onTextChange() {
|
|
2615
2549
|
this.data.userText = this.fabricObject.text;
|
|
2616
2550
|
this.text$.next(this.fabricObject.text);
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
// Skip expensive getBoundingBox if object is clearly within bounds
|
|
2621
|
-
if (currentLeft + (this.fabricObject.width || 0) > canvasWidth * 0.9) {
|
|
2622
|
-
if (this.getBoundingBox().width > canvasWidth) {
|
|
2623
|
-
this.fabricObject.set({ left: 0, width: canvasWidth });
|
|
2624
|
-
this.redraw();
|
|
2625
|
-
}
|
|
2551
|
+
if (this.getBoundingBox().width > this.canvas.getDimensions().widthPx) {
|
|
2552
|
+
this.fabricObject.set({ left: 0, width: this.canvas.getDimensions().widthPx });
|
|
2553
|
+
this.redraw();
|
|
2626
2554
|
}
|
|
2627
2555
|
}
|
|
2628
2556
|
onDelete() {
|
|
2629
2557
|
this.removeBullets();
|
|
2630
2558
|
}
|
|
2631
2559
|
onSelectionChange() {
|
|
2632
|
-
this.updateTextSelection(
|
|
2560
|
+
this.updateTextSelection();
|
|
2633
2561
|
}
|
|
2634
2562
|
hasTextSelection() {
|
|
2635
2563
|
return this.canvas.getSelection().isText && this.textSelection$.value.length > 0;
|
|
2636
2564
|
}
|
|
2637
|
-
updateTextSelection(
|
|
2565
|
+
updateTextSelection() {
|
|
2638
2566
|
if (this.canvas.headless)
|
|
2639
2567
|
return;
|
|
2640
2568
|
this.textSelection$.next(new TextSelection(this.fabricObject, this.fontLibrary));
|
|
2641
|
-
|
|
2642
|
-
this.notifyCanvasOfTextChanges();
|
|
2643
|
-
}
|
|
2569
|
+
this.notifyCanvasOfTextChanges();
|
|
2644
2570
|
}
|
|
2645
2571
|
notifyCanvasOfTextChanges() {
|
|
2646
|
-
|
|
2647
|
-
clearTimeout(this.notifyCanvasTimeout);
|
|
2648
|
-
}
|
|
2649
|
-
this.notifyCanvasTimeout = setTimeout(() => {
|
|
2650
|
-
this.canvas.notifyTextChanged();
|
|
2651
|
-
this.notifyCanvasTimeout = null;
|
|
2652
|
-
}, this.NOTIFY_DELAY_MS);
|
|
2572
|
+
this.canvas.notifyTextChanged();
|
|
2653
2573
|
}
|
|
2654
2574
|
}
|
|
2655
2575
|
Text.NEW_LINE = "\n";
|
|
@@ -2815,7 +2735,6 @@ class AbstractInteractiveCanvas {
|
|
|
2815
2735
|
this.devicePixelRatio = devicePixelRatio;
|
|
2816
2736
|
this.fontLibrary = new FontLibrary();
|
|
2817
2737
|
this.dimensionChangeRejections$ = new rxjs.Subject();
|
|
2818
|
-
this.redrawScheduled = false;
|
|
2819
2738
|
this.IMAGE_CAPTURE_COEFFICIENT = this.calculateImageCaptureCoefficient();
|
|
2820
2739
|
/**
|
|
2821
2740
|
* Fabric defaults to only 2 decimal places when saving, which causes havoc on the scaling of large images.
|
|
@@ -2838,7 +2757,7 @@ class AbstractInteractiveCanvas {
|
|
|
2838
2757
|
this.fabricCanvas.stateful = true;
|
|
2839
2758
|
this.fabricCanvas.preserveObjectStacking = true;
|
|
2840
2759
|
this.fabricCanvas.perPixelTargetFind = true;
|
|
2841
|
-
this.fabricCanvas.targetFindTolerance = 4;
|
|
2760
|
+
this.fabricCanvas.targetFindTolerance = 4;
|
|
2842
2761
|
this.setBackgroundColor("#FFFFFF");
|
|
2843
2762
|
}
|
|
2844
2763
|
/**
|
|
@@ -3142,6 +3061,7 @@ class AbstractInteractiveCanvas {
|
|
|
3142
3061
|
*/
|
|
3143
3062
|
addImageObject(imageUrl) {
|
|
3144
3063
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3064
|
+
// Don't let the image be more than half the canvas in size.
|
|
3145
3065
|
const maxSizeScale = 2;
|
|
3146
3066
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3147
3067
|
const options = { crossOrigin: "anonymous" };
|
|
@@ -3153,6 +3073,7 @@ class AbstractInteractiveCanvas {
|
|
|
3153
3073
|
if (curWidth > maxWidth) {
|
|
3154
3074
|
newScale = maxWidth / curWidth;
|
|
3155
3075
|
}
|
|
3076
|
+
// Set image properties and add to the canvas
|
|
3156
3077
|
const fabricImage = new this.fabric.Image(image, {
|
|
3157
3078
|
id: id,
|
|
3158
3079
|
scaleX: newScale,
|
|
@@ -3172,6 +3093,7 @@ class AbstractInteractiveCanvas {
|
|
|
3172
3093
|
return object;
|
|
3173
3094
|
}
|
|
3174
3095
|
else {
|
|
3096
|
+
// Browser-side logic
|
|
3175
3097
|
return yield new Promise((resolve) => {
|
|
3176
3098
|
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3177
3099
|
const id = this.randomId();
|
|
@@ -3223,13 +3145,14 @@ class AbstractInteractiveCanvas {
|
|
|
3223
3145
|
fontFamily: profile.defaultFont,
|
|
3224
3146
|
textAlign: profile.defaultTextAlignment,
|
|
3225
3147
|
hoverCursor: "move",
|
|
3226
|
-
moveCursor:
|
|
3227
|
-
editable: false,
|
|
3228
|
-
editingBorderColor: '#2196F3',
|
|
3148
|
+
moveCursor: 'move',
|
|
3229
3149
|
multiLine: true,
|
|
3230
3150
|
lineHeight: profile.defaultLineHeight,
|
|
3231
3151
|
charSpacing: profile.defaultCharacterSpacing,
|
|
3152
|
+
perPixelTargetFind: false,
|
|
3153
|
+
targetFindTolerance: 4,
|
|
3232
3154
|
splitByGrapheme: true,
|
|
3155
|
+
editable: false, // Only enable on double-click
|
|
3233
3156
|
padding: 0,
|
|
3234
3157
|
cornerSize: 8,
|
|
3235
3158
|
touchCornerSize: 12
|
|
@@ -3679,17 +3602,9 @@ class AbstractInteractiveCanvas {
|
|
|
3679
3602
|
}
|
|
3680
3603
|
/**
|
|
3681
3604
|
* Redraw the canvas.
|
|
3682
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
3683
3605
|
*/
|
|
3684
3606
|
redraw() {
|
|
3685
|
-
|
|
3686
|
-
return;
|
|
3687
|
-
}
|
|
3688
|
-
this.redrawScheduled = true;
|
|
3689
|
-
requestAnimationFrame(() => {
|
|
3690
|
-
this.fabricCanvas.requestRenderAll();
|
|
3691
|
-
this.redrawScheduled = false;
|
|
3692
|
-
});
|
|
3607
|
+
this.fabricCanvas.requestRenderAll();
|
|
3693
3608
|
}
|
|
3694
3609
|
syncObjectList() {
|
|
3695
3610
|
const newObjectList = _(this.fabricCanvas.getObjects())
|
|
@@ -3815,6 +3730,7 @@ class AbstractInteractiveCanvas {
|
|
|
3815
3730
|
* Update the actual dimensions of the canvas by multiplying the requested dimensions by the current zoom factor.
|
|
3816
3731
|
*/
|
|
3817
3732
|
updateCanvasDimensions(dims, zoom) {
|
|
3733
|
+
this.fabricCanvas.getWidth();
|
|
3818
3734
|
const width = dims.widthPx * zoom;
|
|
3819
3735
|
const height = dims.heightPx * zoom;
|
|
3820
3736
|
this.fabricCanvas.setZoom(zoom);
|
|
@@ -3822,6 +3738,37 @@ class AbstractInteractiveCanvas {
|
|
|
3822
3738
|
width,
|
|
3823
3739
|
height
|
|
3824
3740
|
});
|
|
3741
|
+
/* if (this.layoutManager$.value instanceof AdvancedLayoutManager) {
|
|
3742
|
+
const scaleFactor = width / oldWidth;
|
|
3743
|
+
this.fabricCanvas.calcOffset();
|
|
3744
|
+
const objects = this.fabricCanvas.getObjects();
|
|
3745
|
+
objects.forEach((obj: any) => {
|
|
3746
|
+
obj.set({
|
|
3747
|
+
left: obj.left * scaleFactor,
|
|
3748
|
+
});
|
|
3749
|
+
if (obj.type === "textbox" || obj.type === "text") {
|
|
3750
|
+
obj.set({
|
|
3751
|
+
scaleX: 1,
|
|
3752
|
+
scaleY: 1,
|
|
3753
|
+
width: obj.width * scaleFactor,
|
|
3754
|
+
});
|
|
3755
|
+
obj.initDimensions();
|
|
3756
|
+
} else if (obj.type === "border" || obj.type === "rect") {
|
|
3757
|
+
obj.set({
|
|
3758
|
+
width: obj.width * scaleFactor,
|
|
3759
|
+
scaleX: 1,
|
|
3760
|
+
strokeUniform: true,
|
|
3761
|
+
strokeAlign: "inner",
|
|
3762
|
+
});
|
|
3763
|
+
} else {
|
|
3764
|
+
obj.set({
|
|
3765
|
+
scaleX: obj.scaleX * scaleFactor,
|
|
3766
|
+
});
|
|
3767
|
+
}
|
|
3768
|
+
obj.setCoords();
|
|
3769
|
+
});
|
|
3770
|
+
this.fabricCanvas.requestRenderAll();
|
|
3771
|
+
}*/
|
|
3825
3772
|
}
|
|
3826
3773
|
onProfileChanged(profile) {
|
|
3827
3774
|
this.setMultiSelect(profile.allowMultiSelect);
|
|
@@ -3976,6 +3923,7 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
3976
3923
|
this.fabricCanvas.on("selection:created", (event) => this.onFabricSelectionChanged(event));
|
|
3977
3924
|
this.fabricCanvas.on("selection:cleared", (event) => this.onFabricSelectionChanged(event));
|
|
3978
3925
|
this.fabricCanvas.on("text:editing:entered", () => this.onTextEditing());
|
|
3926
|
+
this.fabricCanvas.on("text:editing:exited", () => this.onTextEditing());
|
|
3979
3927
|
this.fabricCanvas.on("text:editing:exited", (event) => {
|
|
3980
3928
|
this.onTextEditing();
|
|
3981
3929
|
const target = event.target;
|
|
@@ -3984,6 +3932,8 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
3984
3932
|
}
|
|
3985
3933
|
});
|
|
3986
3934
|
this.fabricCanvas.on("text:changed", () => this.onTextChange());
|
|
3935
|
+
// Handle double-click on textbox to enter editing mode
|
|
3936
|
+
// @ts-ignore
|
|
3987
3937
|
this.fabricCanvas.on("mouse:dblclick", (event) => this.onDoubleClick(event));
|
|
3988
3938
|
}
|
|
3989
3939
|
/**
|
|
@@ -4018,20 +3968,29 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
4018
3968
|
selection.setEvent(event);
|
|
4019
3969
|
}
|
|
4020
3970
|
this.selection$.next(selection);
|
|
3971
|
+
this.enterTextSelectionModeIfRequired();
|
|
3972
|
+
}
|
|
3973
|
+
enterTextSelectionModeIfRequired() {
|
|
3974
|
+
var _a, _b;
|
|
3975
|
+
if (!this.profile$.value.enterTextEditImmediatelyOnSelect && !this.layoutManager$.value.enterTextEditImmediatelyOnSelect)
|
|
3976
|
+
return;
|
|
3977
|
+
if (((_b = (_a = this.selection$.value) === null || _a === void 0 ? void 0 : _a.objects[0]) === null || _b === void 0 ? void 0 : _b.getType()) !== exports.ObjectType.TEXT)
|
|
3978
|
+
return;
|
|
3979
|
+
const text = this.selection$.value.objects[0];
|
|
3980
|
+
text.enterEditing();
|
|
4021
3981
|
}
|
|
4022
3982
|
onTextEditing() {
|
|
4023
3983
|
const selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|
|
4024
3984
|
this.selection$.next(new SelectionData(selected));
|
|
4025
3985
|
}
|
|
4026
3986
|
onDoubleClick(event) {
|
|
4027
|
-
var _a, _b;
|
|
4028
3987
|
const target = event.target;
|
|
4029
3988
|
if (target && (target.type === 'textbox' || target.type === 'i-text')) {
|
|
4030
|
-
|
|
4031
|
-
if (!targetIText.isEditing) {
|
|
3989
|
+
if (!target.isEditing) {
|
|
4032
3990
|
target.set({ editable: true, hoverCursor: 'text' });
|
|
4033
|
-
|
|
4034
|
-
|
|
3991
|
+
// target.enterEditing();
|
|
3992
|
+
// target.hiddenTextarea?.focus();
|
|
3993
|
+
this.enterTextSelectionModeIfRequired();
|
|
4035
3994
|
}
|
|
4036
3995
|
}
|
|
4037
3996
|
}
|
|
@@ -9,7 +9,6 @@ export declare class AdvancedLayoutManager extends AbstractLayoutManager {
|
|
|
9
9
|
private repositionCutoffs;
|
|
10
10
|
private repositionBackgrounds;
|
|
11
11
|
private resizeCanvas;
|
|
12
|
-
private dimensionsLayoutScheduled;
|
|
13
12
|
constructor(canvas: IInteractiveCanvas);
|
|
14
13
|
onCanvasDimensionsChange(): void;
|
|
15
14
|
onTextChange(): void;
|
|
@@ -63,8 +63,6 @@ export declare class Text extends AbstractCanvasObject<ExtendedFabricTextbox> im
|
|
|
63
63
|
private readonly text$;
|
|
64
64
|
private readonly textSelection$;
|
|
65
65
|
static readonly NEW_LINE: string;
|
|
66
|
-
private notifyCanvasTimeout;
|
|
67
|
-
private readonly NOTIFY_DELAY_MS;
|
|
68
66
|
constructor(canvas: IInteractiveCanvas, fabricObject: fabric.Textbox, persistedField?: CanvasObjectData);
|
|
69
67
|
/**
|
|
70
68
|
* @override
|