@pooder/kit 5.0.0 → 5.0.2

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.
@@ -7,6 +7,7 @@ const tracer_1 = require("./tracer");
7
7
  const units_1 = require("./units");
8
8
  const geometry_1 = require("./geometry");
9
9
  const sceneLayoutModel_1 = require("./sceneLayoutModel");
10
+ const IMAGE_OBJECT_LAYER_ID = "image.user";
10
11
  class DielineTool {
11
12
  constructor(options) {
12
13
  this.id = "pooder.kit.dieline";
@@ -314,8 +315,8 @@ class DielineTool {
314
315
  {
315
316
  command: "exportCutImage",
316
317
  title: "Export Cut Image",
317
- handler: () => {
318
- return this.exportCutImage();
318
+ handler: (options) => {
319
+ return this.exportCutImage(options);
319
320
  },
320
321
  },
321
322
  {
@@ -445,6 +446,15 @@ class DielineTool {
445
446
  ? -sizeState.cutMarginMm
446
447
  : 0;
447
448
  }
449
+ bringFeatureMarkersToFront() {
450
+ if (!this.canvasService)
451
+ return;
452
+ const canvas = this.canvasService.canvas;
453
+ canvas
454
+ .getObjects()
455
+ .filter((obj) => obj?.data?.type === "feature-marker")
456
+ .forEach((obj) => canvas.bringObjectToFront(obj));
457
+ }
448
458
  updateDieline(_emitEvent = true) {
449
459
  if (!this.canvasService)
450
460
  return;
@@ -632,6 +642,8 @@ class DielineTool {
632
642
  else {
633
643
  this.canvasService.canvas.bringObjectToFront(layer);
634
644
  }
645
+ // Feature tool markers can extend outside trim. Keep them above dieline mask.
646
+ this.bringFeatureMarkersToFront();
635
647
  const rulerLayer = this.canvasService.getLayer("ruler-overlay");
636
648
  if (rulerLayer) {
637
649
  this.canvasService.canvas.bringObjectToFront(rulerLayer);
@@ -655,19 +667,23 @@ class DielineTool {
655
667
  pathData: this.state.pathData,
656
668
  };
657
669
  }
658
- async exportCutImage() {
659
- if (!this.canvasService)
670
+ async exportCutImage(options) {
671
+ const debug = options?.debug === true;
672
+ if (!this.canvasService) {
673
+ console.warn("[DielineTool] exportCutImage returned null: canvas-not-ready");
660
674
  return null;
675
+ }
661
676
  const configService = this.getConfigService();
662
- if (!configService)
663
- return null;
664
- const userLayer = this.canvasService.getLayer("user");
665
- if (!userLayer)
677
+ if (!configService) {
678
+ console.warn("[DielineTool] exportCutImage returned null: config-service-not-ready");
666
679
  return null;
680
+ }
667
681
  this.syncSizeState(configService);
668
682
  const sceneLayout = (0, sceneLayoutModel_1.computeSceneLayout)(this.canvasService, (0, sceneLayoutModel_1.readSizeState)(configService));
669
- if (!sceneLayout)
683
+ if (!sceneLayout) {
684
+ console.warn("[DielineTool] exportCutImage returned null: scene-layout-null");
670
685
  return null;
686
+ }
671
687
  const { shape, radius, features, pathData } = this.state;
672
688
  const canvasW = sceneLayout.canvasWidth || this.canvasService.canvas.width || 800;
673
689
  const canvasH = sceneLayout.canvasHeight || this.canvasService.canvas.height || 600;
@@ -700,24 +716,103 @@ class DielineTool {
700
716
  canvasWidth: canvasW,
701
717
  canvasHeight: canvasH,
702
718
  });
703
- const clonedLayer = await userLayer.clone();
704
719
  const clipPath = new fabric_1.Path(generatedPathData, {
705
- originX: "left",
706
- originY: "top",
707
- left: 0,
708
- top: 0,
720
+ originX: "center",
721
+ originY: "center",
722
+ left: cx,
723
+ top: cy,
709
724
  absolutePositioned: true,
710
725
  });
711
- clonedLayer.clipPath = clipPath;
712
- const bounds = clipPath.getBoundingRect();
713
- return clonedLayer.toDataURL({
714
- format: "png",
715
- multiplier: 2,
716
- left: bounds.left,
717
- top: bounds.top,
718
- width: bounds.width,
719
- height: bounds.height,
726
+ const pathOffsetX = Number(clipPath?.pathOffset?.x);
727
+ const pathOffsetY = Number(clipPath?.pathOffset?.y);
728
+ const centerX = Number.isFinite(pathOffsetX) ? pathOffsetX : cx;
729
+ const centerY = Number.isFinite(pathOffsetY) ? pathOffsetY : cy;
730
+ clipPath.set({
731
+ originX: "center",
732
+ originY: "center",
733
+ left: centerX,
734
+ top: centerY,
735
+ absolutePositioned: true,
720
736
  });
737
+ clipPath.setCoords();
738
+ const pathBounds = clipPath.getBoundingRect();
739
+ if (!Number.isFinite(pathBounds.left) ||
740
+ !Number.isFinite(pathBounds.top) ||
741
+ !Number.isFinite(pathBounds.width) ||
742
+ !Number.isFinite(pathBounds.height) ||
743
+ pathBounds.width <= 0 ||
744
+ pathBounds.height <= 0) {
745
+ console.warn("[DielineTool] exportCutImage returned null: invalid-cut-bounds", {
746
+ bounds: pathBounds,
747
+ });
748
+ return null;
749
+ }
750
+ const exportBounds = pathBounds;
751
+ const sourceImages = this.canvasService.canvas.getObjects().filter((obj) => {
752
+ return obj?.data?.layerId === IMAGE_OBJECT_LAYER_ID;
753
+ });
754
+ if (!sourceImages.length) {
755
+ console.warn("[DielineTool] exportCutImage returned null: no-image-objects-on-canvas");
756
+ return null;
757
+ }
758
+ const sourceCanvasWidth = Number(this.canvasService.canvas.width || sceneLayout.canvasWidth || canvasW);
759
+ const sourceCanvasHeight = Number(this.canvasService.canvas.height || sceneLayout.canvasHeight || canvasH);
760
+ const el = document.createElement("canvas");
761
+ const exportCanvas = new fabric_1.Canvas(el, {
762
+ renderOnAddRemove: false,
763
+ selection: false,
764
+ enableRetinaScaling: false,
765
+ preserveObjectStacking: true,
766
+ });
767
+ exportCanvas.setDimensions({
768
+ width: Math.max(1, sourceCanvasWidth),
769
+ height: Math.max(1, sourceCanvasHeight),
770
+ });
771
+ try {
772
+ for (const source of sourceImages) {
773
+ const clone = await source.clone();
774
+ clone.set({
775
+ selectable: false,
776
+ evented: false,
777
+ });
778
+ clone.setCoords();
779
+ exportCanvas.add(clone);
780
+ }
781
+ exportCanvas.clipPath = clipPath;
782
+ exportCanvas.renderAll();
783
+ const dataUrl = exportCanvas.toDataURL({
784
+ format: "png",
785
+ multiplier: 2,
786
+ left: exportBounds.left,
787
+ top: exportBounds.top,
788
+ width: exportBounds.width,
789
+ height: exportBounds.height,
790
+ });
791
+ if (debug) {
792
+ console.info("[DielineTool] exportCutImage success", {
793
+ sourceCount: sourceImages.length,
794
+ bounds: exportBounds,
795
+ rawPathBounds: pathBounds,
796
+ pathOffset: {
797
+ x: Number.isFinite(pathOffsetX) ? pathOffsetX : null,
798
+ y: Number.isFinite(pathOffsetY) ? pathOffsetY : null,
799
+ },
800
+ clipPathCenter: {
801
+ x: centerX,
802
+ y: centerY,
803
+ },
804
+ cutRect: sceneLayout.cutRect,
805
+ canvasSize: {
806
+ width: Math.max(1, sourceCanvasWidth),
807
+ height: Math.max(1, sourceCanvasHeight),
808
+ },
809
+ });
810
+ }
811
+ return dataUrl;
812
+ }
813
+ finally {
814
+ exportCanvas.dispose();
815
+ }
721
816
  }
722
817
  }
723
818
  exports.DielineTool = DielineTool;
@@ -282,6 +282,8 @@ class FeatureTool {
282
282
  };
283
283
  }
284
284
  this.hasWorkingChanges = false;
285
+ // Keep feature markers above dieline overlay after config-driven redraw.
286
+ this.redraw();
285
287
  return { ok: true };
286
288
  }
287
289
  addFeature(type) {
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @pooder/kit
2
2
 
3
+ ## 5.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - bugfix
8
+
9
+ ## 5.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - bugfix
14
+
3
15
  ## 5.0.0
4
16
 
5
17
  ### Major Changes
package/dist/index.d.mts CHANGED
@@ -133,7 +133,9 @@ declare class DielineTool implements Extension {
133
133
  private bringFeatureMarkersToFront;
134
134
  updateDieline(_emitEvent?: boolean): void;
135
135
  getGeometry(): DielineGeometry | null;
136
- exportCutImage(): Promise<string | null>;
136
+ exportCutImage(options?: {
137
+ debug?: boolean;
138
+ }): Promise<string | null>;
137
139
  }
138
140
 
139
141
  declare class FilmTool implements Extension {
@@ -284,6 +286,7 @@ declare class ImageTool implements Extension {
284
286
  private normalizeItem;
285
287
  private normalizeItems;
286
288
  private cloneItems;
289
+ private emitWorkingChange;
287
290
  private generateId;
288
291
  private getImageIdFromActiveObject;
289
292
  private resolveReplaceTargetId;
package/dist/index.d.ts CHANGED
@@ -133,7 +133,9 @@ declare class DielineTool implements Extension {
133
133
  private bringFeatureMarkersToFront;
134
134
  updateDieline(_emitEvent?: boolean): void;
135
135
  getGeometry(): DielineGeometry | null;
136
- exportCutImage(): Promise<string | null>;
136
+ exportCutImage(options?: {
137
+ debug?: boolean;
138
+ }): Promise<string | null>;
137
139
  }
138
140
 
139
141
  declare class FilmTool implements Extension {
@@ -284,6 +286,7 @@ declare class ImageTool implements Extension {
284
286
  private normalizeItem;
285
287
  private normalizeItems;
286
288
  private cloneItems;
289
+ private emitWorkingChange;
287
290
  private generateId;
288
291
  private getImageIdFromActiveObject;
289
292
  private resolveReplaceTargetId;
package/dist/index.js CHANGED
@@ -1811,6 +1811,7 @@ function buildSceneGeometry(configService, layout) {
1811
1811
  }
1812
1812
 
1813
1813
  // src/dieline.ts
1814
+ var IMAGE_OBJECT_LAYER_ID = "image.user";
1814
1815
  var DielineTool = class {
1815
1816
  constructor(options) {
1816
1817
  this.id = "pooder.kit.dieline";
@@ -2137,8 +2138,8 @@ var DielineTool = class {
2137
2138
  {
2138
2139
  command: "exportCutImage",
2139
2140
  title: "Export Cut Image",
2140
- handler: () => {
2141
- return this.exportCutImage();
2141
+ handler: (options) => {
2142
+ return this.exportCutImage(options);
2142
2143
  }
2143
2144
  },
2144
2145
  {
@@ -2478,18 +2479,29 @@ var DielineTool = class {
2478
2479
  pathData: this.state.pathData
2479
2480
  };
2480
2481
  }
2481
- async exportCutImage() {
2482
- if (!this.canvasService) return null;
2482
+ async exportCutImage(options) {
2483
+ var _a, _b;
2484
+ const debug = (options == null ? void 0 : options.debug) === true;
2485
+ if (!this.canvasService) {
2486
+ console.warn("[DielineTool] exportCutImage returned null: canvas-not-ready");
2487
+ return null;
2488
+ }
2483
2489
  const configService = this.getConfigService();
2484
- if (!configService) return null;
2485
- const userLayer = this.canvasService.getLayer("user");
2486
- if (!userLayer) return null;
2490
+ if (!configService) {
2491
+ console.warn(
2492
+ "[DielineTool] exportCutImage returned null: config-service-not-ready"
2493
+ );
2494
+ return null;
2495
+ }
2487
2496
  this.syncSizeState(configService);
2488
2497
  const sceneLayout = computeSceneLayout(
2489
2498
  this.canvasService,
2490
2499
  readSizeState(configService)
2491
2500
  );
2492
- if (!sceneLayout) return null;
2501
+ if (!sceneLayout) {
2502
+ console.warn("[DielineTool] exportCutImage returned null: scene-layout-null");
2503
+ return null;
2504
+ }
2493
2505
  const { shape, radius, features, pathData } = this.state;
2494
2506
  const canvasW = sceneLayout.canvasWidth || this.canvasService.canvas.width || 800;
2495
2507
  const canvasH = sceneLayout.canvasHeight || this.canvasService.canvas.height || 600;
@@ -2522,24 +2534,104 @@ var DielineTool = class {
2522
2534
  canvasWidth: canvasW,
2523
2535
  canvasHeight: canvasH
2524
2536
  });
2525
- const clonedLayer = await userLayer.clone();
2526
2537
  const clipPath = new import_fabric2.Path(generatedPathData, {
2527
- originX: "left",
2528
- originY: "top",
2529
- left: 0,
2530
- top: 0,
2538
+ originX: "center",
2539
+ originY: "center",
2540
+ left: cx,
2541
+ top: cy,
2531
2542
  absolutePositioned: true
2532
2543
  });
2533
- clonedLayer.clipPath = clipPath;
2534
- const bounds = clipPath.getBoundingRect();
2535
- return clonedLayer.toDataURL({
2536
- format: "png",
2537
- multiplier: 2,
2538
- left: bounds.left,
2539
- top: bounds.top,
2540
- width: bounds.width,
2541
- height: bounds.height
2544
+ const pathOffsetX = Number((_a = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _a.x);
2545
+ const pathOffsetY = Number((_b = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _b.y);
2546
+ const centerX = Number.isFinite(pathOffsetX) ? pathOffsetX : cx;
2547
+ const centerY = Number.isFinite(pathOffsetY) ? pathOffsetY : cy;
2548
+ clipPath.set({
2549
+ originX: "center",
2550
+ originY: "center",
2551
+ left: centerX,
2552
+ top: centerY,
2553
+ absolutePositioned: true
2554
+ });
2555
+ clipPath.setCoords();
2556
+ const pathBounds = clipPath.getBoundingRect();
2557
+ if (!Number.isFinite(pathBounds.left) || !Number.isFinite(pathBounds.top) || !Number.isFinite(pathBounds.width) || !Number.isFinite(pathBounds.height) || pathBounds.width <= 0 || pathBounds.height <= 0) {
2558
+ console.warn("[DielineTool] exportCutImage returned null: invalid-cut-bounds", {
2559
+ bounds: pathBounds
2560
+ });
2561
+ return null;
2562
+ }
2563
+ const exportBounds = pathBounds;
2564
+ const sourceImages = this.canvasService.canvas.getObjects().filter((obj) => {
2565
+ var _a2;
2566
+ return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID;
2567
+ });
2568
+ if (!sourceImages.length) {
2569
+ console.warn(
2570
+ "[DielineTool] exportCutImage returned null: no-image-objects-on-canvas"
2571
+ );
2572
+ return null;
2573
+ }
2574
+ const sourceCanvasWidth = Number(
2575
+ this.canvasService.canvas.width || sceneLayout.canvasWidth || canvasW
2576
+ );
2577
+ const sourceCanvasHeight = Number(
2578
+ this.canvasService.canvas.height || sceneLayout.canvasHeight || canvasH
2579
+ );
2580
+ const el = document.createElement("canvas");
2581
+ const exportCanvas = new import_fabric2.Canvas(el, {
2582
+ renderOnAddRemove: false,
2583
+ selection: false,
2584
+ enableRetinaScaling: false,
2585
+ preserveObjectStacking: true
2586
+ });
2587
+ exportCanvas.setDimensions({
2588
+ width: Math.max(1, sourceCanvasWidth),
2589
+ height: Math.max(1, sourceCanvasHeight)
2542
2590
  });
2591
+ try {
2592
+ for (const source of sourceImages) {
2593
+ const clone = await source.clone();
2594
+ clone.set({
2595
+ selectable: false,
2596
+ evented: false
2597
+ });
2598
+ clone.setCoords();
2599
+ exportCanvas.add(clone);
2600
+ }
2601
+ exportCanvas.clipPath = clipPath;
2602
+ exportCanvas.renderAll();
2603
+ const dataUrl = exportCanvas.toDataURL({
2604
+ format: "png",
2605
+ multiplier: 2,
2606
+ left: exportBounds.left,
2607
+ top: exportBounds.top,
2608
+ width: exportBounds.width,
2609
+ height: exportBounds.height
2610
+ });
2611
+ if (debug) {
2612
+ console.info("[DielineTool] exportCutImage success", {
2613
+ sourceCount: sourceImages.length,
2614
+ bounds: exportBounds,
2615
+ rawPathBounds: pathBounds,
2616
+ pathOffset: {
2617
+ x: Number.isFinite(pathOffsetX) ? pathOffsetX : null,
2618
+ y: Number.isFinite(pathOffsetY) ? pathOffsetY : null
2619
+ },
2620
+ clipPathCenter: {
2621
+ x: centerX,
2622
+ y: centerY
2623
+ },
2624
+ cutRect: sceneLayout.cutRect,
2625
+ canvasSize: {
2626
+ width: Math.max(1, sourceCanvasWidth),
2627
+ height: Math.max(1, sourceCanvasHeight)
2628
+ }
2629
+ });
2630
+ }
2631
+ return dataUrl;
2632
+ } finally {
2633
+ exportCanvas.dispose();
2634
+ }
2543
2635
  }
2544
2636
  };
2545
2637
 
@@ -3625,7 +3717,7 @@ var FeatureTool = class {
3625
3717
  // src/image.ts
3626
3718
  var import_core5 = require("@pooder/core");
3627
3719
  var import_fabric5 = require("fabric");
3628
- var IMAGE_OBJECT_LAYER_ID = "image.user";
3720
+ var IMAGE_OBJECT_LAYER_ID2 = "image.user";
3629
3721
  var IMAGE_OVERLAY_LAYER_ID = "image-overlay";
3630
3722
  var IMAGE_REPLACE_GUARD_MS = 2500;
3631
3723
  var ImageTool = class {
@@ -3685,7 +3777,7 @@ var ImageTool = class {
3685
3777
  const selectedImage = list.find(
3686
3778
  (obj) => {
3687
3779
  var _a2;
3688
- return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID;
3780
+ return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID2;
3689
3781
  }
3690
3782
  );
3691
3783
  this.isImageSelectionActive = !!selectedImage;
@@ -3724,7 +3816,7 @@ var ImageTool = class {
3724
3816
  const target = e == null ? void 0 : e.target;
3725
3817
  const id = (_a = target == null ? void 0 : target.data) == null ? void 0 : _a.id;
3726
3818
  const layerId = (_b = target == null ? void 0 : target.data) == null ? void 0 : _b.layerId;
3727
- if (typeof id !== "string" || layerId !== IMAGE_OBJECT_LAYER_ID) return;
3819
+ if (typeof id !== "string" || layerId !== IMAGE_OBJECT_LAYER_ID2) return;
3728
3820
  const frame = this.getFrameRect();
3729
3821
  if (!frame.width || !frame.height) return;
3730
3822
  const center = target.getCenterPoint ? target.getCenterPoint() : new import_fabric5.Point((_c = target.left) != null ? _c : 0, (_d = target.top) != null ? _d : 0);
@@ -3755,10 +3847,7 @@ var ImageTool = class {
3755
3847
  context.eventBus.on("selection:created", this.onSelectionChanged);
3756
3848
  context.eventBus.on("selection:updated", this.onSelectionChanged);
3757
3849
  context.eventBus.on("selection:cleared", this.onSelectionCleared);
3758
- context.eventBus.on(
3759
- "scene:layout:change",
3760
- this.onSceneLayoutChanged
3761
- );
3850
+ context.eventBus.on("scene:layout:change", this.onSceneLayoutChanged);
3762
3851
  const configService = context.services.get(
3763
3852
  "ConfigurationService"
3764
3853
  );
@@ -3798,10 +3887,7 @@ var ImageTool = class {
3798
3887
  context.eventBus.off("selection:created", this.onSelectionChanged);
3799
3888
  context.eventBus.off("selection:updated", this.onSelectionChanged);
3800
3889
  context.eventBus.off("selection:cleared", this.onSelectionCleared);
3801
- context.eventBus.off(
3802
- "scene:layout:change",
3803
- this.onSceneLayoutChanged
3804
- );
3890
+ context.eventBus.off("scene:layout:change", this.onSceneLayoutChanged);
3805
3891
  (_a = this.dirtyTrackerDisposable) == null ? void 0 : _a.dispose();
3806
3892
  this.dirtyTrackerDisposable = void 0;
3807
3893
  this.clearRenderedImages();
@@ -3910,7 +3996,7 @@ var ImageTool = class {
3910
3996
  id: "image.frame.outerBackground",
3911
3997
  type: "color",
3912
3998
  label: "Image Frame Outer Background",
3913
- default: "rgba(0,0,0,0.18)"
3999
+ default: "#f5f5f5"
3914
4000
  }
3915
4001
  ],
3916
4002
  [import_core5.ContributionPointIds.COMMANDS]: [
@@ -3953,6 +4039,7 @@ var ImageTool = class {
3953
4039
  this.workingItems = this.cloneItems(this.items);
3954
4040
  this.hasWorkingChanges = false;
3955
4041
  this.updateImages();
4042
+ this.emitWorkingChange();
3956
4043
  }
3957
4044
  },
3958
4045
  {
@@ -4067,13 +4154,20 @@ var ImageTool = class {
4067
4154
  cloneItems(items) {
4068
4155
  return this.normalizeItems((items || []).map((i) => ({ ...i })));
4069
4156
  }
4157
+ emitWorkingChange(changedId = null) {
4158
+ var _a;
4159
+ (_a = this.context) == null ? void 0 : _a.eventBus.emit("image:working:change", {
4160
+ changedId,
4161
+ items: this.cloneItems(this.workingItems)
4162
+ });
4163
+ }
4070
4164
  generateId() {
4071
4165
  return Math.random().toString(36).substring(2, 9);
4072
4166
  }
4073
4167
  getImageIdFromActiveObject() {
4074
4168
  var _a, _b, _c;
4075
4169
  const active = (_a = this.canvasService) == null ? void 0 : _a.canvas.getActiveObject();
4076
- if (((_b = active == null ? void 0 : active.data) == null ? void 0 : _b.layerId) === IMAGE_OBJECT_LAYER_ID && typeof ((_c = active == null ? void 0 : active.data) == null ? void 0 : _c.id) === "string") {
4170
+ if (((_b = active == null ? void 0 : active.data) == null ? void 0 : _b.layerId) === IMAGE_OBJECT_LAYER_ID2 && typeof ((_c = active == null ? void 0 : active.data) == null ? void 0 : _c.id) === "string") {
4077
4171
  return active.data.id;
4078
4172
  }
4079
4173
  return null;
@@ -4135,6 +4229,7 @@ var ImageTool = class {
4135
4229
  if (this.workingItems.some((existing) => existing.id === item.id)) return;
4136
4230
  this.workingItems = this.cloneItems([...this.workingItems, item]);
4137
4231
  this.updateImages();
4232
+ this.emitWorkingChange(item.id);
4138
4233
  }
4139
4234
  async updateImage(id, updates, options = {}) {
4140
4235
  this.syncToolActiveFromWorkbench();
@@ -4242,7 +4337,7 @@ var ImageTool = class {
4242
4337
  if (!this.canvasService) return [];
4243
4338
  return this.canvasService.canvas.getObjects().filter((obj) => {
4244
4339
  var _a;
4245
- return ((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) === IMAGE_OBJECT_LAYER_ID;
4340
+ return ((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) === IMAGE_OBJECT_LAYER_ID2;
4246
4341
  });
4247
4342
  }
4248
4343
  getOverlayObjects() {
@@ -4318,10 +4413,7 @@ var ImageTool = class {
4318
4413
  "image.frame.innerBackground",
4319
4414
  "rgba(0,0,0,0)"
4320
4415
  ) || "rgba(0,0,0,0)",
4321
- outerBackground: this.getConfig(
4322
- "image.frame.outerBackground",
4323
- "rgba(0,0,0,0.18)"
4324
- ) || "rgba(0,0,0,0.18)"
4416
+ outerBackground: "#f5f5f5"
4325
4417
  };
4326
4418
  }
4327
4419
  resolveRenderImageState(item) {
@@ -4398,7 +4490,7 @@ var ImageTool = class {
4398
4490
  created.set({
4399
4491
  data: {
4400
4492
  id: item.id,
4401
- layerId: IMAGE_OBJECT_LAYER_ID,
4493
+ layerId: IMAGE_OBJECT_LAYER_ID2,
4402
4494
  type: "image-item"
4403
4495
  }
4404
4496
  });
@@ -4413,7 +4505,7 @@ var ImageTool = class {
4413
4505
  data: {
4414
4506
  ...obj.data || {},
4415
4507
  id: item.id,
4416
- layerId: IMAGE_OBJECT_LAYER_ID,
4508
+ layerId: IMAGE_OBJECT_LAYER_ID2,
4417
4509
  type: "image-item"
4418
4510
  }
4419
4511
  });
@@ -4465,10 +4557,21 @@ var ImageTool = class {
4465
4557
  const canvasW = this.canvasService.canvas.width || 0;
4466
4558
  const canvasH = this.canvasService.canvas.height || 0;
4467
4559
  const visual = this.getFrameVisualConfig();
4468
- const topH = Math.max(0, frame.top);
4469
- const bottomH = Math.max(0, canvasH - (frame.top + frame.height));
4470
- const leftW = Math.max(0, frame.left);
4471
- const rightW = Math.max(0, canvasW - (frame.left + frame.width));
4560
+ const frameLeft = Math.max(0, Math.min(canvasW, frame.left));
4561
+ const frameTop = Math.max(0, Math.min(canvasH, frame.top));
4562
+ const frameRight = Math.max(
4563
+ frameLeft,
4564
+ Math.min(canvasW, frame.left + frame.width)
4565
+ );
4566
+ const frameBottom = Math.max(
4567
+ frameTop,
4568
+ Math.min(canvasH, frame.top + frame.height)
4569
+ );
4570
+ const visibleFrameH = Math.max(0, frameBottom - frameTop);
4571
+ const topH = frameTop;
4572
+ const bottomH = Math.max(0, canvasH - frameBottom);
4573
+ const leftW = frameLeft;
4574
+ const rightW = Math.max(0, canvasW - frameRight);
4472
4575
  const mask = [
4473
4576
  {
4474
4577
  id: "image.cropMask.top",
@@ -4492,7 +4595,7 @@ var ImageTool = class {
4492
4595
  data: { id: "image.cropMask.bottom", zIndex: 2 },
4493
4596
  props: {
4494
4597
  left: canvasW / 2,
4495
- top: frame.top + frame.height + bottomH / 2,
4598
+ top: frameBottom + bottomH / 2,
4496
4599
  width: canvasW,
4497
4600
  height: bottomH,
4498
4601
  originX: "center",
@@ -4508,9 +4611,9 @@ var ImageTool = class {
4508
4611
  data: { id: "image.cropMask.left", zIndex: 3 },
4509
4612
  props: {
4510
4613
  left: leftW / 2,
4511
- top: frame.top + frame.height / 2,
4614
+ top: frameTop + visibleFrameH / 2,
4512
4615
  width: leftW,
4513
- height: frame.height,
4616
+ height: visibleFrameH,
4514
4617
  originX: "center",
4515
4618
  originY: "center",
4516
4619
  fill: visual.outerBackground,
@@ -4523,10 +4626,10 @@ var ImageTool = class {
4523
4626
  type: "rect",
4524
4627
  data: { id: "image.cropMask.right", zIndex: 4 },
4525
4628
  props: {
4526
- left: frame.left + frame.width + rightW / 2,
4527
- top: frame.top + frame.height / 2,
4629
+ left: frameRight + rightW / 2,
4630
+ top: frameTop + visibleFrameH / 2,
4528
4631
  width: rightW,
4529
- height: frame.height,
4632
+ height: visibleFrameH,
4530
4633
  originX: "center",
4531
4634
  originY: "center",
4532
4635
  fill: visual.outerBackground,
@@ -4616,6 +4719,7 @@ var ImageTool = class {
4616
4719
  if (this.isToolActive) {
4617
4720
  this.updateImages();
4618
4721
  }
4722
+ this.emitWorkingChange(id);
4619
4723
  }
4620
4724
  async updateImageInConfig(id, updates) {
4621
4725
  var _a, _b, _c, _d;
@@ -4696,6 +4800,7 @@ var ImageTool = class {
4696
4800
  this.isImageSelectionActive = true;
4697
4801
  this.focusedImageId = id;
4698
4802
  this.updateImages();
4803
+ this.emitWorkingChange(id);
4699
4804
  }
4700
4805
  focusImageSelection(id) {
4701
4806
  if (!this.canvasService) return;
@@ -4788,6 +4893,7 @@ var ImageTool = class {
4788
4893
  this.hasWorkingChanges = false;
4789
4894
  this.workingItems = this.cloneItems(next);
4790
4895
  this.updateConfig(next);
4896
+ this.emitWorkingChange(focusId);
4791
4897
  if (focusId) {
4792
4898
  this.focusedImageId = focusId;
4793
4899
  this.isImageSelectionActive = true;
@@ -4817,7 +4923,7 @@ var ImageTool = class {
4817
4923
  const idSet = new Set(imageIds);
4818
4924
  const sourceObjects = this.canvasService.canvas.getObjects().filter((obj) => {
4819
4925
  var _a2, _b2;
4820
- return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID && typeof ((_b2 = obj == null ? void 0 : obj.data) == null ? void 0 : _b2.id) === "string" && idSet.has(obj.data.id);
4926
+ return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID2 && typeof ((_b2 = obj == null ? void 0 : obj.data) == null ? void 0 : _b2.id) === "string" && idSet.has(obj.data.id);
4821
4927
  });
4822
4928
  for (const source of sourceObjects) {
4823
4929
  const clone = await source.clone();
@@ -4862,7 +4968,7 @@ var ImageTool = class {
4862
4968
  var import_core6 = require("@pooder/core");
4863
4969
  var import_fabric6 = require("fabric");
4864
4970
  var WHITE_INK_OBJECT_LAYER_ID = "white-ink.user";
4865
- var IMAGE_OBJECT_LAYER_ID2 = "image.user";
4971
+ var IMAGE_OBJECT_LAYER_ID3 = "image.user";
4866
4972
  var WHITE_INK_DEBUG_KEY = "whiteInk.debug";
4867
4973
  var WHITE_INK_PREVIEW_IMAGE_VISIBLE_KEY = "whiteInk.previewImageVisible";
4868
4974
  var WHITE_INK_DEFAULT_OPACITY = 0.85;
@@ -5563,7 +5669,7 @@ var WhiteInkTool = class {
5563
5669
  const imageIndexes = objects.map(
5564
5670
  (obj, index) => {
5565
5671
  var _a;
5566
- return ((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) === IMAGE_OBJECT_LAYER_ID2 ? index : -1;
5672
+ return ((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) === IMAGE_OBJECT_LAYER_ID3 ? index : -1;
5567
5673
  }
5568
5674
  ).filter((index) => index >= 0);
5569
5675
  if (imageIndexes.length > 0) {
@@ -5596,7 +5702,7 @@ var WhiteInkTool = class {
5596
5702
  let changed = false;
5597
5703
  this.canvasService.canvas.getObjects().forEach((obj) => {
5598
5704
  var _a, _b;
5599
- if (((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) !== IMAGE_OBJECT_LAYER_ID2) return;
5705
+ if (((_a = obj == null ? void 0 : obj.data) == null ? void 0 : _a.layerId) !== IMAGE_OBJECT_LAYER_ID3) return;
5600
5706
  if (obj.visible === visible) return;
5601
5707
  obj.set({ visible });
5602
5708
  (_b = obj.setCoords) == null ? void 0 : _b.call(obj);