@pooder/kit 5.3.1 → 6.0.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.
- package/.test-dist/src/extensions/background.js +475 -131
- package/.test-dist/src/extensions/dieline.js +283 -180
- package/.test-dist/src/extensions/dielineShape.js +66 -0
- package/.test-dist/src/extensions/feature.js +388 -303
- package/.test-dist/src/extensions/film.js +133 -74
- package/.test-dist/src/extensions/geometry.js +120 -56
- package/.test-dist/src/extensions/image.js +296 -212
- package/.test-dist/src/extensions/index.js +1 -3
- package/.test-dist/src/extensions/maskOps.js +75 -20
- package/.test-dist/src/extensions/ruler.js +312 -215
- package/.test-dist/src/extensions/sceneLayoutModel.js +9 -3
- package/.test-dist/src/extensions/sceneVisibility.js +3 -10
- package/.test-dist/src/extensions/tracer.js +229 -58
- package/.test-dist/src/extensions/white-ink.js +139 -129
- package/.test-dist/src/services/CanvasService.js +888 -126
- package/.test-dist/src/services/index.js +1 -0
- package/.test-dist/src/services/visibility.js +54 -0
- package/.test-dist/tests/run.js +58 -4
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +377 -82
- package/dist/index.d.ts +377 -82
- package/dist/index.js +3920 -2178
- package/dist/index.mjs +3992 -2247
- package/package.json +1 -1
- package/src/extensions/background.ts +631 -145
- package/src/extensions/dieline.ts +280 -187
- package/src/extensions/dielineShape.ts +109 -0
- package/src/extensions/feature.ts +485 -366
- package/src/extensions/film.ts +152 -76
- package/src/extensions/geometry.ts +203 -104
- package/src/extensions/image.ts +319 -238
- package/src/extensions/index.ts +0 -1
- package/src/extensions/ruler.ts +481 -268
- package/src/extensions/sceneLayoutModel.ts +18 -6
- package/src/extensions/white-ink.ts +157 -171
- package/src/services/CanvasService.ts +1126 -140
- package/src/services/index.ts +1 -0
- package/src/services/renderSpec.ts +69 -4
- package/src/services/visibility.ts +78 -0
- package/tests/run.ts +139 -4
- package/.test-dist/src/CanvasService.js +0 -249
- package/.test-dist/src/ViewportSystem.js +0 -75
- package/.test-dist/src/background.js +0 -203
- package/.test-dist/src/bridgeSelection.js +0 -20
- package/.test-dist/src/constraints.js +0 -237
- package/.test-dist/src/dieline.js +0 -818
- package/.test-dist/src/edgeScale.js +0 -12
- package/.test-dist/src/feature.js +0 -826
- package/.test-dist/src/featureComplete.js +0 -32
- package/.test-dist/src/film.js +0 -167
- package/.test-dist/src/geometry.js +0 -506
- package/.test-dist/src/image.js +0 -1250
- package/.test-dist/src/maskOps.js +0 -270
- package/.test-dist/src/mirror.js +0 -104
- package/.test-dist/src/renderSpec.js +0 -2
- package/.test-dist/src/ruler.js +0 -343
- package/.test-dist/src/sceneLayout.js +0 -99
- package/.test-dist/src/sceneLayoutModel.js +0 -196
- package/.test-dist/src/sceneView.js +0 -40
- package/.test-dist/src/sceneVisibility.js +0 -42
- package/.test-dist/src/size.js +0 -332
- package/.test-dist/src/tracer.js +0 -544
- package/.test-dist/src/white-ink.js +0 -829
- package/.test-dist/src/wrappedOffsets.js +0 -33
- package/src/extensions/sceneVisibility.ts +0 -71
|
@@ -7,13 +7,19 @@ import {
|
|
|
7
7
|
ConfigurationService,
|
|
8
8
|
} from "@pooder/core";
|
|
9
9
|
import { Canvas as FabricCanvas, Path, Pattern } from "fabric";
|
|
10
|
-
import { CanvasService } from "../services";
|
|
10
|
+
import { CanvasService, RenderEffectSpec, RenderObjectSpec } from "../services";
|
|
11
11
|
import { ImageTracer } from "./tracer";
|
|
12
|
-
import { Unit } from "../coordinate";
|
|
13
12
|
import { parseLengthToMm } from "../units";
|
|
13
|
+
import {
|
|
14
|
+
DEFAULT_DIELINE_SHAPE,
|
|
15
|
+
DEFAULT_DIELINE_SHAPE_STYLE,
|
|
16
|
+
DIELINE_SHAPES,
|
|
17
|
+
normalizeShapeStyle,
|
|
18
|
+
normalizeDielineShape,
|
|
19
|
+
} from "./dielineShape";
|
|
20
|
+
import type { DielineShape, DielineShapeStyle } from "./dielineShape";
|
|
14
21
|
import {
|
|
15
22
|
generateDielinePath,
|
|
16
|
-
generateMaskPath,
|
|
17
23
|
generateBleedZonePath,
|
|
18
24
|
DielineFeature,
|
|
19
25
|
} from "./geometry";
|
|
@@ -24,9 +30,9 @@ import {
|
|
|
24
30
|
} from "./sceneLayoutModel";
|
|
25
31
|
|
|
26
32
|
export interface DielineGeometry {
|
|
27
|
-
shape:
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
shape: DielineShape;
|
|
34
|
+
shapeStyle: DielineShapeStyle;
|
|
35
|
+
unit: "px";
|
|
30
36
|
x: number;
|
|
31
37
|
y: number;
|
|
32
38
|
width: number;
|
|
@@ -49,8 +55,8 @@ export interface LineStyle {
|
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
export interface DielineState {
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
shape: DielineShape;
|
|
59
|
+
shapeStyle: DielineShapeStyle;
|
|
54
60
|
width: number;
|
|
55
61
|
height: number;
|
|
56
62
|
radius: number;
|
|
@@ -59,7 +65,6 @@ export interface DielineState {
|
|
|
59
65
|
mainLine: LineStyle;
|
|
60
66
|
offsetLine: LineStyle;
|
|
61
67
|
insideColor: string;
|
|
62
|
-
outsideColor: string;
|
|
63
68
|
showBleedLines: boolean;
|
|
64
69
|
features: DielineFeature[];
|
|
65
70
|
pathData?: string;
|
|
@@ -68,6 +73,7 @@ export interface DielineState {
|
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
const IMAGE_OBJECT_LAYER_ID = "image.user";
|
|
76
|
+
const DIELINE_LAYER_ID = "dieline-overlay";
|
|
71
77
|
|
|
72
78
|
export class DielineTool implements Extension {
|
|
73
79
|
id = "pooder.kit.dieline";
|
|
@@ -76,8 +82,8 @@ export class DielineTool implements Extension {
|
|
|
76
82
|
};
|
|
77
83
|
|
|
78
84
|
private state: DielineState = {
|
|
79
|
-
|
|
80
|
-
|
|
85
|
+
shape: DEFAULT_DIELINE_SHAPE,
|
|
86
|
+
shapeStyle: { ...DEFAULT_DIELINE_SHAPE_STYLE },
|
|
81
87
|
width: 500,
|
|
82
88
|
height: 500,
|
|
83
89
|
radius: 0,
|
|
@@ -96,13 +102,16 @@ export class DielineTool implements Extension {
|
|
|
96
102
|
style: "solid",
|
|
97
103
|
},
|
|
98
104
|
insideColor: "rgba(0,0,0,0)",
|
|
99
|
-
outsideColor: "#ffffff",
|
|
100
105
|
showBleedLines: true,
|
|
101
106
|
features: [],
|
|
102
107
|
};
|
|
103
108
|
|
|
104
109
|
private canvasService?: CanvasService;
|
|
105
110
|
private context?: ExtensionContext;
|
|
111
|
+
private specs: RenderObjectSpec[] = [];
|
|
112
|
+
private effects: RenderEffectSpec[] = [];
|
|
113
|
+
private renderSeq = 0;
|
|
114
|
+
private renderProducerDisposable?: { dispose: () => void };
|
|
106
115
|
private onCanvasResized = () => {
|
|
107
116
|
this.updateDieline();
|
|
108
117
|
};
|
|
@@ -118,7 +127,15 @@ export class DielineTool implements Extension {
|
|
|
118
127
|
Object.assign(this.state.offsetLine, options.offsetLine);
|
|
119
128
|
delete options.offsetLine;
|
|
120
129
|
}
|
|
130
|
+
if (options.shapeStyle) {
|
|
131
|
+
this.state.shapeStyle = normalizeShapeStyle(
|
|
132
|
+
options.shapeStyle,
|
|
133
|
+
this.state.shapeStyle,
|
|
134
|
+
);
|
|
135
|
+
delete options.shapeStyle;
|
|
136
|
+
}
|
|
121
137
|
Object.assign(this.state, options);
|
|
138
|
+
this.state.shape = normalizeDielineShape(options.shape, this.state.shape);
|
|
122
139
|
}
|
|
123
140
|
}
|
|
124
141
|
|
|
@@ -129,6 +146,30 @@ export class DielineTool implements Extension {
|
|
|
129
146
|
console.warn("CanvasService not found for DielineTool");
|
|
130
147
|
return;
|
|
131
148
|
}
|
|
149
|
+
this.renderProducerDisposable?.dispose();
|
|
150
|
+
this.renderProducerDisposable = this.canvasService.registerRenderProducer(
|
|
151
|
+
this.id,
|
|
152
|
+
() => ({
|
|
153
|
+
passes: [
|
|
154
|
+
{
|
|
155
|
+
id: DIELINE_LAYER_ID,
|
|
156
|
+
stack: 700,
|
|
157
|
+
order: 0,
|
|
158
|
+
replace: true,
|
|
159
|
+
visibility: {
|
|
160
|
+
op: "not",
|
|
161
|
+
expr: {
|
|
162
|
+
op: "activeToolIn",
|
|
163
|
+
ids: ["pooder.kit.image", "pooder.kit.white-ink"],
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
effects: this.effects,
|
|
167
|
+
objects: this.specs,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
}),
|
|
171
|
+
{ priority: 250 },
|
|
172
|
+
);
|
|
132
173
|
|
|
133
174
|
const configService = context.services.get<ConfigurationService>(
|
|
134
175
|
"ConfigurationService",
|
|
@@ -137,8 +178,14 @@ export class DielineTool implements Extension {
|
|
|
137
178
|
// Load initial config
|
|
138
179
|
const s = this.state;
|
|
139
180
|
const sizeState = readSizeState(configService);
|
|
140
|
-
s.
|
|
141
|
-
|
|
181
|
+
s.shape = normalizeDielineShape(
|
|
182
|
+
configService.get("dieline.shape", s.shape),
|
|
183
|
+
s.shape,
|
|
184
|
+
);
|
|
185
|
+
s.shapeStyle = normalizeShapeStyle(
|
|
186
|
+
configService.get("dieline.shapeStyle", s.shapeStyle),
|
|
187
|
+
s.shapeStyle,
|
|
188
|
+
);
|
|
142
189
|
s.width = sizeState.actualWidthMm;
|
|
143
190
|
s.height = sizeState.actualHeightMm;
|
|
144
191
|
s.radius = parseLengthToMm(
|
|
@@ -187,10 +234,6 @@ export class DielineTool implements Extension {
|
|
|
187
234
|
);
|
|
188
235
|
|
|
189
236
|
s.insideColor = configService.get("dieline.insideColor", s.insideColor);
|
|
190
|
-
s.outsideColor = configService.get(
|
|
191
|
-
"dieline.outsideColor",
|
|
192
|
-
s.outsideColor,
|
|
193
|
-
);
|
|
194
237
|
s.showBleedLines = configService.get(
|
|
195
238
|
"dieline.showBleedLines",
|
|
196
239
|
s.showBleedLines,
|
|
@@ -216,7 +259,6 @@ export class DielineTool implements Extension {
|
|
|
216
259
|
configService.onAnyChange((e: { key: string; value: any }) => {
|
|
217
260
|
if (e.key.startsWith("size.")) {
|
|
218
261
|
const nextSize = readSizeState(configService);
|
|
219
|
-
s.displayUnit = nextSize.unit;
|
|
220
262
|
s.width = nextSize.actualWidthMm;
|
|
221
263
|
s.height = nextSize.actualHeightMm;
|
|
222
264
|
s.padding = nextSize.viewPadding;
|
|
@@ -233,7 +275,10 @@ export class DielineTool implements Extension {
|
|
|
233
275
|
if (e.key.startsWith("dieline.")) {
|
|
234
276
|
switch (e.key) {
|
|
235
277
|
case "dieline.shape":
|
|
236
|
-
s.shape = e.value;
|
|
278
|
+
s.shape = normalizeDielineShape(e.value, s.shape);
|
|
279
|
+
break;
|
|
280
|
+
case "dieline.shapeStyle":
|
|
281
|
+
s.shapeStyle = normalizeShapeStyle(e.value, s.shapeStyle);
|
|
237
282
|
break;
|
|
238
283
|
case "dieline.radius":
|
|
239
284
|
s.radius = parseLengthToMm(e.value, "mm");
|
|
@@ -268,9 +313,6 @@ export class DielineTool implements Extension {
|
|
|
268
313
|
case "dieline.insideColor":
|
|
269
314
|
s.insideColor = e.value;
|
|
270
315
|
break;
|
|
271
|
-
case "dieline.outsideColor":
|
|
272
|
-
s.outsideColor = e.value;
|
|
273
|
-
break;
|
|
274
316
|
case "dieline.showBleedLines":
|
|
275
317
|
s.showBleedLines = e.value;
|
|
276
318
|
break;
|
|
@@ -299,13 +341,19 @@ export class DielineTool implements Extension {
|
|
|
299
341
|
}
|
|
300
342
|
|
|
301
343
|
context.eventBus.on("canvas:resized", this.onCanvasResized);
|
|
302
|
-
this.createLayer();
|
|
303
344
|
this.updateDieline();
|
|
304
345
|
}
|
|
305
346
|
|
|
306
347
|
deactivate(context: ExtensionContext) {
|
|
307
348
|
context.eventBus.off("canvas:resized", this.onCanvasResized);
|
|
308
|
-
this.
|
|
349
|
+
this.renderSeq += 1;
|
|
350
|
+
this.specs = [];
|
|
351
|
+
this.effects = [];
|
|
352
|
+
this.renderProducerDisposable?.dispose();
|
|
353
|
+
this.renderProducerDisposable = undefined;
|
|
354
|
+
if (this.canvasService) {
|
|
355
|
+
void this.canvasService.flushRenderFromProducers();
|
|
356
|
+
}
|
|
309
357
|
this.canvasService = undefined;
|
|
310
358
|
this.context = undefined;
|
|
311
359
|
}
|
|
@@ -329,7 +377,7 @@ export class DielineTool implements Extension {
|
|
|
329
377
|
id: "dieline.shape",
|
|
330
378
|
type: "select",
|
|
331
379
|
label: "Shape",
|
|
332
|
-
options:
|
|
380
|
+
options: Array.from(DIELINE_SHAPES),
|
|
333
381
|
default: s.shape,
|
|
334
382
|
},
|
|
335
383
|
{
|
|
@@ -340,6 +388,12 @@ export class DielineTool implements Extension {
|
|
|
340
388
|
max: 500,
|
|
341
389
|
default: s.radius,
|
|
342
390
|
},
|
|
391
|
+
{
|
|
392
|
+
id: "dieline.shapeStyle",
|
|
393
|
+
type: "json",
|
|
394
|
+
label: "Shape Style",
|
|
395
|
+
default: s.shapeStyle,
|
|
396
|
+
},
|
|
343
397
|
{
|
|
344
398
|
id: "dieline.showBleedLines",
|
|
345
399
|
type: "boolean",
|
|
@@ -412,12 +466,6 @@ export class DielineTool implements Extension {
|
|
|
412
466
|
label: "Inside Color",
|
|
413
467
|
default: s.insideColor,
|
|
414
468
|
},
|
|
415
|
-
{
|
|
416
|
-
id: "dieline.outsideColor",
|
|
417
|
-
type: "color",
|
|
418
|
-
label: "Outside Color",
|
|
419
|
-
default: s.outsideColor,
|
|
420
|
-
},
|
|
421
469
|
{
|
|
422
470
|
id: "dieline.features",
|
|
423
471
|
type: "json",
|
|
@@ -531,42 +579,6 @@ export class DielineTool implements Extension {
|
|
|
531
579
|
};
|
|
532
580
|
}
|
|
533
581
|
|
|
534
|
-
private getLayer() {
|
|
535
|
-
return this.canvasService?.getLayer("dieline-overlay");
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
private createLayer() {
|
|
539
|
-
if (!this.canvasService) return;
|
|
540
|
-
const width = this.canvasService.canvas.width || 800;
|
|
541
|
-
const height = this.canvasService.canvas.height || 600;
|
|
542
|
-
|
|
543
|
-
const layer = this.canvasService.createLayer("dieline-overlay", {
|
|
544
|
-
width,
|
|
545
|
-
height,
|
|
546
|
-
selectable: false,
|
|
547
|
-
evented: false,
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
this.canvasService.canvas.bringObjectToFront(layer);
|
|
551
|
-
|
|
552
|
-
// Ensure above user layer
|
|
553
|
-
const userLayer = this.canvasService.getLayer("user");
|
|
554
|
-
if (userLayer) {
|
|
555
|
-
const userIndex = this.canvasService.canvas
|
|
556
|
-
.getObjects()
|
|
557
|
-
.indexOf(userLayer);
|
|
558
|
-
this.canvasService.canvas.moveObjectTo(layer, userIndex + 1);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
private destroyLayer() {
|
|
563
|
-
if (!this.canvasService) return;
|
|
564
|
-
const layer = this.getLayer();
|
|
565
|
-
if (layer) {
|
|
566
|
-
this.canvasService.canvas.remove(layer);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
|
|
570
582
|
private createHatchPattern(color: string = "rgba(0, 0, 0, 0.3)") {
|
|
571
583
|
if (typeof document === "undefined") {
|
|
572
584
|
return undefined;
|
|
@@ -598,9 +610,15 @@ export class DielineTool implements Extension {
|
|
|
598
610
|
);
|
|
599
611
|
}
|
|
600
612
|
|
|
613
|
+
private hasImageItems(): boolean {
|
|
614
|
+
const configService = this.getConfigService();
|
|
615
|
+
if (!configService) return false;
|
|
616
|
+
const items = configService.get("image.items", []) as unknown;
|
|
617
|
+
return Array.isArray(items) && items.length > 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
601
620
|
private syncSizeState(configService: ConfigurationService) {
|
|
602
621
|
const sizeState = readSizeState(configService);
|
|
603
|
-
this.state.displayUnit = sizeState.unit;
|
|
604
622
|
this.state.width = sizeState.actualWidthMm;
|
|
605
623
|
this.state.height = sizeState.actualHeightMm;
|
|
606
624
|
this.state.padding = sizeState.viewPadding;
|
|
@@ -609,47 +627,28 @@ export class DielineTool implements Extension {
|
|
|
609
627
|
? sizeState.cutMarginMm
|
|
610
628
|
: sizeState.cutMode === "inset"
|
|
611
629
|
? -sizeState.cutMarginMm
|
|
612
|
-
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
private bringFeatureMarkersToFront() {
|
|
616
|
-
if (!this.canvasService) return;
|
|
617
|
-
const canvas = this.canvasService.canvas;
|
|
618
|
-
canvas
|
|
619
|
-
.getObjects()
|
|
620
|
-
.filter((obj: any) => obj?.data?.type === "feature-marker")
|
|
621
|
-
.forEach((obj: any) => canvas.bringObjectToFront(obj));
|
|
630
|
+
: 0;
|
|
622
631
|
}
|
|
623
632
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
if (!layer) return;
|
|
628
|
-
const configService = this.getConfigService();
|
|
629
|
-
if (!configService) return;
|
|
630
|
-
|
|
631
|
-
this.syncSizeState(configService);
|
|
632
|
-
const sceneLayout = computeSceneLayout(
|
|
633
|
-
this.canvasService,
|
|
634
|
-
readSizeState(configService),
|
|
635
|
-
);
|
|
636
|
-
if (!sceneLayout) return;
|
|
637
|
-
|
|
633
|
+
private buildDielineSpecs(
|
|
634
|
+
sceneLayout: NonNullable<ReturnType<typeof computeSceneLayout>>,
|
|
635
|
+
): RenderObjectSpec[] {
|
|
638
636
|
const {
|
|
639
637
|
shape,
|
|
638
|
+
shapeStyle,
|
|
640
639
|
radius,
|
|
641
640
|
mainLine,
|
|
642
641
|
offsetLine,
|
|
643
642
|
insideColor,
|
|
644
|
-
outsideColor,
|
|
645
643
|
showBleedLines,
|
|
646
644
|
features,
|
|
647
645
|
} = this.state;
|
|
646
|
+
const hasImages = this.hasImageItems();
|
|
648
647
|
|
|
649
648
|
const canvasW =
|
|
650
|
-
sceneLayout.canvasWidth || this.canvasService
|
|
649
|
+
sceneLayout.canvasWidth || this.canvasService?.canvas.width || 800;
|
|
651
650
|
const canvasH =
|
|
652
|
-
sceneLayout.canvasHeight || this.canvasService
|
|
651
|
+
sceneLayout.canvasHeight || this.canvasService?.canvas.height || 600;
|
|
653
652
|
const scale = sceneLayout.scale;
|
|
654
653
|
const cx = sceneLayout.trimRect.centerX;
|
|
655
654
|
const cy = sceneLayout.trimRect.centerY;
|
|
@@ -663,8 +662,6 @@ export class DielineTool implements Extension {
|
|
|
663
662
|
const cutR =
|
|
664
663
|
visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
665
664
|
|
|
666
|
-
layer.remove(...layer.getObjects());
|
|
667
|
-
|
|
668
665
|
const absoluteFeatures = (features || []).map((f) => ({
|
|
669
666
|
...f,
|
|
670
667
|
x: f.x,
|
|
@@ -675,36 +672,13 @@ export class DielineTool implements Extension {
|
|
|
675
672
|
}));
|
|
676
673
|
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
677
674
|
|
|
678
|
-
const
|
|
679
|
-
canvasWidth: canvasW,
|
|
680
|
-
canvasHeight: canvasH,
|
|
681
|
-
shape,
|
|
682
|
-
width: cutW,
|
|
683
|
-
height: cutH,
|
|
684
|
-
radius: cutR,
|
|
685
|
-
x: cx,
|
|
686
|
-
y: cy,
|
|
687
|
-
features: cutFeatures,
|
|
688
|
-
pathData: this.state.pathData,
|
|
689
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
690
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
691
|
-
});
|
|
692
|
-
const mask = new Path(maskPathData, {
|
|
693
|
-
fill: outsideColor,
|
|
694
|
-
stroke: null,
|
|
695
|
-
selectable: false,
|
|
696
|
-
evented: false,
|
|
697
|
-
originX: "left" as const,
|
|
698
|
-
originY: "top" as const,
|
|
699
|
-
left: 0,
|
|
700
|
-
top: 0,
|
|
701
|
-
});
|
|
702
|
-
layer.add(mask);
|
|
675
|
+
const specs: RenderObjectSpec[] = [];
|
|
703
676
|
|
|
704
677
|
if (
|
|
705
678
|
insideColor &&
|
|
706
679
|
insideColor !== "transparent" &&
|
|
707
|
-
insideColor !== "rgba(0,0,0,0)"
|
|
680
|
+
insideColor !== "rgba(0,0,0,0)" &&
|
|
681
|
+
!hasImages
|
|
708
682
|
) {
|
|
709
683
|
const productPathData = generateDielinePath({
|
|
710
684
|
shape,
|
|
@@ -714,6 +688,7 @@ export class DielineTool implements Extension {
|
|
|
714
688
|
x: cx,
|
|
715
689
|
y: cy,
|
|
716
690
|
features: cutFeatures,
|
|
691
|
+
shapeStyle,
|
|
717
692
|
pathData: this.state.pathData,
|
|
718
693
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
719
694
|
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
@@ -721,15 +696,21 @@ export class DielineTool implements Extension {
|
|
|
721
696
|
canvasHeight: canvasH,
|
|
722
697
|
});
|
|
723
698
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
699
|
+
specs.push({
|
|
700
|
+
id: "dieline.inside",
|
|
701
|
+
type: "path",
|
|
702
|
+
space: "screen",
|
|
703
|
+
data: { id: "dieline.inside", type: "dieline" },
|
|
704
|
+
props: {
|
|
705
|
+
pathData: productPathData,
|
|
706
|
+
fill: insideColor,
|
|
707
|
+
stroke: null,
|
|
708
|
+
selectable: false,
|
|
709
|
+
evented: false,
|
|
710
|
+
originX: "left",
|
|
711
|
+
originY: "top",
|
|
712
|
+
},
|
|
731
713
|
});
|
|
732
|
-
layer.add(insideObj);
|
|
733
714
|
}
|
|
734
715
|
|
|
735
716
|
if (Math.abs(visualOffset) > 0.0001) {
|
|
@@ -742,6 +723,7 @@ export class DielineTool implements Extension {
|
|
|
742
723
|
x: cx,
|
|
743
724
|
y: cy,
|
|
744
725
|
features: cutFeatures,
|
|
726
|
+
shapeStyle,
|
|
745
727
|
pathData: this.state.pathData,
|
|
746
728
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
747
729
|
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
@@ -756,6 +738,7 @@ export class DielineTool implements Extension {
|
|
|
756
738
|
x: cx,
|
|
757
739
|
y: cy,
|
|
758
740
|
features: cutFeatures,
|
|
741
|
+
shapeStyle,
|
|
759
742
|
pathData: this.state.pathData,
|
|
760
743
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
761
744
|
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
@@ -768,16 +751,22 @@ export class DielineTool implements Extension {
|
|
|
768
751
|
if (showBleedLines !== false) {
|
|
769
752
|
const pattern = this.createHatchPattern(mainLine.color);
|
|
770
753
|
if (pattern) {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
754
|
+
specs.push({
|
|
755
|
+
id: "dieline.bleed-zone",
|
|
756
|
+
type: "path",
|
|
757
|
+
space: "screen",
|
|
758
|
+
data: { id: "dieline.bleed-zone", type: "dieline" },
|
|
759
|
+
props: {
|
|
760
|
+
pathData: bleedPathData,
|
|
761
|
+
fill: pattern,
|
|
762
|
+
stroke: null,
|
|
763
|
+
selectable: false,
|
|
764
|
+
evented: false,
|
|
765
|
+
objectCaching: false,
|
|
766
|
+
originX: "left",
|
|
767
|
+
originY: "top",
|
|
768
|
+
},
|
|
779
769
|
});
|
|
780
|
-
layer.add(bleedObj);
|
|
781
770
|
}
|
|
782
771
|
}
|
|
783
772
|
|
|
@@ -789,6 +778,7 @@ export class DielineTool implements Extension {
|
|
|
789
778
|
x: cx,
|
|
790
779
|
y: cy,
|
|
791
780
|
features: cutFeatures,
|
|
781
|
+
shapeStyle,
|
|
792
782
|
pathData: this.state.pathData,
|
|
793
783
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
794
784
|
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
@@ -796,20 +786,26 @@ export class DielineTool implements Extension {
|
|
|
796
786
|
canvasHeight: canvasH,
|
|
797
787
|
});
|
|
798
788
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
789
|
+
specs.push({
|
|
790
|
+
id: "dieline.offset-border",
|
|
791
|
+
type: "path",
|
|
792
|
+
space: "screen",
|
|
793
|
+
data: { id: "dieline.offset-border", type: "dieline" },
|
|
794
|
+
props: {
|
|
795
|
+
pathData: offsetPathData,
|
|
796
|
+
fill: null,
|
|
797
|
+
stroke: offsetLine.style === "hidden" ? null : offsetLine.color,
|
|
798
|
+
strokeWidth: offsetLine.width,
|
|
799
|
+
strokeDashArray:
|
|
800
|
+
offsetLine.style === "dashed"
|
|
801
|
+
? [offsetLine.dashLength, offsetLine.dashLength]
|
|
802
|
+
: undefined,
|
|
803
|
+
selectable: false,
|
|
804
|
+
evented: false,
|
|
805
|
+
originX: "left",
|
|
806
|
+
originY: "top",
|
|
807
|
+
},
|
|
811
808
|
});
|
|
812
|
-
layer.add(offsetBorderObj);
|
|
813
809
|
}
|
|
814
810
|
|
|
815
811
|
const borderPathData = generateDielinePath({
|
|
@@ -820,49 +816,145 @@ export class DielineTool implements Extension {
|
|
|
820
816
|
x: cx,
|
|
821
817
|
y: cy,
|
|
822
818
|
features: absoluteFeatures,
|
|
819
|
+
shapeStyle,
|
|
823
820
|
pathData: this.state.pathData,
|
|
824
821
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
825
822
|
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
826
823
|
canvasWidth: canvasW,
|
|
827
824
|
canvasHeight: canvasH,
|
|
828
825
|
});
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
826
|
+
|
|
827
|
+
specs.push({
|
|
828
|
+
id: "dieline.border",
|
|
829
|
+
type: "path",
|
|
830
|
+
space: "screen",
|
|
831
|
+
data: { id: "dieline.border", type: "dieline" },
|
|
832
|
+
props: {
|
|
833
|
+
pathData: borderPathData,
|
|
834
|
+
fill: "transparent",
|
|
835
|
+
stroke: mainLine.style === "hidden" ? null : mainLine.color,
|
|
836
|
+
strokeWidth: mainLine.width,
|
|
837
|
+
strokeDashArray:
|
|
838
|
+
mainLine.style === "dashed"
|
|
839
|
+
? [mainLine.dashLength, mainLine.dashLength]
|
|
840
|
+
: undefined,
|
|
841
|
+
selectable: false,
|
|
842
|
+
evented: false,
|
|
843
|
+
originX: "left",
|
|
844
|
+
originY: "top",
|
|
845
|
+
},
|
|
841
846
|
});
|
|
842
|
-
layer.add(borderObj);
|
|
843
|
-
|
|
844
|
-
const userLayer = this.canvasService.getLayer("user");
|
|
845
|
-
if (layer && userLayer) {
|
|
846
|
-
const layerIndex = this.canvasService.canvas.getObjects().indexOf(layer);
|
|
847
|
-
const userIndex = this.canvasService.canvas
|
|
848
|
-
.getObjects()
|
|
849
|
-
.indexOf(userLayer);
|
|
850
|
-
if (layerIndex < userIndex) {
|
|
851
|
-
this.canvasService.canvas.moveObjectTo(layer, userIndex + 1);
|
|
852
|
-
}
|
|
853
|
-
} else {
|
|
854
|
-
this.canvasService.canvas.bringObjectToFront(layer);
|
|
855
|
-
}
|
|
856
847
|
|
|
857
|
-
|
|
858
|
-
|
|
848
|
+
return specs;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
private buildImageClipEffects(
|
|
852
|
+
sceneLayout: NonNullable<ReturnType<typeof computeSceneLayout>>,
|
|
853
|
+
): RenderEffectSpec[] {
|
|
854
|
+
const { shape, shapeStyle, radius, features } = this.state;
|
|
855
|
+
|
|
856
|
+
const canvasW =
|
|
857
|
+
sceneLayout.canvasWidth || this.canvasService?.canvas.width || 800;
|
|
858
|
+
const canvasH =
|
|
859
|
+
sceneLayout.canvasHeight || this.canvasService?.canvas.height || 600;
|
|
860
|
+
const scale = sceneLayout.scale;
|
|
861
|
+
const cx = sceneLayout.trimRect.centerX;
|
|
862
|
+
const cy = sceneLayout.trimRect.centerY;
|
|
863
|
+
|
|
864
|
+
const visualWidth = sceneLayout.trimRect.width;
|
|
865
|
+
const visualRadius = radius * scale;
|
|
866
|
+
const cutW = sceneLayout.cutRect.width;
|
|
867
|
+
const cutH = sceneLayout.cutRect.height;
|
|
868
|
+
const visualOffset = (cutW - visualWidth) / 2;
|
|
869
|
+
const cutR =
|
|
870
|
+
visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
859
871
|
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
872
|
+
const absoluteFeatures = (features || []).map((f) => ({
|
|
873
|
+
...f,
|
|
874
|
+
x: f.x,
|
|
875
|
+
y: f.y,
|
|
876
|
+
width: (f.width || 0) * scale,
|
|
877
|
+
height: (f.height || 0) * scale,
|
|
878
|
+
radius: (f.radius || 0) * scale,
|
|
879
|
+
}));
|
|
880
|
+
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
881
|
+
|
|
882
|
+
const clipPathData = generateDielinePath({
|
|
883
|
+
shape,
|
|
884
|
+
width: cutW,
|
|
885
|
+
height: cutH,
|
|
886
|
+
radius: cutR,
|
|
887
|
+
x: cx,
|
|
888
|
+
y: cy,
|
|
889
|
+
features: cutFeatures,
|
|
890
|
+
shapeStyle,
|
|
891
|
+
pathData: this.state.pathData,
|
|
892
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
893
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
894
|
+
canvasWidth: canvasW,
|
|
895
|
+
canvasHeight: canvasH,
|
|
896
|
+
});
|
|
897
|
+
if (!clipPathData) return [];
|
|
898
|
+
|
|
899
|
+
return [
|
|
900
|
+
{
|
|
901
|
+
type: "clipPath",
|
|
902
|
+
id: "dieline.clip.image",
|
|
903
|
+
targetPassIds: [IMAGE_OBJECT_LAYER_ID],
|
|
904
|
+
source: {
|
|
905
|
+
id: "dieline.effect.clip-path",
|
|
906
|
+
type: "path",
|
|
907
|
+
space: "screen",
|
|
908
|
+
data: {
|
|
909
|
+
id: "dieline.effect.clip-path",
|
|
910
|
+
type: "dieline-effect",
|
|
911
|
+
effect: "clipPath",
|
|
912
|
+
},
|
|
913
|
+
props: {
|
|
914
|
+
pathData: clipPathData,
|
|
915
|
+
fill: "#000000",
|
|
916
|
+
stroke: null,
|
|
917
|
+
originX: "left",
|
|
918
|
+
originY: "top",
|
|
919
|
+
selectable: false,
|
|
920
|
+
evented: false,
|
|
921
|
+
excludeFromExport: true,
|
|
922
|
+
},
|
|
923
|
+
},
|
|
924
|
+
},
|
|
925
|
+
];
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
public updateDieline(_emitEvent: boolean = true) {
|
|
929
|
+
void this.updateDielineAsync();
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
private async updateDielineAsync() {
|
|
933
|
+
if (!this.canvasService) return;
|
|
934
|
+
const configService = this.getConfigService();
|
|
935
|
+
if (!configService) return;
|
|
936
|
+
const seq = ++this.renderSeq;
|
|
937
|
+
|
|
938
|
+
this.syncSizeState(configService);
|
|
939
|
+
const sceneLayout = computeSceneLayout(
|
|
940
|
+
this.canvasService,
|
|
941
|
+
readSizeState(configService),
|
|
942
|
+
);
|
|
943
|
+
if (!sceneLayout) {
|
|
944
|
+
if (seq !== this.renderSeq) return;
|
|
945
|
+
this.specs = [];
|
|
946
|
+
this.effects = [];
|
|
947
|
+
await this.canvasService.flushRenderFromProducers();
|
|
948
|
+
return;
|
|
863
949
|
}
|
|
864
950
|
|
|
865
|
-
|
|
951
|
+
const nextSpecs = this.buildDielineSpecs(sceneLayout);
|
|
952
|
+
const nextEffects = this.buildImageClipEffects(sceneLayout);
|
|
953
|
+
if (seq !== this.renderSeq) return;
|
|
954
|
+
this.specs = nextSpecs;
|
|
955
|
+
this.effects = nextEffects;
|
|
956
|
+
await this.canvasService.flushRenderFromProducers();
|
|
957
|
+
if (seq !== this.renderSeq) return;
|
|
866
958
|
this.canvasService.requestRenderAll();
|
|
867
959
|
}
|
|
868
960
|
|
|
@@ -914,7 +1006,7 @@ export class DielineTool implements Extension {
|
|
|
914
1006
|
return null;
|
|
915
1007
|
}
|
|
916
1008
|
|
|
917
|
-
const { shape, radius, features, pathData } = this.state;
|
|
1009
|
+
const { shape, shapeStyle, radius, features, pathData } = this.state;
|
|
918
1010
|
const canvasW =
|
|
919
1011
|
sceneLayout.canvasWidth || this.canvasService.canvas.width || 800;
|
|
920
1012
|
const canvasH =
|
|
@@ -947,6 +1039,7 @@ export class DielineTool implements Extension {
|
|
|
947
1039
|
x: cx,
|
|
948
1040
|
y: cy,
|
|
949
1041
|
features: cutFeatures,
|
|
1042
|
+
shapeStyle,
|
|
950
1043
|
pathData,
|
|
951
1044
|
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
952
1045
|
customSourceHeightPx: this.state.customSourceHeightPx,
|