@pooder/kit 6.1.2 → 6.2.1
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/BackgroundTool.js +177 -5
- package/.test-dist/src/extensions/constraintUtils.js +44 -0
- package/.test-dist/src/extensions/dieline/DielineTool.js +52 -409
- package/.test-dist/src/extensions/dieline/featureResolution.js +29 -0
- package/.test-dist/src/extensions/dieline/model.js +83 -0
- package/.test-dist/src/extensions/dieline/renderBuilder.js +227 -0
- package/.test-dist/src/extensions/feature/FeatureTool.js +156 -45
- package/.test-dist/src/extensions/featureCoordinates.js +21 -0
- package/.test-dist/src/extensions/featurePlacement.js +46 -0
- package/.test-dist/src/extensions/image/ImageTool.js +281 -25
- package/.test-dist/src/extensions/ruler/RulerTool.js +24 -1
- package/.test-dist/src/shared/constants/layers.js +3 -1
- package/.test-dist/tests/run.js +25 -0
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +47 -13
- package/dist/index.d.ts +47 -13
- package/dist/index.js +1325 -977
- package/dist/index.mjs +1311 -966
- package/package.json +1 -1
- package/src/extensions/background/BackgroundTool.ts +264 -4
- package/src/extensions/dieline/DielineTool.ts +67 -548
- package/src/extensions/dieline/model.ts +165 -1
- package/src/extensions/dieline/renderBuilder.ts +301 -0
- package/src/extensions/feature/FeatureTool.ts +190 -47
- package/src/extensions/featureCoordinates.ts +35 -0
- package/src/extensions/featurePlacement.ts +118 -0
- package/src/extensions/image/ImageTool.ts +139 -157
- package/src/extensions/ruler/RulerTool.ts +24 -2
- package/src/shared/constants/layers.ts +2 -0
- package/tests/run.ts +37 -0
|
@@ -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,
|
|
@@ -13,6 +13,7 @@ const DEFAULT_FONT_SIZE = 10;
|
|
|
13
13
|
const DEFAULT_BACKGROUND_COLOR = "#f0f0f0";
|
|
14
14
|
const DEFAULT_TEXT_COLOR = "#333333";
|
|
15
15
|
const DEFAULT_LINE_COLOR = "#999999";
|
|
16
|
+
const RULER_DEBUG_KEY = "ruler.debug";
|
|
16
17
|
const RULER_THICKNESS_MIN = 10;
|
|
17
18
|
const RULER_THICKNESS_MAX = 100;
|
|
18
19
|
const RULER_GAP_MIN = 0;
|
|
@@ -31,6 +32,7 @@ class RulerTool {
|
|
|
31
32
|
this.textColor = DEFAULT_TEXT_COLOR;
|
|
32
33
|
this.lineColor = DEFAULT_LINE_COLOR;
|
|
33
34
|
this.fontSize = DEFAULT_FONT_SIZE;
|
|
35
|
+
this.debugEnabled = false;
|
|
34
36
|
this.renderSeq = 0;
|
|
35
37
|
this.numericProps = new Set(["thickness", "gap", "fontSize"]);
|
|
36
38
|
this.specs = [];
|
|
@@ -72,7 +74,15 @@ class RulerTool {
|
|
|
72
74
|
this.syncConfig(configService);
|
|
73
75
|
configService.onAnyChange((e) => {
|
|
74
76
|
let shouldUpdate = false;
|
|
75
|
-
if (e.key
|
|
77
|
+
if (e.key === RULER_DEBUG_KEY) {
|
|
78
|
+
this.debugEnabled = e.value === true;
|
|
79
|
+
this.log("config:update", {
|
|
80
|
+
key: e.key,
|
|
81
|
+
raw: e.value,
|
|
82
|
+
normalized: this.debugEnabled,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else if (e.key.startsWith("ruler.")) {
|
|
76
86
|
const prop = e.key.split(".")[1];
|
|
77
87
|
if (prop && prop in this) {
|
|
78
88
|
if (this.numericProps.has(prop)) {
|
|
@@ -158,6 +168,12 @@ class RulerTool {
|
|
|
158
168
|
max: RULER_FONT_SIZE_MAX,
|
|
159
169
|
default: DEFAULT_FONT_SIZE,
|
|
160
170
|
},
|
|
171
|
+
{
|
|
172
|
+
id: RULER_DEBUG_KEY,
|
|
173
|
+
type: "boolean",
|
|
174
|
+
label: "Ruler Debug Log",
|
|
175
|
+
default: false,
|
|
176
|
+
},
|
|
161
177
|
],
|
|
162
178
|
[core_1.ContributionPointIds.COMMANDS]: [
|
|
163
179
|
{
|
|
@@ -187,7 +203,12 @@ class RulerTool {
|
|
|
187
203
|
],
|
|
188
204
|
};
|
|
189
205
|
}
|
|
206
|
+
isDebugEnabled() {
|
|
207
|
+
return this.debugEnabled;
|
|
208
|
+
}
|
|
190
209
|
log(step, payload) {
|
|
210
|
+
if (!this.isDebugEnabled())
|
|
211
|
+
return;
|
|
191
212
|
if (payload) {
|
|
192
213
|
console.debug(`[RulerTool] ${step}`, payload);
|
|
193
214
|
return;
|
|
@@ -201,6 +222,8 @@ class RulerTool {
|
|
|
201
222
|
this.textColor = configService.get("ruler.textColor", this.textColor);
|
|
202
223
|
this.lineColor = configService.get("ruler.lineColor", this.lineColor);
|
|
203
224
|
this.fontSize = this.toFiniteNumber(configService.get("ruler.fontSize", this.fontSize), DEFAULT_FONT_SIZE);
|
|
225
|
+
this.debugEnabled =
|
|
226
|
+
configService.get(RULER_DEBUG_KEY, this.debugEnabled) === true;
|
|
204
227
|
this.log("config:loaded", {
|
|
205
228
|
thickness: this.thickness,
|
|
206
229
|
gap: this.gap,
|
|
@@ -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/.test-dist/tests/run.js
CHANGED
|
@@ -11,6 +11,7 @@ const commands_2 = require("../src/extensions/white-ink/commands");
|
|
|
11
11
|
const config_2 = require("../src/extensions/white-ink/config");
|
|
12
12
|
const commands_3 = require("../src/extensions/dieline/commands");
|
|
13
13
|
const config_3 = require("../src/extensions/dieline/config");
|
|
14
|
+
const featureCoordinates_1 = require("../src/extensions/featureCoordinates");
|
|
14
15
|
function assert(condition, message) {
|
|
15
16
|
if (!condition)
|
|
16
17
|
throw new Error(message);
|
|
@@ -91,6 +92,29 @@ function testEdgeScale() {
|
|
|
91
92
|
assert(width === 140, `expected width 140, got ${width}`);
|
|
92
93
|
assert(height === 80, `expected height 80, got ${height}`);
|
|
93
94
|
}
|
|
95
|
+
function testFeaturePlacementProjection() {
|
|
96
|
+
const trimGeometry = {
|
|
97
|
+
x: 100,
|
|
98
|
+
y: 120,
|
|
99
|
+
width: 120,
|
|
100
|
+
height: 180,
|
|
101
|
+
};
|
|
102
|
+
const cutGeometry = {
|
|
103
|
+
x: 100,
|
|
104
|
+
y: 120,
|
|
105
|
+
width: 150,
|
|
106
|
+
height: 210,
|
|
107
|
+
};
|
|
108
|
+
const trimFeature = {
|
|
109
|
+
x: 0.82,
|
|
110
|
+
y: 0.68,
|
|
111
|
+
};
|
|
112
|
+
const trimCenter = (0, featureCoordinates_1.resolveFeaturePosition)(trimFeature, trimGeometry);
|
|
113
|
+
const cutFeature = (0, featureCoordinates_1.normalizePointInGeometry)(trimCenter, cutGeometry);
|
|
114
|
+
const cutCenter = (0, featureCoordinates_1.resolveFeaturePosition)(cutFeature, cutGeometry);
|
|
115
|
+
assert(Math.abs(trimCenter.x - cutCenter.x) < 1e-6, `expected projected feature x to stay fixed, got ${trimCenter.x} vs ${cutCenter.x}`);
|
|
116
|
+
assert(Math.abs(trimCenter.y - cutCenter.y) < 1e-6, `expected projected feature y to stay fixed, got ${trimCenter.y} vs ${cutCenter.y}`);
|
|
117
|
+
}
|
|
94
118
|
function testVisibilityDsl() {
|
|
95
119
|
const layers = new Map([
|
|
96
120
|
["ruler-overlay", { exists: true, objectCount: 2 }],
|
|
@@ -259,6 +283,7 @@ function main() {
|
|
|
259
283
|
testBridgeSelection();
|
|
260
284
|
testMaskOps();
|
|
261
285
|
testEdgeScale();
|
|
286
|
+
testFeaturePlacementProjection();
|
|
262
287
|
testVisibilityDsl();
|
|
263
288
|
testContributionCompatibility();
|
|
264
289
|
console.log("ok");
|