@leapfrog/interactive-canvas 2.0.25-beta-15 → 2.0.25-beta-16
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.
|
@@ -343,7 +343,6 @@ export declare abstract class AbstractInteractiveCanvas implements IInteractiveC
|
|
|
343
343
|
private redrawScheduled;
|
|
344
344
|
/**
|
|
345
345
|
* Redraw the canvas.
|
|
346
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
347
346
|
*/
|
|
348
347
|
redraw(): void;
|
|
349
348
|
syncObjectList(): void;
|
|
@@ -270,6 +270,7 @@ class StackObjectsLayoutFunction {
|
|
|
270
270
|
const footerObjects = objects[0];
|
|
271
271
|
const bodyObjects = objects[1];
|
|
272
272
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
273
|
+
// canvas.redraw();
|
|
273
274
|
//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.
|
|
274
275
|
this.applyWidths(allObjects, bodyWidth);
|
|
275
276
|
const bodyRows = this.getRows(bodyObjects);
|
|
@@ -356,11 +357,11 @@ class StackObjectsLayoutFunction {
|
|
|
356
357
|
object.setPosition({
|
|
357
358
|
width: actualWidth
|
|
358
359
|
});
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
360
|
+
_(objects).forEach((object) => {
|
|
361
|
+
if (object.getType() !== ObjectType.VERTICAL_RULE) {
|
|
362
|
+
object.updateDimensions();
|
|
363
|
+
}
|
|
364
|
+
});
|
|
364
365
|
});
|
|
365
366
|
}
|
|
366
367
|
adjustCanvasSize(canvas, requiredHeight) {
|
|
@@ -472,9 +473,7 @@ class AdvancedLayoutManager extends AbstractLayoutManager {
|
|
|
472
473
|
dimensionChange() {
|
|
473
474
|
const canvasMargin = this.canvas.getMargin();
|
|
474
475
|
const canvasDimensions = this.canvas.getDimensions();
|
|
475
|
-
const allObjects = this.canvas.getObjectsByTypesInternal(ObjectType.TEXT, ObjectType.RICH_TEXT,
|
|
476
|
-
//ObjectType.IMAGE,
|
|
477
|
-
ObjectType.RECTANGLE, ObjectType.VERTICAL_RULE, ObjectType.HORIZONTAL_RULE);
|
|
476
|
+
const allObjects = this.canvas.getObjectsByTypesInternal(ObjectType.TEXT, ObjectType.RICH_TEXT, ObjectType.RECTANGLE, ObjectType.VERTICAL_RULE, ObjectType.HORIZONTAL_RULE);
|
|
478
477
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
479
478
|
this.canvas.redraw();
|
|
480
479
|
//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.
|
|
@@ -1117,8 +1116,7 @@ class AbstractCanvasObject {
|
|
|
1117
1116
|
mt: options.allowScale,
|
|
1118
1117
|
mr: options.allowScale,
|
|
1119
1118
|
mb: options.allowScale,
|
|
1120
|
-
mtr: options.allowRotate
|
|
1121
|
-
// dragControl: options.allowMove // Show drag control when movement is allowed
|
|
1119
|
+
mtr: options.allowRotate
|
|
1122
1120
|
});
|
|
1123
1121
|
}
|
|
1124
1122
|
}
|
|
@@ -1857,8 +1855,6 @@ class Text extends AbstractCanvasObject {
|
|
|
1857
1855
|
});
|
|
1858
1856
|
this.fabricObject.on("changed", () => this.onTextChange());
|
|
1859
1857
|
this.fabricObject.on("selection:changed", () => this.onSelectionChange());
|
|
1860
|
-
// Note: Removed containsPoint override to allow Fabric's default bounding box
|
|
1861
|
-
// detection with padding to work properly for hover detection
|
|
1862
1858
|
this.fabricObject.on("mousedown", (e) => {
|
|
1863
1859
|
var _a;
|
|
1864
1860
|
if (!this.fabricObject.isEditing) {
|
|
@@ -2513,7 +2509,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2513
2509
|
lockMovementY: true,
|
|
2514
2510
|
hasControls: false,
|
|
2515
2511
|
selectable: false,
|
|
2516
|
-
// evented: false, // Don't capture mouse events - allows clicks to pass through to textbox
|
|
2517
2512
|
originX: "left",
|
|
2518
2513
|
originY: "top"
|
|
2519
2514
|
});
|
|
@@ -2620,16 +2615,12 @@ class Text extends AbstractCanvasObject {
|
|
|
2620
2615
|
* @inheritDoc
|
|
2621
2616
|
*/
|
|
2622
2617
|
updateFabricObjectBehavior() {
|
|
2623
|
-
// DON'T call super.updateFabricObjectBehavior() for textboxes
|
|
2624
|
-
// because it locks movement which interferes with text editing in Fabric v7
|
|
2625
2618
|
super.updateFabricObjectBehavior();
|
|
2626
2619
|
const profile = this.canvas.getProfile();
|
|
2627
2620
|
const allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
|
|
2628
|
-
// For textboxes, we keep them moveable but hide all controls except drag control
|
|
2629
|
-
// This allows text editing to work properly while still supporting drag via the icon
|
|
2630
2621
|
this.fabricObject.set({
|
|
2631
2622
|
lockMovementX: false, // Allow dragging
|
|
2632
|
-
lockMovementY: false,
|
|
2623
|
+
lockMovementY: false,
|
|
2633
2624
|
lockScalingY: true,
|
|
2634
2625
|
lockScalingX: this.isPinToBottom(),
|
|
2635
2626
|
lockScalingFlip: true,
|
|
@@ -2655,7 +2646,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2655
2646
|
onTextChange() {
|
|
2656
2647
|
this.data.userText = this.fabricObject.text;
|
|
2657
2648
|
this.text$.next(this.fabricObject.text);
|
|
2658
|
-
// Only check width bounds if text is close to canvas edge (performance optimization)
|
|
2659
2649
|
const currentLeft = this.fabricObject.left || 0;
|
|
2660
2650
|
const canvasWidth = this.canvas.getDimensions().widthPx;
|
|
2661
2651
|
// Skip expensive getBoundingBox if object is clearly within bounds
|
|
@@ -2892,8 +2882,8 @@ class AbstractInteractiveCanvas {
|
|
|
2892
2882
|
//Configure canvas behaviour
|
|
2893
2883
|
this.fabricCanvas.stateful = true;
|
|
2894
2884
|
this.fabricCanvas.preserveObjectStacking = true;
|
|
2895
|
-
this.fabricCanvas.perPixelTargetFind = false;
|
|
2896
|
-
this.fabricCanvas.targetFindTolerance = 0;
|
|
2885
|
+
this.fabricCanvas.perPixelTargetFind = false;
|
|
2886
|
+
this.fabricCanvas.targetFindTolerance = 0;
|
|
2897
2887
|
this.setBackgroundColor("#FFFFFF");
|
|
2898
2888
|
}
|
|
2899
2889
|
/**
|
|
@@ -3197,6 +3187,7 @@ class AbstractInteractiveCanvas {
|
|
|
3197
3187
|
*/
|
|
3198
3188
|
addImageObject(imageUrl) {
|
|
3199
3189
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3190
|
+
// Don't let the image be more than half the canvas in size.
|
|
3200
3191
|
const maxSizeScale = 2;
|
|
3201
3192
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3202
3193
|
const options = { crossOrigin: "anonymous" };
|
|
@@ -3208,6 +3199,7 @@ class AbstractInteractiveCanvas {
|
|
|
3208
3199
|
if (curWidth > maxWidth) {
|
|
3209
3200
|
newScale = maxWidth / curWidth;
|
|
3210
3201
|
}
|
|
3202
|
+
// Set image properties and add to the canvas
|
|
3211
3203
|
const fabricImage = new this.fabric.Image(image, {
|
|
3212
3204
|
id: id,
|
|
3213
3205
|
scaleX: newScale,
|
|
@@ -3227,6 +3219,7 @@ class AbstractInteractiveCanvas {
|
|
|
3227
3219
|
return object;
|
|
3228
3220
|
}
|
|
3229
3221
|
else {
|
|
3222
|
+
// Browser-side logic
|
|
3230
3223
|
return yield new Promise((resolve) => {
|
|
3231
3224
|
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3232
3225
|
const id = this.randomId();
|
|
@@ -3734,7 +3727,6 @@ class AbstractInteractiveCanvas {
|
|
|
3734
3727
|
}
|
|
3735
3728
|
/**
|
|
3736
3729
|
* Redraw the canvas.
|
|
3737
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
3738
3730
|
*/
|
|
3739
3731
|
redraw() {
|
|
3740
3732
|
if (this.redrawScheduled) {
|
|
@@ -4073,6 +4065,16 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
4073
4065
|
selection.setEvent(event);
|
|
4074
4066
|
}
|
|
4075
4067
|
this.selection$.next(selection);
|
|
4068
|
+
//this.enterTextSelectionModeIfRequired();
|
|
4069
|
+
}
|
|
4070
|
+
enterTextSelectionModeIfRequired() {
|
|
4071
|
+
var _a, _b;
|
|
4072
|
+
if (!this.profile$.value.enterTextEditImmediatelyOnSelect && !this.layoutManager$.value.enterTextEditImmediatelyOnSelect)
|
|
4073
|
+
return;
|
|
4074
|
+
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)
|
|
4075
|
+
return;
|
|
4076
|
+
const text = this.selection$.value.objects[0];
|
|
4077
|
+
text.enterEditing();
|
|
4076
4078
|
}
|
|
4077
4079
|
onTextEditing() {
|
|
4078
4080
|
const selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|
|
@@ -291,6 +291,7 @@ class StackObjectsLayoutFunction {
|
|
|
291
291
|
const footerObjects = objects[0];
|
|
292
292
|
const bodyObjects = objects[1];
|
|
293
293
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
294
|
+
// canvas.redraw();
|
|
294
295
|
//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.
|
|
295
296
|
this.applyWidths(allObjects, bodyWidth);
|
|
296
297
|
const bodyRows = this.getRows(bodyObjects);
|
|
@@ -377,11 +378,11 @@ class StackObjectsLayoutFunction {
|
|
|
377
378
|
object.setPosition({
|
|
378
379
|
width: actualWidth
|
|
379
380
|
});
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
381
|
+
_(objects).forEach((object) => {
|
|
382
|
+
if (object.getType() !== exports.ObjectType.VERTICAL_RULE) {
|
|
383
|
+
object.updateDimensions();
|
|
384
|
+
}
|
|
385
|
+
});
|
|
385
386
|
});
|
|
386
387
|
}
|
|
387
388
|
adjustCanvasSize(canvas, requiredHeight) {
|
|
@@ -493,9 +494,7 @@ class AdvancedLayoutManager extends AbstractLayoutManager {
|
|
|
493
494
|
dimensionChange() {
|
|
494
495
|
const canvasMargin = this.canvas.getMargin();
|
|
495
496
|
const canvasDimensions = this.canvas.getDimensions();
|
|
496
|
-
const allObjects = this.canvas.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.RICH_TEXT,
|
|
497
|
-
//ObjectType.IMAGE,
|
|
498
|
-
exports.ObjectType.RECTANGLE, exports.ObjectType.VERTICAL_RULE, exports.ObjectType.HORIZONTAL_RULE);
|
|
497
|
+
const allObjects = this.canvas.getObjectsByTypesInternal(exports.ObjectType.TEXT, exports.ObjectType.RICH_TEXT, exports.ObjectType.RECTANGLE, exports.ObjectType.VERTICAL_RULE, exports.ObjectType.HORIZONTAL_RULE);
|
|
499
498
|
const bodyWidth = canvasDimensions.widthPx - canvasMargin.right - canvasMargin.left;
|
|
500
499
|
this.canvas.redraw();
|
|
501
500
|
//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.
|
|
@@ -1138,8 +1137,7 @@ class AbstractCanvasObject {
|
|
|
1138
1137
|
mt: options.allowScale,
|
|
1139
1138
|
mr: options.allowScale,
|
|
1140
1139
|
mb: options.allowScale,
|
|
1141
|
-
mtr: options.allowRotate
|
|
1142
|
-
// dragControl: options.allowMove // Show drag control when movement is allowed
|
|
1140
|
+
mtr: options.allowRotate
|
|
1143
1141
|
});
|
|
1144
1142
|
}
|
|
1145
1143
|
}
|
|
@@ -1878,8 +1876,6 @@ class Text extends AbstractCanvasObject {
|
|
|
1878
1876
|
});
|
|
1879
1877
|
this.fabricObject.on("changed", () => this.onTextChange());
|
|
1880
1878
|
this.fabricObject.on("selection:changed", () => this.onSelectionChange());
|
|
1881
|
-
// Note: Removed containsPoint override to allow Fabric's default bounding box
|
|
1882
|
-
// detection with padding to work properly for hover detection
|
|
1883
1879
|
this.fabricObject.on("mousedown", (e) => {
|
|
1884
1880
|
var _a;
|
|
1885
1881
|
if (!this.fabricObject.isEditing) {
|
|
@@ -2534,7 +2530,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2534
2530
|
lockMovementY: true,
|
|
2535
2531
|
hasControls: false,
|
|
2536
2532
|
selectable: false,
|
|
2537
|
-
// evented: false, // Don't capture mouse events - allows clicks to pass through to textbox
|
|
2538
2533
|
originX: "left",
|
|
2539
2534
|
originY: "top"
|
|
2540
2535
|
});
|
|
@@ -2641,16 +2636,12 @@ class Text extends AbstractCanvasObject {
|
|
|
2641
2636
|
* @inheritDoc
|
|
2642
2637
|
*/
|
|
2643
2638
|
updateFabricObjectBehavior() {
|
|
2644
|
-
// DON'T call super.updateFabricObjectBehavior() for textboxes
|
|
2645
|
-
// because it locks movement which interferes with text editing in Fabric v7
|
|
2646
2639
|
super.updateFabricObjectBehavior();
|
|
2647
2640
|
const profile = this.canvas.getProfile();
|
|
2648
2641
|
const allowManualPositioning = !this.canvas.getLayoutManager().isEnforcedPositioning;
|
|
2649
|
-
// For textboxes, we keep them moveable but hide all controls except drag control
|
|
2650
|
-
// This allows text editing to work properly while still supporting drag via the icon
|
|
2651
2642
|
this.fabricObject.set({
|
|
2652
2643
|
lockMovementX: false, // Allow dragging
|
|
2653
|
-
lockMovementY: false,
|
|
2644
|
+
lockMovementY: false,
|
|
2654
2645
|
lockScalingY: true,
|
|
2655
2646
|
lockScalingX: this.isPinToBottom(),
|
|
2656
2647
|
lockScalingFlip: true,
|
|
@@ -2676,7 +2667,6 @@ class Text extends AbstractCanvasObject {
|
|
|
2676
2667
|
onTextChange() {
|
|
2677
2668
|
this.data.userText = this.fabricObject.text;
|
|
2678
2669
|
this.text$.next(this.fabricObject.text);
|
|
2679
|
-
// Only check width bounds if text is close to canvas edge (performance optimization)
|
|
2680
2670
|
const currentLeft = this.fabricObject.left || 0;
|
|
2681
2671
|
const canvasWidth = this.canvas.getDimensions().widthPx;
|
|
2682
2672
|
// Skip expensive getBoundingBox if object is clearly within bounds
|
|
@@ -2913,8 +2903,8 @@ class AbstractInteractiveCanvas {
|
|
|
2913
2903
|
//Configure canvas behaviour
|
|
2914
2904
|
this.fabricCanvas.stateful = true;
|
|
2915
2905
|
this.fabricCanvas.preserveObjectStacking = true;
|
|
2916
|
-
this.fabricCanvas.perPixelTargetFind = false;
|
|
2917
|
-
this.fabricCanvas.targetFindTolerance = 0;
|
|
2906
|
+
this.fabricCanvas.perPixelTargetFind = false;
|
|
2907
|
+
this.fabricCanvas.targetFindTolerance = 0;
|
|
2918
2908
|
this.setBackgroundColor("#FFFFFF");
|
|
2919
2909
|
}
|
|
2920
2910
|
/**
|
|
@@ -3218,6 +3208,7 @@ class AbstractInteractiveCanvas {
|
|
|
3218
3208
|
*/
|
|
3219
3209
|
addImageObject(imageUrl) {
|
|
3220
3210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3211
|
+
// Don't let the image be more than half the canvas in size.
|
|
3221
3212
|
const maxSizeScale = 2;
|
|
3222
3213
|
const maxWidth = this.dimensions$.value.widthPx / maxSizeScale;
|
|
3223
3214
|
const options = { crossOrigin: "anonymous" };
|
|
@@ -3229,6 +3220,7 @@ class AbstractInteractiveCanvas {
|
|
|
3229
3220
|
if (curWidth > maxWidth) {
|
|
3230
3221
|
newScale = maxWidth / curWidth;
|
|
3231
3222
|
}
|
|
3223
|
+
// Set image properties and add to the canvas
|
|
3232
3224
|
const fabricImage = new this.fabric.Image(image, {
|
|
3233
3225
|
id: id,
|
|
3234
3226
|
scaleX: newScale,
|
|
@@ -3248,6 +3240,7 @@ class AbstractInteractiveCanvas {
|
|
|
3248
3240
|
return object;
|
|
3249
3241
|
}
|
|
3250
3242
|
else {
|
|
3243
|
+
// Browser-side logic
|
|
3251
3244
|
return yield new Promise((resolve) => {
|
|
3252
3245
|
this.fabric.Image.fromURL(imageUrl, options).then((fabricImage) => {
|
|
3253
3246
|
const id = this.randomId();
|
|
@@ -3755,7 +3748,6 @@ class AbstractInteractiveCanvas {
|
|
|
3755
3748
|
}
|
|
3756
3749
|
/**
|
|
3757
3750
|
* Redraw the canvas.
|
|
3758
|
-
* Uses requestAnimationFrame to batch multiple redraw calls into a single render.
|
|
3759
3751
|
*/
|
|
3760
3752
|
redraw() {
|
|
3761
3753
|
if (this.redrawScheduled) {
|
|
@@ -4094,6 +4086,16 @@ class InteractiveCanvas extends AbstractInteractiveCanvas {
|
|
|
4094
4086
|
selection.setEvent(event);
|
|
4095
4087
|
}
|
|
4096
4088
|
this.selection$.next(selection);
|
|
4089
|
+
//this.enterTextSelectionModeIfRequired();
|
|
4090
|
+
}
|
|
4091
|
+
enterTextSelectionModeIfRequired() {
|
|
4092
|
+
var _a, _b;
|
|
4093
|
+
if (!this.profile$.value.enterTextEditImmediatelyOnSelect && !this.layoutManager$.value.enterTextEditImmediatelyOnSelect)
|
|
4094
|
+
return;
|
|
4095
|
+
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)
|
|
4096
|
+
return;
|
|
4097
|
+
const text = this.selection$.value.objects[0];
|
|
4098
|
+
text.enterEditing();
|
|
4097
4099
|
}
|
|
4098
4100
|
onTextEditing() {
|
|
4099
4101
|
const selected = this.getFieldsByCanvasObject(this.fabricCanvas.getActiveObjects());
|