@pooder/kit 6.1.1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ const IMAGE_DEFAULT_CONTROL_CAPABILITIES = [
17
17
  "rotate",
18
18
  "scale",
19
19
  ];
20
+ const IMAGE_MOVE_SNAP_THRESHOLD_PX = 6;
20
21
  const IMAGE_CONTROL_DESCRIPTORS = [
21
22
  {
22
23
  key: "tl",
@@ -59,12 +60,17 @@ class ImageTool {
59
60
  this.renderSeq = 0;
60
61
  this.imageSpecs = [];
61
62
  this.overlaySpecs = [];
63
+ this.activeSnapX = null;
64
+ this.activeSnapY = null;
65
+ this.movingImageId = null;
66
+ this.hasRenderedSnapGuides = false;
62
67
  this.subscriptions = new subscriptions_1.SubscriptionBag();
63
68
  this.imageControlsByCapabilityKey = new Map();
64
69
  this.onToolActivated = (event) => {
65
70
  const before = this.isToolActive;
66
71
  this.syncToolActiveFromWorkbench(event.id);
67
72
  if (!this.isToolActive) {
73
+ this.endMoveSnapInteraction();
68
74
  this.setImageFocus(null, {
69
75
  syncCanvasSelection: true,
70
76
  skipRender: true,
@@ -110,6 +116,7 @@ class ImageTool {
110
116
  this.updateImages();
111
117
  };
112
118
  this.onSelectionCleared = () => {
119
+ this.endMoveSnapInteraction();
113
120
  this.setImageFocus(null, {
114
121
  syncCanvasSelection: false,
115
122
  skipRender: true,
@@ -118,6 +125,7 @@ class ImageTool {
118
125
  this.updateImages();
119
126
  };
120
127
  this.onSceneLayoutChanged = () => {
128
+ this.canvasService?.requestRenderAll();
121
129
  this.updateImages();
122
130
  };
123
131
  this.onSceneGeometryChanged = () => {
@@ -131,7 +139,11 @@ class ImageTool {
131
139
  const layerId = target?.data?.layerId;
132
140
  if (typeof id !== "string" || layerId !== layers_1.IMAGE_OBJECT_LAYER_ID)
133
141
  return;
142
+ if (this.movingImageId === id) {
143
+ this.applyMoveSnapToTarget(target);
144
+ }
134
145
  const frame = this.getFrameRect();
146
+ this.endMoveSnapInteraction();
135
147
  if (!frame.width || !frame.height)
136
148
  return;
137
149
  const center = target.getCenterPoint
@@ -195,6 +207,7 @@ class ImageTool {
195
207
  },
196
208
  ],
197
209
  }), { priority: 300 });
210
+ this.bindCanvasInteractionHandlers();
198
211
  this.subscriptions.on(context.eventBus, "tool:activated", this.onToolActivated);
199
212
  this.subscriptions.on(context.eventBus, "object:modified", this.onObjectModified);
200
213
  this.subscriptions.on(context.eventBus, "selection:created", this.onSelectionChanged);
@@ -238,6 +251,8 @@ class ImageTool {
238
251
  this.imageSpecs = [];
239
252
  this.overlaySpecs = [];
240
253
  this.imageControlsByCapabilityKey.clear();
254
+ this.endMoveSnapInteraction();
255
+ this.unbindCanvasInteractionHandlers();
241
256
  this.clearRenderedImages();
242
257
  this.renderProducerDisposable?.dispose();
243
258
  this.renderProducerDisposable = undefined;
@@ -247,6 +262,271 @@ class ImageTool {
247
262
  }
248
263
  this.context = undefined;
249
264
  }
265
+ bindCanvasInteractionHandlers() {
266
+ if (!this.canvasService || this.canvasObjectMovingHandler)
267
+ return;
268
+ this.canvasMouseUpHandler = (e) => {
269
+ const target = this.getActiveImageTarget(e?.target);
270
+ if (target &&
271
+ typeof target?.data?.id === "string" &&
272
+ target.data.id === this.movingImageId) {
273
+ this.applyMoveSnapToTarget(target);
274
+ }
275
+ this.endMoveSnapInteraction();
276
+ };
277
+ this.canvasObjectMovingHandler = (e) => {
278
+ this.handleCanvasObjectMoving(e);
279
+ };
280
+ this.canvasBeforeRenderHandler = () => {
281
+ this.handleCanvasBeforeRender();
282
+ };
283
+ this.canvasAfterRenderHandler = () => {
284
+ this.handleCanvasAfterRender();
285
+ };
286
+ this.canvasService.canvas.on("mouse:up", this.canvasMouseUpHandler);
287
+ this.canvasService.canvas.on("object:moving", this.canvasObjectMovingHandler);
288
+ this.canvasService.canvas.on("before:render", this.canvasBeforeRenderHandler);
289
+ this.canvasService.canvas.on("after:render", this.canvasAfterRenderHandler);
290
+ }
291
+ unbindCanvasInteractionHandlers() {
292
+ if (!this.canvasService)
293
+ return;
294
+ if (this.canvasMouseUpHandler) {
295
+ this.canvasService.canvas.off("mouse:up", this.canvasMouseUpHandler);
296
+ }
297
+ if (this.canvasObjectMovingHandler) {
298
+ this.canvasService.canvas.off("object:moving", this.canvasObjectMovingHandler);
299
+ }
300
+ if (this.canvasBeforeRenderHandler) {
301
+ this.canvasService.canvas.off("before:render", this.canvasBeforeRenderHandler);
302
+ }
303
+ if (this.canvasAfterRenderHandler) {
304
+ this.canvasService.canvas.off("after:render", this.canvasAfterRenderHandler);
305
+ }
306
+ this.canvasMouseUpHandler = undefined;
307
+ this.canvasObjectMovingHandler = undefined;
308
+ this.canvasBeforeRenderHandler = undefined;
309
+ this.canvasAfterRenderHandler = undefined;
310
+ }
311
+ getActiveImageTarget(target) {
312
+ if (!this.isToolActive)
313
+ return null;
314
+ if (!target)
315
+ return null;
316
+ if (target?.data?.layerId !== layers_1.IMAGE_OBJECT_LAYER_ID)
317
+ return null;
318
+ if (typeof target?.data?.id !== "string")
319
+ return null;
320
+ return target;
321
+ }
322
+ getTargetBoundsScene(target) {
323
+ if (!this.canvasService || !target)
324
+ return null;
325
+ const rawBounds = typeof target.getBoundingRect === "function"
326
+ ? target.getBoundingRect()
327
+ : {
328
+ left: Number(target.left || 0),
329
+ top: Number(target.top || 0),
330
+ width: Number(target.width || 0),
331
+ height: Number(target.height || 0),
332
+ };
333
+ return this.canvasService.toSceneRect({
334
+ left: Number(rawBounds.left || 0),
335
+ top: Number(rawBounds.top || 0),
336
+ width: Number(rawBounds.width || 0),
337
+ height: Number(rawBounds.height || 0),
338
+ });
339
+ }
340
+ getSnapThresholdScene(px) {
341
+ if (!this.canvasService)
342
+ return px;
343
+ return this.canvasService.toSceneLength(px);
344
+ }
345
+ pickSnapMatch(candidates) {
346
+ if (!candidates.length)
347
+ return null;
348
+ const snapThreshold = this.getSnapThresholdScene(IMAGE_MOVE_SNAP_THRESHOLD_PX);
349
+ let best = null;
350
+ candidates.forEach((candidate) => {
351
+ if (Math.abs(candidate.deltaScene) > snapThreshold)
352
+ return;
353
+ if (!best || Math.abs(candidate.deltaScene) < Math.abs(best.deltaScene)) {
354
+ best = candidate;
355
+ }
356
+ });
357
+ return best;
358
+ }
359
+ computeMoveSnapMatches(bounds, frame) {
360
+ if (!bounds || frame.width <= 0 || frame.height <= 0) {
361
+ return { x: null, y: null };
362
+ }
363
+ const xCandidates = [
364
+ {
365
+ axis: "x",
366
+ lineId: "frame-left",
367
+ kind: "edge",
368
+ lineScene: frame.left,
369
+ deltaScene: frame.left - bounds.left,
370
+ },
371
+ {
372
+ axis: "x",
373
+ lineId: "frame-center-x",
374
+ kind: "center",
375
+ lineScene: frame.left + frame.width / 2,
376
+ deltaScene: frame.left + frame.width / 2 - (bounds.left + bounds.width / 2),
377
+ },
378
+ {
379
+ axis: "x",
380
+ lineId: "frame-right",
381
+ kind: "edge",
382
+ lineScene: frame.left + frame.width,
383
+ deltaScene: frame.left + frame.width - (bounds.left + bounds.width),
384
+ },
385
+ ];
386
+ const yCandidates = [
387
+ {
388
+ axis: "y",
389
+ lineId: "frame-top",
390
+ kind: "edge",
391
+ lineScene: frame.top,
392
+ deltaScene: frame.top - bounds.top,
393
+ },
394
+ {
395
+ axis: "y",
396
+ lineId: "frame-center-y",
397
+ kind: "center",
398
+ lineScene: frame.top + frame.height / 2,
399
+ deltaScene: frame.top + frame.height / 2 - (bounds.top + bounds.height / 2),
400
+ },
401
+ {
402
+ axis: "y",
403
+ lineId: "frame-bottom",
404
+ kind: "edge",
405
+ lineScene: frame.top + frame.height,
406
+ deltaScene: frame.top + frame.height - (bounds.top + bounds.height),
407
+ },
408
+ ];
409
+ return {
410
+ x: this.pickSnapMatch(xCandidates),
411
+ y: this.pickSnapMatch(yCandidates),
412
+ };
413
+ }
414
+ areSnapMatchesEqual(a, b) {
415
+ if (!a && !b)
416
+ return true;
417
+ if (!a || !b)
418
+ return false;
419
+ return a.lineId === b.lineId && a.axis === b.axis && a.kind === b.kind;
420
+ }
421
+ updateSnapMatchState(nextX, nextY) {
422
+ const changed = !this.areSnapMatchesEqual(this.activeSnapX, nextX) ||
423
+ !this.areSnapMatchesEqual(this.activeSnapY, nextY);
424
+ this.activeSnapX = nextX;
425
+ this.activeSnapY = nextY;
426
+ if (changed) {
427
+ this.canvasService?.requestRenderAll();
428
+ }
429
+ }
430
+ clearSnapPreview() {
431
+ this.activeSnapX = null;
432
+ this.activeSnapY = null;
433
+ this.hasRenderedSnapGuides = false;
434
+ this.canvasService?.requestRenderAll();
435
+ }
436
+ endMoveSnapInteraction() {
437
+ this.movingImageId = null;
438
+ this.clearSnapPreview();
439
+ }
440
+ applyMoveSnapToTarget(target) {
441
+ if (!this.canvasService) {
442
+ return { x: null, y: null };
443
+ }
444
+ const frame = this.getFrameRect();
445
+ if (frame.width <= 0 || frame.height <= 0) {
446
+ return { x: null, y: null };
447
+ }
448
+ const bounds = this.getTargetBoundsScene(target);
449
+ const matches = this.computeMoveSnapMatches(bounds, frame);
450
+ const deltaScreenX = this.canvasService.toScreenLength(matches.x?.deltaScene ?? 0);
451
+ const deltaScreenY = this.canvasService.toScreenLength(matches.y?.deltaScene ?? 0);
452
+ if (deltaScreenX || deltaScreenY) {
453
+ target.set({
454
+ left: Number(target.left || 0) + deltaScreenX,
455
+ top: Number(target.top || 0) + deltaScreenY,
456
+ });
457
+ target.setCoords();
458
+ }
459
+ return matches;
460
+ }
461
+ handleCanvasBeforeRender() {
462
+ if (!this.canvasService)
463
+ return;
464
+ if (!this.hasRenderedSnapGuides && !this.activeSnapX && !this.activeSnapY) {
465
+ return;
466
+ }
467
+ this.canvasService.canvas.clearContext(this.canvasService.canvas.contextTop);
468
+ this.hasRenderedSnapGuides = false;
469
+ }
470
+ drawSnapGuideLine(from, to) {
471
+ if (!this.canvasService)
472
+ return;
473
+ const ctx = this.canvasService.canvas.contextTop;
474
+ if (!ctx)
475
+ return;
476
+ const color = this.getConfig("image.control.borderColor", "#1677ff") ||
477
+ "#1677ff";
478
+ ctx.save();
479
+ ctx.strokeStyle = color;
480
+ ctx.lineWidth = 1;
481
+ ctx.beginPath();
482
+ ctx.moveTo(from.x, from.y);
483
+ ctx.lineTo(to.x, to.y);
484
+ ctx.stroke();
485
+ ctx.restore();
486
+ }
487
+ handleCanvasAfterRender() {
488
+ if (!this.canvasService || !this.isImageEditingVisible()) {
489
+ return;
490
+ }
491
+ const frame = this.getFrameRect();
492
+ if (frame.width <= 0 || frame.height <= 0) {
493
+ return;
494
+ }
495
+ const frameScreen = this.getFrameRectScreen(frame);
496
+ let drew = false;
497
+ if (this.activeSnapX) {
498
+ const x = this.canvasService.toScreenPoint({
499
+ x: this.activeSnapX.lineScene,
500
+ y: frame.top,
501
+ }).x;
502
+ this.drawSnapGuideLine({ x, y: frameScreen.top }, { x, y: frameScreen.top + frameScreen.height });
503
+ drew = true;
504
+ }
505
+ if (this.activeSnapY) {
506
+ const y = this.canvasService.toScreenPoint({
507
+ x: frame.left,
508
+ y: this.activeSnapY.lineScene,
509
+ }).y;
510
+ this.drawSnapGuideLine({ x: frameScreen.left, y }, { x: frameScreen.left + frameScreen.width, y });
511
+ drew = true;
512
+ }
513
+ this.hasRenderedSnapGuides = drew;
514
+ }
515
+ handleCanvasObjectMoving(e) {
516
+ const target = this.getActiveImageTarget(e?.target);
517
+ if (!target || !this.canvasService)
518
+ return;
519
+ this.movingImageId =
520
+ typeof target?.data?.id === "string" ? target.data.id : null;
521
+ const frame = this.getFrameRect();
522
+ if (frame.width <= 0 || frame.height <= 0) {
523
+ this.endMoveSnapInteraction();
524
+ return;
525
+ }
526
+ const rawBounds = this.getTargetBoundsScene(target);
527
+ const matches = this.computeMoveSnapMatches(rawBounds, frame);
528
+ this.updateSnapMatchState(matches.x, matches.y);
529
+ }
250
530
  syncToolActiveFromWorkbench(fallbackId) {
251
531
  const wb = this.context?.services.get("WorkbenchService");
252
532
  const activeId = wb?.activeToolId;
@@ -864,33 +1144,9 @@ class ImageTool {
864
1144
  originY: "top",
865
1145
  fill: hatchFill,
866
1146
  opacity: patternFill ? 1 : 0.8,
867
- stroke: null,
868
- fillRule: "evenodd",
869
- selectable: false,
870
- evented: false,
871
- excludeFromExport: true,
872
- objectCaching: false,
873
- },
874
- },
875
- {
876
- id: "image.cropShapePath",
877
- type: "path",
878
- data: { id: "image.cropShapePath", zIndex: 6 },
879
- layout: {
880
- reference: "custom",
881
- referenceRect: frameRect,
882
- alignX: "start",
883
- alignY: "start",
884
- offsetX: shapeBounds.x,
885
- offsetY: shapeBounds.y,
886
- },
887
- props: {
888
- pathData: shapePathData,
889
- originX: "left",
890
- originY: "top",
891
- fill: "rgba(0,0,0,0)",
892
1147
  stroke: "rgba(255, 0, 0, 0.9)",
893
1148
  strokeWidth: this.canvasService?.toSceneLength(1) ?? 1,
1149
+ fillRule: "evenodd",
894
1150
  selectable: false,
895
1151
  evented: false,
896
1152
  excludeFromExport: true,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LAYER_IDS = exports.FILM_LAYER_ID = exports.RULER_LAYER_ID = exports.FEATURE_OVERLAY_LAYER_ID = exports.DIELINE_LAYER_ID = exports.WHITE_INK_OVERLAY_LAYER_ID = exports.WHITE_INK_COVER_LAYER_ID = exports.WHITE_INK_OBJECT_LAYER_ID = exports.IMAGE_OVERLAY_LAYER_ID = exports.IMAGE_OBJECT_LAYER_ID = exports.BACKGROUND_LAYER_ID = void 0;
3
+ exports.LAYER_IDS = exports.FILM_LAYER_ID = exports.RULER_LAYER_ID = exports.FEATURE_OVERLAY_LAYER_ID = exports.FEATURE_DIELINE_LAYER_ID = exports.DIELINE_LAYER_ID = exports.WHITE_INK_OVERLAY_LAYER_ID = exports.WHITE_INK_COVER_LAYER_ID = exports.WHITE_INK_OBJECT_LAYER_ID = exports.IMAGE_OVERLAY_LAYER_ID = exports.IMAGE_OBJECT_LAYER_ID = exports.BACKGROUND_LAYER_ID = void 0;
4
4
  exports.BACKGROUND_LAYER_ID = "background";
5
5
  exports.IMAGE_OBJECT_LAYER_ID = "image.user";
6
6
  exports.IMAGE_OVERLAY_LAYER_ID = "image-overlay";
@@ -8,6 +8,7 @@ exports.WHITE_INK_OBJECT_LAYER_ID = "white-ink.user";
8
8
  exports.WHITE_INK_COVER_LAYER_ID = "white-ink.cover";
9
9
  exports.WHITE_INK_OVERLAY_LAYER_ID = "white-ink.overlay";
10
10
  exports.DIELINE_LAYER_ID = "dieline-overlay";
11
+ exports.FEATURE_DIELINE_LAYER_ID = "feature-dieline-overlay";
11
12
  exports.FEATURE_OVERLAY_LAYER_ID = "feature-overlay";
12
13
  exports.RULER_LAYER_ID = "ruler-overlay";
13
14
  exports.FILM_LAYER_ID = "overlay";
@@ -19,6 +20,7 @@ exports.LAYER_IDS = {
19
20
  whiteInkCover: exports.WHITE_INK_COVER_LAYER_ID,
20
21
  whiteInkOverlay: exports.WHITE_INK_OVERLAY_LAYER_ID,
21
22
  dieline: exports.DIELINE_LAYER_ID,
23
+ featureDieline: exports.FEATURE_DIELINE_LAYER_ID,
22
24
  featureOverlay: exports.FEATURE_OVERLAY_LAYER_ID,
23
25
  rulerOverlay: exports.RULER_LAYER_ID,
24
26
  filmOverlay: exports.FILM_LAYER_ID,
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @pooder/kit
2
2
 
3
+ ## 6.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - refactor the dieline feature and modify the image snap
8
+
9
+ ## 6.1.2
10
+
11
+ ### Patch Changes
12
+
13
+ - snapping
14
+
3
15
  ## 6.1.1
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,9 +1,23 @@
1
1
  import * as _pooder_core from '@pooder/core';
2
- import { Extension, ExtensionContext, ContributionPointIds, ConfigurationContribution, CommandContribution, Service, ServiceContext, EventBus } from '@pooder/core';
2
+ import { Extension, ExtensionContext, ContributionPointIds, ConfigurationContribution, CommandContribution, ConfigurationService, Service, ServiceContext, EventBus } from '@pooder/core';
3
3
  import { Canvas, FabricObject } from 'fabric';
4
4
 
5
5
  type BackgroundLayerKind = "color" | "image";
6
6
  type BackgroundFitMode = "cover" | "contain" | "stretch";
7
+ type BackgroundRegionUnit = "normalized" | "px";
8
+ type BackgroundRegistrationFrame = "trim" | "cut" | "bleed" | "focus" | "viewport";
9
+ interface BackgroundRegistrationRegion {
10
+ left: number;
11
+ top: number;
12
+ width: number;
13
+ height: number;
14
+ unit: BackgroundRegionUnit;
15
+ }
16
+ interface BackgroundRegistration {
17
+ sourceRegion?: BackgroundRegistrationRegion;
18
+ targetFrame?: BackgroundRegistrationFrame;
19
+ fit?: BackgroundFitMode;
20
+ }
7
21
  interface BackgroundLayer {
8
22
  id: string;
9
23
  kind: BackgroundLayerKind;
@@ -15,6 +29,7 @@ interface BackgroundLayer {
15
29
  exportable: boolean;
16
30
  color?: string;
17
31
  src?: string;
32
+ registration?: BackgroundRegistration;
18
33
  }
19
34
  interface BackgroundConfig {
20
35
  version: number;
@@ -47,8 +62,11 @@ declare class BackgroundTool implements Extension {
47
62
  private getViewportRect;
48
63
  private resolveSceneLayout;
49
64
  private resolveFocusRect;
65
+ private resolveTargetFrameRect;
50
66
  private resolveAnchorRect;
51
67
  private resolveImagePlacement;
68
+ private resolveRegistrationRegion;
69
+ private resolveRegistrationPlacement;
52
70
  private buildColorLayerSpec;
53
71
  private buildImageLayerSpec;
54
72
  private buildBackgroundSpecs;
@@ -92,6 +110,14 @@ declare class ImageTool implements Extension {
92
110
  private cropShapeHatchPatternKey?;
93
111
  private imageSpecs;
94
112
  private overlaySpecs;
113
+ private activeSnapX;
114
+ private activeSnapY;
115
+ private movingImageId;
116
+ private hasRenderedSnapGuides;
117
+ private canvasObjectMovingHandler?;
118
+ private canvasMouseUpHandler?;
119
+ private canvasBeforeRenderHandler?;
120
+ private canvasAfterRenderHandler?;
95
121
  private renderProducerDisposable?;
96
122
  private readonly subscriptions;
97
123
  private imageControlsByCapabilityKey;
@@ -102,6 +128,22 @@ declare class ImageTool implements Extension {
102
128
  private onSelectionCleared;
103
129
  private onSceneLayoutChanged;
104
130
  private onSceneGeometryChanged;
131
+ private bindCanvasInteractionHandlers;
132
+ private unbindCanvasInteractionHandlers;
133
+ private getActiveImageTarget;
134
+ private getTargetBoundsScene;
135
+ private getSnapThresholdScene;
136
+ private pickSnapMatch;
137
+ private computeMoveSnapMatches;
138
+ private areSnapMatchesEqual;
139
+ private updateSnapMatchState;
140
+ private clearSnapPreview;
141
+ private endMoveSnapInteraction;
142
+ private applyMoveSnapToTarget;
143
+ private handleCanvasBeforeRender;
144
+ private drawSnapGuideLine;
145
+ private handleCanvasAfterRender;
146
+ private handleCanvasObjectMoving;
105
147
  private syncToolActiveFromWorkbench;
106
148
  private isImageEditingVisible;
107
149
  private getEnabledImageControlCapabilities;
@@ -293,6 +335,9 @@ interface DielineState {
293
335
  customSourceWidthPx?: number;
294
336
  customSourceHeightPx?: number;
295
337
  }
338
+ declare function createDefaultDielineState(): DielineState;
339
+ declare function readDielineState(configService: ConfigurationService, fallback?: Partial<DielineState>): DielineState;
340
+
296
341
  declare class DielineTool implements Extension {
297
342
  id: string;
298
343
  metadata: {
@@ -325,7 +370,6 @@ declare class DielineTool implements Extension {
325
370
  private createHatchPattern;
326
371
  private getConfigService;
327
372
  private hasImageItems;
328
- private syncSizeState;
329
373
  private buildDielineSpecs;
330
374
  private buildImageClipEffects;
331
375
  updateDieline(_emitEvent?: boolean): void;
@@ -719,7 +763,9 @@ declare class FeatureTool implements Extension {
719
763
  private hasWorkingChanges;
720
764
  private dirtyTrackerDisposable?;
721
765
  private renderProducerDisposable?;
722
- private specs;
766
+ private markerSpecs;
767
+ private sessionDielineSpecs;
768
+ private sessionDielineEffects;
723
769
  private renderSeq;
724
770
  private readonly subscriptions;
725
771
  private handleMoving;
@@ -733,6 +779,7 @@ declare class FeatureTool implements Extension {
733
779
  deactivate(context: ExtensionContext): void;
734
780
  private onToolActivated;
735
781
  private updateVisibility;
782
+ private isSessionVisible;
736
783
  contribute(): {
737
784
  [ContributionPointIds.TOOLS]: {
738
785
  id: string;
@@ -754,8 +801,10 @@ declare class FeatureTool implements Extension {
754
801
  private getConfigService;
755
802
  private getCommittedFeatures;
756
803
  private updateCommittedFeatures;
804
+ private hasFeatureSessionDraft;
757
805
  private clearFeatureSessionState;
758
- private restoreSessionFeaturesToConfig;
806
+ private restoreCommittedFeaturesToConfig;
807
+ private suspendFeatureSession;
759
808
  private emitWorkingChange;
760
809
  private refreshGeometry;
761
810
  private resetWorkingFeaturesFromSource;
@@ -767,6 +816,7 @@ declare class FeatureTool implements Extension {
767
816
  private getGeometryForFeature;
768
817
  private setup;
769
818
  private teardown;
819
+ private createHatchPattern;
770
820
  private getDraggableMarkerTarget;
771
821
  private getFeatureForMarker;
772
822
  private constrainPosition;
@@ -775,7 +825,9 @@ declare class FeatureTool implements Extension {
775
825
  private syncGroupFromCanvas;
776
826
  private redraw;
777
827
  private redrawAsync;
778
- private buildFeatureSpecs;
828
+ private buildSessionDielineRender;
829
+ private hasImageItems;
830
+ private buildMarkerSpecs;
779
831
  private appendMarkerSpecs;
780
832
  private buildMarkerData;
781
833
  private markerId;
@@ -1008,4 +1060,4 @@ declare function createWhiteInkCommands(tool: any): CommandContribution[];
1008
1060
 
1009
1061
  declare function createWhiteInkConfigurations(): ConfigurationContribution[];
1010
1062
 
1011
- export { type BackgroundConfig, type BackgroundFitMode, type BackgroundLayer, type BackgroundLayerKind, BackgroundTool, CanvasService, type DielineGeometry, type DielineState, DielineTool, FeatureTool, FilmTool, type ImageItem, ImageTool, type LayerObjectCountComparator, type LineStyle, MirrorTool, type RenderClipPathEffectSpec, type RenderCoordinateSpace, type RenderEffectSpec, type RenderLayoutAlign, type RenderLayoutInsets, type RenderLayoutLength, type RenderLayoutRect, type RenderLayoutReference, type RenderObjectLayoutSpec, type RenderObjectSpec, type RenderObjectType, type RenderPassSpec, type RenderProps, RulerTool, SceneLayoutService, SizeTool, ViewportSystem, type VisibilityEvalContext, type VisibilityExpr, type VisibilityLayerState, type WhiteInkItem, WhiteInkTool, getCoverScale as computeImageCoverScale, getCoverScale as computeWhiteInkCoverScale, createDielineCommands, createDielineConfigurations, createImageCommands, createImageConfigurations, createWhiteInkCommands, createWhiteInkConfigurations, evaluateVisibilityExpr };
1063
+ export { type BackgroundConfig, type BackgroundFitMode, type BackgroundLayer, type BackgroundLayerKind, type BackgroundRegionUnit, type BackgroundRegistration, type BackgroundRegistrationFrame, type BackgroundRegistrationRegion, BackgroundTool, CanvasService, type DielineGeometry, type DielineState, DielineTool, FeatureTool, FilmTool, type ImageItem, ImageTool, type LayerObjectCountComparator, type LineStyle, MirrorTool, type RenderClipPathEffectSpec, type RenderCoordinateSpace, type RenderEffectSpec, type RenderLayoutAlign, type RenderLayoutInsets, type RenderLayoutLength, type RenderLayoutRect, type RenderLayoutReference, type RenderObjectLayoutSpec, type RenderObjectSpec, type RenderObjectType, type RenderPassSpec, type RenderProps, RulerTool, SceneLayoutService, SizeTool, ViewportSystem, type VisibilityEvalContext, type VisibilityExpr, type VisibilityLayerState, type WhiteInkItem, WhiteInkTool, getCoverScale as computeImageCoverScale, getCoverScale as computeWhiteInkCoverScale, createDefaultDielineState, createDielineCommands, createDielineConfigurations, createImageCommands, createImageConfigurations, createWhiteInkCommands, createWhiteInkConfigurations, evaluateVisibilityExpr, readDielineState };