@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
|
@@ -5,9 +5,11 @@ const core_1 = require("@pooder/core");
|
|
|
5
5
|
const fabric_1 = require("fabric");
|
|
6
6
|
const tracer_1 = require("./tracer");
|
|
7
7
|
const units_1 = require("../units");
|
|
8
|
+
const dielineShape_1 = require("./dielineShape");
|
|
8
9
|
const geometry_1 = require("./geometry");
|
|
9
10
|
const sceneLayoutModel_1 = require("./sceneLayoutModel");
|
|
10
11
|
const IMAGE_OBJECT_LAYER_ID = "image.user";
|
|
12
|
+
const DIELINE_LAYER_ID = "dieline-overlay";
|
|
11
13
|
class DielineTool {
|
|
12
14
|
constructor(options) {
|
|
13
15
|
this.id = "pooder.kit.dieline";
|
|
@@ -15,8 +17,8 @@ class DielineTool {
|
|
|
15
17
|
name: "DielineTool",
|
|
16
18
|
};
|
|
17
19
|
this.state = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
shape: dielineShape_1.DEFAULT_DIELINE_SHAPE,
|
|
21
|
+
shapeStyle: { ...dielineShape_1.DEFAULT_DIELINE_SHAPE_STYLE },
|
|
20
22
|
width: 500,
|
|
21
23
|
height: 500,
|
|
22
24
|
radius: 0,
|
|
@@ -35,10 +37,12 @@ class DielineTool {
|
|
|
35
37
|
style: "solid",
|
|
36
38
|
},
|
|
37
39
|
insideColor: "rgba(0,0,0,0)",
|
|
38
|
-
outsideColor: "#ffffff",
|
|
39
40
|
showBleedLines: true,
|
|
40
41
|
features: [],
|
|
41
42
|
};
|
|
43
|
+
this.specs = [];
|
|
44
|
+
this.effects = [];
|
|
45
|
+
this.renderSeq = 0;
|
|
42
46
|
this.onCanvasResized = () => {
|
|
43
47
|
this.updateDieline();
|
|
44
48
|
};
|
|
@@ -52,7 +56,12 @@ class DielineTool {
|
|
|
52
56
|
Object.assign(this.state.offsetLine, options.offsetLine);
|
|
53
57
|
delete options.offsetLine;
|
|
54
58
|
}
|
|
59
|
+
if (options.shapeStyle) {
|
|
60
|
+
this.state.shapeStyle = (0, dielineShape_1.normalizeShapeStyle)(options.shapeStyle, this.state.shapeStyle);
|
|
61
|
+
delete options.shapeStyle;
|
|
62
|
+
}
|
|
55
63
|
Object.assign(this.state, options);
|
|
64
|
+
this.state.shape = (0, dielineShape_1.normalizeDielineShape)(options.shape, this.state.shape);
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
67
|
activate(context) {
|
|
@@ -62,13 +71,33 @@ class DielineTool {
|
|
|
62
71
|
console.warn("CanvasService not found for DielineTool");
|
|
63
72
|
return;
|
|
64
73
|
}
|
|
74
|
+
this.renderProducerDisposable?.dispose();
|
|
75
|
+
this.renderProducerDisposable = this.canvasService.registerRenderProducer(this.id, () => ({
|
|
76
|
+
passes: [
|
|
77
|
+
{
|
|
78
|
+
id: DIELINE_LAYER_ID,
|
|
79
|
+
stack: 700,
|
|
80
|
+
order: 0,
|
|
81
|
+
replace: true,
|
|
82
|
+
visibility: {
|
|
83
|
+
op: "not",
|
|
84
|
+
expr: {
|
|
85
|
+
op: "activeToolIn",
|
|
86
|
+
ids: ["pooder.kit.image", "pooder.kit.white-ink"],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
effects: this.effects,
|
|
90
|
+
objects: this.specs,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
}), { priority: 250 });
|
|
65
94
|
const configService = context.services.get("ConfigurationService");
|
|
66
95
|
if (configService) {
|
|
67
96
|
// Load initial config
|
|
68
97
|
const s = this.state;
|
|
69
98
|
const sizeState = (0, sceneLayoutModel_1.readSizeState)(configService);
|
|
70
|
-
s.
|
|
71
|
-
s.
|
|
99
|
+
s.shape = (0, dielineShape_1.normalizeDielineShape)(configService.get("dieline.shape", s.shape), s.shape);
|
|
100
|
+
s.shapeStyle = (0, dielineShape_1.normalizeShapeStyle)(configService.get("dieline.shapeStyle", s.shapeStyle), s.shapeStyle);
|
|
72
101
|
s.width = sizeState.actualWidthMm;
|
|
73
102
|
s.height = sizeState.actualHeightMm;
|
|
74
103
|
s.radius = (0, units_1.parseLengthToMm)(configService.get("dieline.radius", s.radius), "mm");
|
|
@@ -90,15 +119,23 @@ class DielineTool {
|
|
|
90
119
|
s.offsetLine.dashLength = configService.get("dieline.offsetDashLength", s.offsetLine.dashLength);
|
|
91
120
|
s.offsetLine.style = configService.get("dieline.offsetStyle", s.offsetLine.style);
|
|
92
121
|
s.insideColor = configService.get("dieline.insideColor", s.insideColor);
|
|
93
|
-
s.outsideColor = configService.get("dieline.outsideColor", s.outsideColor);
|
|
94
122
|
s.showBleedLines = configService.get("dieline.showBleedLines", s.showBleedLines);
|
|
95
123
|
s.features = configService.get("dieline.features", s.features);
|
|
96
124
|
s.pathData = configService.get("dieline.pathData", s.pathData);
|
|
125
|
+
const sourceWidth = Number(configService.get("dieline.customSourceWidthPx", 0));
|
|
126
|
+
const sourceHeight = Number(configService.get("dieline.customSourceHeightPx", 0));
|
|
127
|
+
s.customSourceWidthPx =
|
|
128
|
+
Number.isFinite(sourceWidth) && sourceWidth > 0
|
|
129
|
+
? sourceWidth
|
|
130
|
+
: undefined;
|
|
131
|
+
s.customSourceHeightPx =
|
|
132
|
+
Number.isFinite(sourceHeight) && sourceHeight > 0
|
|
133
|
+
? sourceHeight
|
|
134
|
+
: undefined;
|
|
97
135
|
// Listen for changes
|
|
98
136
|
configService.onAnyChange((e) => {
|
|
99
137
|
if (e.key.startsWith("size.")) {
|
|
100
138
|
const nextSize = (0, sceneLayoutModel_1.readSizeState)(configService);
|
|
101
|
-
s.displayUnit = nextSize.unit;
|
|
102
139
|
s.width = nextSize.actualWidthMm;
|
|
103
140
|
s.height = nextSize.actualHeightMm;
|
|
104
141
|
s.padding = nextSize.viewPadding;
|
|
@@ -114,7 +151,10 @@ class DielineTool {
|
|
|
114
151
|
if (e.key.startsWith("dieline.")) {
|
|
115
152
|
switch (e.key) {
|
|
116
153
|
case "dieline.shape":
|
|
117
|
-
s.shape = e.value;
|
|
154
|
+
s.shape = (0, dielineShape_1.normalizeDielineShape)(e.value, s.shape);
|
|
155
|
+
break;
|
|
156
|
+
case "dieline.shapeStyle":
|
|
157
|
+
s.shapeStyle = (0, dielineShape_1.normalizeShapeStyle)(e.value, s.shapeStyle);
|
|
118
158
|
break;
|
|
119
159
|
case "dieline.radius":
|
|
120
160
|
s.radius = (0, units_1.parseLengthToMm)(e.value, "mm");
|
|
@@ -146,9 +186,6 @@ class DielineTool {
|
|
|
146
186
|
case "dieline.insideColor":
|
|
147
187
|
s.insideColor = e.value;
|
|
148
188
|
break;
|
|
149
|
-
case "dieline.outsideColor":
|
|
150
|
-
s.outsideColor = e.value;
|
|
151
|
-
break;
|
|
152
189
|
case "dieline.showBleedLines":
|
|
153
190
|
s.showBleedLines = e.value;
|
|
154
191
|
break;
|
|
@@ -158,18 +195,36 @@ class DielineTool {
|
|
|
158
195
|
case "dieline.pathData":
|
|
159
196
|
s.pathData = e.value;
|
|
160
197
|
break;
|
|
198
|
+
case "dieline.customSourceWidthPx":
|
|
199
|
+
s.customSourceWidthPx =
|
|
200
|
+
Number.isFinite(Number(e.value)) && Number(e.value) > 0
|
|
201
|
+
? Number(e.value)
|
|
202
|
+
: undefined;
|
|
203
|
+
break;
|
|
204
|
+
case "dieline.customSourceHeightPx":
|
|
205
|
+
s.customSourceHeightPx =
|
|
206
|
+
Number.isFinite(Number(e.value)) && Number(e.value) > 0
|
|
207
|
+
? Number(e.value)
|
|
208
|
+
: undefined;
|
|
209
|
+
break;
|
|
161
210
|
}
|
|
162
211
|
this.updateDieline();
|
|
163
212
|
}
|
|
164
213
|
});
|
|
165
214
|
}
|
|
166
215
|
context.eventBus.on("canvas:resized", this.onCanvasResized);
|
|
167
|
-
this.createLayer();
|
|
168
216
|
this.updateDieline();
|
|
169
217
|
}
|
|
170
218
|
deactivate(context) {
|
|
171
219
|
context.eventBus.off("canvas:resized", this.onCanvasResized);
|
|
172
|
-
this.
|
|
220
|
+
this.renderSeq += 1;
|
|
221
|
+
this.specs = [];
|
|
222
|
+
this.effects = [];
|
|
223
|
+
this.renderProducerDisposable?.dispose();
|
|
224
|
+
this.renderProducerDisposable = undefined;
|
|
225
|
+
if (this.canvasService) {
|
|
226
|
+
void this.canvasService.flushRenderFromProducers();
|
|
227
|
+
}
|
|
173
228
|
this.canvasService = undefined;
|
|
174
229
|
this.context = undefined;
|
|
175
230
|
}
|
|
@@ -192,7 +247,7 @@ class DielineTool {
|
|
|
192
247
|
id: "dieline.shape",
|
|
193
248
|
type: "select",
|
|
194
249
|
label: "Shape",
|
|
195
|
-
options:
|
|
250
|
+
options: Array.from(dielineShape_1.DIELINE_SHAPES),
|
|
196
251
|
default: s.shape,
|
|
197
252
|
},
|
|
198
253
|
{
|
|
@@ -203,6 +258,12 @@ class DielineTool {
|
|
|
203
258
|
max: 500,
|
|
204
259
|
default: s.radius,
|
|
205
260
|
},
|
|
261
|
+
{
|
|
262
|
+
id: "dieline.shapeStyle",
|
|
263
|
+
type: "json",
|
|
264
|
+
label: "Shape Style",
|
|
265
|
+
default: s.shapeStyle,
|
|
266
|
+
},
|
|
206
267
|
{
|
|
207
268
|
id: "dieline.showBleedLines",
|
|
208
269
|
type: "boolean",
|
|
@@ -275,12 +336,6 @@ class DielineTool {
|
|
|
275
336
|
label: "Inside Color",
|
|
276
337
|
default: s.insideColor,
|
|
277
338
|
},
|
|
278
|
-
{
|
|
279
|
-
id: "dieline.outsideColor",
|
|
280
|
-
type: "color",
|
|
281
|
-
label: "Outside Color",
|
|
282
|
-
default: s.outsideColor,
|
|
283
|
-
},
|
|
284
339
|
{
|
|
285
340
|
id: "dieline.features",
|
|
286
341
|
type: "json",
|
|
@@ -326,6 +381,13 @@ class DielineTool {
|
|
|
326
381
|
try {
|
|
327
382
|
const detectOptions = options || {};
|
|
328
383
|
const debug = detectOptions.debug === true;
|
|
384
|
+
const tracerOptions = {
|
|
385
|
+
expand: detectOptions.expand ?? 0,
|
|
386
|
+
smoothing: detectOptions.smoothing ?? true,
|
|
387
|
+
simplifyTolerance: detectOptions.simplifyTolerance ?? 2,
|
|
388
|
+
threshold: detectOptions.threshold,
|
|
389
|
+
debug,
|
|
390
|
+
};
|
|
329
391
|
// Helper to get image dimensions
|
|
330
392
|
const loadImage = (url) => {
|
|
331
393
|
return new Promise((resolve, reject) => {
|
|
@@ -338,7 +400,7 @@ class DielineTool {
|
|
|
338
400
|
};
|
|
339
401
|
const [img, traced] = await Promise.all([
|
|
340
402
|
loadImage(imageUrl),
|
|
341
|
-
tracer_1.ImageTracer.traceWithBounds(imageUrl,
|
|
403
|
+
tracer_1.ImageTracer.traceWithBounds(imageUrl, tracerOptions),
|
|
342
404
|
]);
|
|
343
405
|
const { pathData, baseBounds, bounds } = traced;
|
|
344
406
|
if (debug) {
|
|
@@ -349,21 +411,8 @@ class DielineTool {
|
|
|
349
411
|
expandedBounds: bounds,
|
|
350
412
|
currentDielineWidth: s.width,
|
|
351
413
|
currentDielineHeight: s.height,
|
|
352
|
-
options:
|
|
353
|
-
|
|
354
|
-
morphologyRadius: detectOptions.morphologyRadius,
|
|
355
|
-
connectRadiusMax: detectOptions.connectRadiusMax,
|
|
356
|
-
smoothing: detectOptions.smoothing,
|
|
357
|
-
simplifyTolerance: detectOptions.simplifyTolerance,
|
|
358
|
-
threshold: detectOptions.threshold,
|
|
359
|
-
maskMode: detectOptions.maskMode,
|
|
360
|
-
whiteThreshold: detectOptions.whiteThreshold,
|
|
361
|
-
alphaOpaqueCutoff: detectOptions.alphaOpaqueCutoff,
|
|
362
|
-
noChannels: detectOptions.noChannels,
|
|
363
|
-
componentMode: detectOptions.componentMode,
|
|
364
|
-
minComponentArea: detectOptions.minComponentArea,
|
|
365
|
-
forceConnected: detectOptions.forceConnected,
|
|
366
|
-
},
|
|
414
|
+
options: tracerOptions,
|
|
415
|
+
strategy: "single-connected-silhouette",
|
|
367
416
|
});
|
|
368
417
|
}
|
|
369
418
|
return {
|
|
@@ -383,38 +432,6 @@ class DielineTool {
|
|
|
383
432
|
],
|
|
384
433
|
};
|
|
385
434
|
}
|
|
386
|
-
getLayer() {
|
|
387
|
-
return this.canvasService?.getLayer("dieline-overlay");
|
|
388
|
-
}
|
|
389
|
-
createLayer() {
|
|
390
|
-
if (!this.canvasService)
|
|
391
|
-
return;
|
|
392
|
-
const width = this.canvasService.canvas.width || 800;
|
|
393
|
-
const height = this.canvasService.canvas.height || 600;
|
|
394
|
-
const layer = this.canvasService.createLayer("dieline-overlay", {
|
|
395
|
-
width,
|
|
396
|
-
height,
|
|
397
|
-
selectable: false,
|
|
398
|
-
evented: false,
|
|
399
|
-
});
|
|
400
|
-
this.canvasService.canvas.bringObjectToFront(layer);
|
|
401
|
-
// Ensure above user layer
|
|
402
|
-
const userLayer = this.canvasService.getLayer("user");
|
|
403
|
-
if (userLayer) {
|
|
404
|
-
const userIndex = this.canvasService.canvas
|
|
405
|
-
.getObjects()
|
|
406
|
-
.indexOf(userLayer);
|
|
407
|
-
this.canvasService.canvas.moveObjectTo(layer, userIndex + 1);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
destroyLayer() {
|
|
411
|
-
if (!this.canvasService)
|
|
412
|
-
return;
|
|
413
|
-
const layer = this.getLayer();
|
|
414
|
-
if (layer) {
|
|
415
|
-
this.canvasService.canvas.remove(layer);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
435
|
createHatchPattern(color = "rgba(0, 0, 0, 0.3)") {
|
|
419
436
|
if (typeof document === "undefined") {
|
|
420
437
|
return undefined;
|
|
@@ -441,9 +458,15 @@ class DielineTool {
|
|
|
441
458
|
getConfigService() {
|
|
442
459
|
return this.context?.services.get("ConfigurationService");
|
|
443
460
|
}
|
|
461
|
+
hasImageItems() {
|
|
462
|
+
const configService = this.getConfigService();
|
|
463
|
+
if (!configService)
|
|
464
|
+
return false;
|
|
465
|
+
const items = configService.get("image.items", []);
|
|
466
|
+
return Array.isArray(items) && items.length > 0;
|
|
467
|
+
}
|
|
444
468
|
syncSizeState(configService) {
|
|
445
469
|
const sizeState = (0, sceneLayoutModel_1.readSizeState)(configService);
|
|
446
|
-
this.state.displayUnit = sizeState.unit;
|
|
447
470
|
this.state.width = sizeState.actualWidthMm;
|
|
448
471
|
this.state.height = sizeState.actualHeightMm;
|
|
449
472
|
this.state.padding = sizeState.viewPadding;
|
|
@@ -454,31 +477,11 @@ class DielineTool {
|
|
|
454
477
|
? -sizeState.cutMarginMm
|
|
455
478
|
: 0;
|
|
456
479
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const
|
|
461
|
-
canvas
|
|
462
|
-
.getObjects()
|
|
463
|
-
.filter((obj) => obj?.data?.type === "feature-marker")
|
|
464
|
-
.forEach((obj) => canvas.bringObjectToFront(obj));
|
|
465
|
-
}
|
|
466
|
-
updateDieline(_emitEvent = true) {
|
|
467
|
-
if (!this.canvasService)
|
|
468
|
-
return;
|
|
469
|
-
const layer = this.getLayer();
|
|
470
|
-
if (!layer)
|
|
471
|
-
return;
|
|
472
|
-
const configService = this.getConfigService();
|
|
473
|
-
if (!configService)
|
|
474
|
-
return;
|
|
475
|
-
this.syncSizeState(configService);
|
|
476
|
-
const sceneLayout = (0, sceneLayoutModel_1.computeSceneLayout)(this.canvasService, (0, sceneLayoutModel_1.readSizeState)(configService));
|
|
477
|
-
if (!sceneLayout)
|
|
478
|
-
return;
|
|
479
|
-
const { shape, radius, mainLine, offsetLine, insideColor, outsideColor, showBleedLines, features, } = this.state;
|
|
480
|
-
const canvasW = sceneLayout.canvasWidth || this.canvasService.canvas.width || 800;
|
|
481
|
-
const canvasH = sceneLayout.canvasHeight || this.canvasService.canvas.height || 600;
|
|
480
|
+
buildDielineSpecs(sceneLayout) {
|
|
481
|
+
const { shape, shapeStyle, radius, mainLine, offsetLine, insideColor, showBleedLines, features, } = this.state;
|
|
482
|
+
const hasImages = this.hasImageItems();
|
|
483
|
+
const canvasW = sceneLayout.canvasWidth || this.canvasService?.canvas.width || 800;
|
|
484
|
+
const canvasH = sceneLayout.canvasHeight || this.canvasService?.canvas.height || 600;
|
|
482
485
|
const scale = sceneLayout.scale;
|
|
483
486
|
const cx = sceneLayout.trimRect.centerX;
|
|
484
487
|
const cy = sceneLayout.trimRect.centerY;
|
|
@@ -489,7 +492,6 @@ class DielineTool {
|
|
|
489
492
|
const cutH = sceneLayout.cutRect.height;
|
|
490
493
|
const visualOffset = (cutW - visualWidth) / 2;
|
|
491
494
|
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
492
|
-
layer.remove(...layer.getObjects());
|
|
493
495
|
const absoluteFeatures = (features || []).map((f) => ({
|
|
494
496
|
...f,
|
|
495
497
|
x: f.x,
|
|
@@ -499,32 +501,11 @@ class DielineTool {
|
|
|
499
501
|
radius: (f.radius || 0) * scale,
|
|
500
502
|
}));
|
|
501
503
|
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
502
|
-
const
|
|
503
|
-
canvasWidth: canvasW,
|
|
504
|
-
canvasHeight: canvasH,
|
|
505
|
-
shape,
|
|
506
|
-
width: cutW,
|
|
507
|
-
height: cutH,
|
|
508
|
-
radius: cutR,
|
|
509
|
-
x: cx,
|
|
510
|
-
y: cy,
|
|
511
|
-
features: cutFeatures,
|
|
512
|
-
pathData: this.state.pathData,
|
|
513
|
-
});
|
|
514
|
-
const mask = new fabric_1.Path(maskPathData, {
|
|
515
|
-
fill: outsideColor,
|
|
516
|
-
stroke: null,
|
|
517
|
-
selectable: false,
|
|
518
|
-
evented: false,
|
|
519
|
-
originX: "left",
|
|
520
|
-
originY: "top",
|
|
521
|
-
left: 0,
|
|
522
|
-
top: 0,
|
|
523
|
-
});
|
|
524
|
-
layer.add(mask);
|
|
504
|
+
const specs = [];
|
|
525
505
|
if (insideColor &&
|
|
526
506
|
insideColor !== "transparent" &&
|
|
527
|
-
insideColor !== "rgba(0,0,0,0)"
|
|
507
|
+
insideColor !== "rgba(0,0,0,0)" &&
|
|
508
|
+
!hasImages) {
|
|
528
509
|
const productPathData = (0, geometry_1.generateDielinePath)({
|
|
529
510
|
shape,
|
|
530
511
|
width: cutW,
|
|
@@ -533,19 +514,28 @@ class DielineTool {
|
|
|
533
514
|
x: cx,
|
|
534
515
|
y: cy,
|
|
535
516
|
features: cutFeatures,
|
|
517
|
+
shapeStyle,
|
|
536
518
|
pathData: this.state.pathData,
|
|
519
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
520
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
537
521
|
canvasWidth: canvasW,
|
|
538
522
|
canvasHeight: canvasH,
|
|
539
523
|
});
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
524
|
+
specs.push({
|
|
525
|
+
id: "dieline.inside",
|
|
526
|
+
type: "path",
|
|
527
|
+
space: "screen",
|
|
528
|
+
data: { id: "dieline.inside", type: "dieline" },
|
|
529
|
+
props: {
|
|
530
|
+
pathData: productPathData,
|
|
531
|
+
fill: insideColor,
|
|
532
|
+
stroke: null,
|
|
533
|
+
selectable: false,
|
|
534
|
+
evented: false,
|
|
535
|
+
originX: "left",
|
|
536
|
+
originY: "top",
|
|
537
|
+
},
|
|
547
538
|
});
|
|
548
|
-
layer.add(insideObj);
|
|
549
539
|
}
|
|
550
540
|
if (Math.abs(visualOffset) > 0.0001) {
|
|
551
541
|
const bleedPathData = (0, geometry_1.generateBleedZonePath)({
|
|
@@ -556,7 +546,10 @@ class DielineTool {
|
|
|
556
546
|
x: cx,
|
|
557
547
|
y: cy,
|
|
558
548
|
features: cutFeatures,
|
|
549
|
+
shapeStyle,
|
|
559
550
|
pathData: this.state.pathData,
|
|
551
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
552
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
560
553
|
canvasWidth: canvasW,
|
|
561
554
|
canvasHeight: canvasH,
|
|
562
555
|
}, {
|
|
@@ -567,23 +560,32 @@ class DielineTool {
|
|
|
567
560
|
x: cx,
|
|
568
561
|
y: cy,
|
|
569
562
|
features: cutFeatures,
|
|
563
|
+
shapeStyle,
|
|
570
564
|
pathData: this.state.pathData,
|
|
565
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
566
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
571
567
|
canvasWidth: canvasW,
|
|
572
568
|
canvasHeight: canvasH,
|
|
573
569
|
}, visualOffset);
|
|
574
570
|
if (showBleedLines !== false) {
|
|
575
571
|
const pattern = this.createHatchPattern(mainLine.color);
|
|
576
572
|
if (pattern) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
573
|
+
specs.push({
|
|
574
|
+
id: "dieline.bleed-zone",
|
|
575
|
+
type: "path",
|
|
576
|
+
space: "screen",
|
|
577
|
+
data: { id: "dieline.bleed-zone", type: "dieline" },
|
|
578
|
+
props: {
|
|
579
|
+
pathData: bleedPathData,
|
|
580
|
+
fill: pattern,
|
|
581
|
+
stroke: null,
|
|
582
|
+
selectable: false,
|
|
583
|
+
evented: false,
|
|
584
|
+
objectCaching: false,
|
|
585
|
+
originX: "left",
|
|
586
|
+
originY: "top",
|
|
587
|
+
},
|
|
585
588
|
});
|
|
586
|
-
layer.add(bleedObj);
|
|
587
589
|
}
|
|
588
590
|
}
|
|
589
591
|
const offsetPathData = (0, geometry_1.generateDielinePath)({
|
|
@@ -594,23 +596,32 @@ class DielineTool {
|
|
|
594
596
|
x: cx,
|
|
595
597
|
y: cy,
|
|
596
598
|
features: cutFeatures,
|
|
599
|
+
shapeStyle,
|
|
597
600
|
pathData: this.state.pathData,
|
|
601
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
602
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
598
603
|
canvasWidth: canvasW,
|
|
599
604
|
canvasHeight: canvasH,
|
|
600
605
|
});
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
:
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
606
|
+
specs.push({
|
|
607
|
+
id: "dieline.offset-border",
|
|
608
|
+
type: "path",
|
|
609
|
+
space: "screen",
|
|
610
|
+
data: { id: "dieline.offset-border", type: "dieline" },
|
|
611
|
+
props: {
|
|
612
|
+
pathData: offsetPathData,
|
|
613
|
+
fill: null,
|
|
614
|
+
stroke: offsetLine.style === "hidden" ? null : offsetLine.color,
|
|
615
|
+
strokeWidth: offsetLine.width,
|
|
616
|
+
strokeDashArray: offsetLine.style === "dashed"
|
|
617
|
+
? [offsetLine.dashLength, offsetLine.dashLength]
|
|
618
|
+
: undefined,
|
|
619
|
+
selectable: false,
|
|
620
|
+
evented: false,
|
|
621
|
+
originX: "left",
|
|
622
|
+
originY: "top",
|
|
623
|
+
},
|
|
612
624
|
});
|
|
613
|
-
layer.add(offsetBorderObj);
|
|
614
625
|
}
|
|
615
626
|
const borderPathData = (0, geometry_1.generateDielinePath)({
|
|
616
627
|
shape,
|
|
@@ -620,43 +631,130 @@ class DielineTool {
|
|
|
620
631
|
x: cx,
|
|
621
632
|
y: cy,
|
|
622
633
|
features: absoluteFeatures,
|
|
634
|
+
shapeStyle,
|
|
623
635
|
pathData: this.state.pathData,
|
|
636
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
637
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
624
638
|
canvasWidth: canvasW,
|
|
625
639
|
canvasHeight: canvasH,
|
|
626
640
|
});
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
:
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
641
|
+
specs.push({
|
|
642
|
+
id: "dieline.border",
|
|
643
|
+
type: "path",
|
|
644
|
+
space: "screen",
|
|
645
|
+
data: { id: "dieline.border", type: "dieline" },
|
|
646
|
+
props: {
|
|
647
|
+
pathData: borderPathData,
|
|
648
|
+
fill: "transparent",
|
|
649
|
+
stroke: mainLine.style === "hidden" ? null : mainLine.color,
|
|
650
|
+
strokeWidth: mainLine.width,
|
|
651
|
+
strokeDashArray: mainLine.style === "dashed"
|
|
652
|
+
? [mainLine.dashLength, mainLine.dashLength]
|
|
653
|
+
: undefined,
|
|
654
|
+
selectable: false,
|
|
655
|
+
evented: false,
|
|
656
|
+
originX: "left",
|
|
657
|
+
originY: "top",
|
|
658
|
+
},
|
|
638
659
|
});
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
660
|
+
return specs;
|
|
661
|
+
}
|
|
662
|
+
buildImageClipEffects(sceneLayout) {
|
|
663
|
+
const { shape, shapeStyle, radius, features } = this.state;
|
|
664
|
+
const canvasW = sceneLayout.canvasWidth || this.canvasService?.canvas.width || 800;
|
|
665
|
+
const canvasH = sceneLayout.canvasHeight || this.canvasService?.canvas.height || 600;
|
|
666
|
+
const scale = sceneLayout.scale;
|
|
667
|
+
const cx = sceneLayout.trimRect.centerX;
|
|
668
|
+
const cy = sceneLayout.trimRect.centerY;
|
|
669
|
+
const visualWidth = sceneLayout.trimRect.width;
|
|
670
|
+
const visualRadius = radius * scale;
|
|
671
|
+
const cutW = sceneLayout.cutRect.width;
|
|
672
|
+
const cutH = sceneLayout.cutRect.height;
|
|
673
|
+
const visualOffset = (cutW - visualWidth) / 2;
|
|
674
|
+
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
675
|
+
const absoluteFeatures = (features || []).map((f) => ({
|
|
676
|
+
...f,
|
|
677
|
+
x: f.x,
|
|
678
|
+
y: f.y,
|
|
679
|
+
width: (f.width || 0) * scale,
|
|
680
|
+
height: (f.height || 0) * scale,
|
|
681
|
+
radius: (f.radius || 0) * scale,
|
|
682
|
+
}));
|
|
683
|
+
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
684
|
+
const clipPathData = (0, geometry_1.generateDielinePath)({
|
|
685
|
+
shape,
|
|
686
|
+
width: cutW,
|
|
687
|
+
height: cutH,
|
|
688
|
+
radius: cutR,
|
|
689
|
+
x: cx,
|
|
690
|
+
y: cy,
|
|
691
|
+
features: cutFeatures,
|
|
692
|
+
shapeStyle,
|
|
693
|
+
pathData: this.state.pathData,
|
|
694
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
695
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
696
|
+
canvasWidth: canvasW,
|
|
697
|
+
canvasHeight: canvasH,
|
|
698
|
+
});
|
|
699
|
+
if (!clipPathData)
|
|
700
|
+
return [];
|
|
701
|
+
return [
|
|
702
|
+
{
|
|
703
|
+
type: "clipPath",
|
|
704
|
+
id: "dieline.clip.image",
|
|
705
|
+
targetPassIds: [IMAGE_OBJECT_LAYER_ID],
|
|
706
|
+
source: {
|
|
707
|
+
id: "dieline.effect.clip-path",
|
|
708
|
+
type: "path",
|
|
709
|
+
space: "screen",
|
|
710
|
+
data: {
|
|
711
|
+
id: "dieline.effect.clip-path",
|
|
712
|
+
type: "dieline-effect",
|
|
713
|
+
effect: "clipPath",
|
|
714
|
+
},
|
|
715
|
+
props: {
|
|
716
|
+
pathData: clipPathData,
|
|
717
|
+
fill: "#000000",
|
|
718
|
+
stroke: null,
|
|
719
|
+
originX: "left",
|
|
720
|
+
originY: "top",
|
|
721
|
+
selectable: false,
|
|
722
|
+
evented: false,
|
|
723
|
+
excludeFromExport: true,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
];
|
|
728
|
+
}
|
|
729
|
+
updateDieline(_emitEvent = true) {
|
|
730
|
+
void this.updateDielineAsync();
|
|
731
|
+
}
|
|
732
|
+
async updateDielineAsync() {
|
|
733
|
+
if (!this.canvasService)
|
|
734
|
+
return;
|
|
735
|
+
const configService = this.getConfigService();
|
|
736
|
+
if (!configService)
|
|
737
|
+
return;
|
|
738
|
+
const seq = ++this.renderSeq;
|
|
739
|
+
this.syncSizeState(configService);
|
|
740
|
+
const sceneLayout = (0, sceneLayoutModel_1.computeSceneLayout)(this.canvasService, (0, sceneLayoutModel_1.readSizeState)(configService));
|
|
741
|
+
if (!sceneLayout) {
|
|
742
|
+
if (seq !== this.renderSeq)
|
|
743
|
+
return;
|
|
744
|
+
this.specs = [];
|
|
745
|
+
this.effects = [];
|
|
746
|
+
await this.canvasService.flushRenderFromProducers();
|
|
747
|
+
return;
|
|
658
748
|
}
|
|
659
|
-
|
|
749
|
+
const nextSpecs = this.buildDielineSpecs(sceneLayout);
|
|
750
|
+
const nextEffects = this.buildImageClipEffects(sceneLayout);
|
|
751
|
+
if (seq !== this.renderSeq)
|
|
752
|
+
return;
|
|
753
|
+
this.specs = nextSpecs;
|
|
754
|
+
this.effects = nextEffects;
|
|
755
|
+
await this.canvasService.flushRenderFromProducers();
|
|
756
|
+
if (seq !== this.renderSeq)
|
|
757
|
+
return;
|
|
660
758
|
this.canvasService.requestRenderAll();
|
|
661
759
|
}
|
|
662
760
|
getGeometry() {
|
|
@@ -673,6 +771,8 @@ class DielineTool {
|
|
|
673
771
|
...sceneGeometry,
|
|
674
772
|
strokeWidth: this.state.mainLine.width,
|
|
675
773
|
pathData: this.state.pathData,
|
|
774
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
775
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
676
776
|
};
|
|
677
777
|
}
|
|
678
778
|
async exportCutImage(options) {
|
|
@@ -692,7 +792,7 @@ class DielineTool {
|
|
|
692
792
|
console.warn("[DielineTool] exportCutImage returned null: scene-layout-null");
|
|
693
793
|
return null;
|
|
694
794
|
}
|
|
695
|
-
const { shape, radius, features, pathData } = this.state;
|
|
795
|
+
const { shape, shapeStyle, radius, features, pathData } = this.state;
|
|
696
796
|
const canvasW = sceneLayout.canvasWidth || this.canvasService.canvas.width || 800;
|
|
697
797
|
const canvasH = sceneLayout.canvasHeight || this.canvasService.canvas.height || 600;
|
|
698
798
|
const scale = sceneLayout.scale;
|
|
@@ -720,7 +820,10 @@ class DielineTool {
|
|
|
720
820
|
x: cx,
|
|
721
821
|
y: cy,
|
|
722
822
|
features: cutFeatures,
|
|
823
|
+
shapeStyle,
|
|
723
824
|
pathData,
|
|
825
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
826
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
724
827
|
canvasWidth: canvasW,
|
|
725
828
|
canvasHeight: canvasH,
|
|
726
829
|
});
|