@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
package/dist/index.js
CHANGED
|
@@ -1075,13 +1075,15 @@ __export(index_exports, {
|
|
|
1075
1075
|
WhiteInkTool: () => WhiteInkTool,
|
|
1076
1076
|
computeImageCoverScale: () => getCoverScale,
|
|
1077
1077
|
computeWhiteInkCoverScale: () => getCoverScale,
|
|
1078
|
+
createDefaultDielineState: () => createDefaultDielineState,
|
|
1078
1079
|
createDielineCommands: () => createDielineCommands,
|
|
1079
1080
|
createDielineConfigurations: () => createDielineConfigurations,
|
|
1080
1081
|
createImageCommands: () => createImageCommands,
|
|
1081
1082
|
createImageConfigurations: () => createImageConfigurations,
|
|
1082
1083
|
createWhiteInkCommands: () => createWhiteInkCommands,
|
|
1083
1084
|
createWhiteInkConfigurations: () => createWhiteInkConfigurations,
|
|
1084
|
-
evaluateVisibilityExpr: () => evaluateVisibilityExpr
|
|
1085
|
+
evaluateVisibilityExpr: () => evaluateVisibilityExpr,
|
|
1086
|
+
readDielineState: () => readDielineState
|
|
1085
1087
|
});
|
|
1086
1088
|
module.exports = __toCommonJS(index_exports);
|
|
1087
1089
|
|
|
@@ -1485,6 +1487,7 @@ var WHITE_INK_OBJECT_LAYER_ID = "white-ink.user";
|
|
|
1485
1487
|
var WHITE_INK_COVER_LAYER_ID = "white-ink.cover";
|
|
1486
1488
|
var WHITE_INK_OVERLAY_LAYER_ID = "white-ink.overlay";
|
|
1487
1489
|
var DIELINE_LAYER_ID = "dieline-overlay";
|
|
1490
|
+
var FEATURE_DIELINE_LAYER_ID = "feature-dieline-overlay";
|
|
1488
1491
|
var FEATURE_OVERLAY_LAYER_ID = "feature-overlay";
|
|
1489
1492
|
var RULER_LAYER_ID = "ruler-overlay";
|
|
1490
1493
|
var FILM_LAYER_ID = "overlay";
|
|
@@ -1626,6 +1629,18 @@ function normalizeFitMode2(value, fallback) {
|
|
|
1626
1629
|
}
|
|
1627
1630
|
return fallback;
|
|
1628
1631
|
}
|
|
1632
|
+
function normalizeRegionUnit(value, fallback) {
|
|
1633
|
+
if (value === "px" || value === "normalized") {
|
|
1634
|
+
return value;
|
|
1635
|
+
}
|
|
1636
|
+
return fallback;
|
|
1637
|
+
}
|
|
1638
|
+
function normalizeRegistrationFrame(value, fallback) {
|
|
1639
|
+
if (value === "trim" || value === "cut" || value === "bleed" || value === "focus" || value === "viewport") {
|
|
1640
|
+
return value;
|
|
1641
|
+
}
|
|
1642
|
+
return fallback;
|
|
1643
|
+
}
|
|
1629
1644
|
function normalizeAnchor(value, fallback) {
|
|
1630
1645
|
if (typeof value !== "string") return fallback;
|
|
1631
1646
|
const trimmed = value.trim();
|
|
@@ -1636,6 +1651,63 @@ function normalizeOrder(value, fallback) {
|
|
|
1636
1651
|
if (!Number.isFinite(numeric)) return fallback;
|
|
1637
1652
|
return numeric;
|
|
1638
1653
|
}
|
|
1654
|
+
function normalizeRegionValue(value, fallback) {
|
|
1655
|
+
const numeric = Number(value);
|
|
1656
|
+
return Number.isFinite(numeric) ? numeric : fallback;
|
|
1657
|
+
}
|
|
1658
|
+
function normalizeRegistrationRegion(raw, fallback) {
|
|
1659
|
+
if (!raw || typeof raw !== "object") {
|
|
1660
|
+
return fallback ? { ...fallback } : void 0;
|
|
1661
|
+
}
|
|
1662
|
+
const input = raw;
|
|
1663
|
+
const base = fallback || {
|
|
1664
|
+
left: 0,
|
|
1665
|
+
top: 0,
|
|
1666
|
+
width: 1,
|
|
1667
|
+
height: 1,
|
|
1668
|
+
unit: "normalized"
|
|
1669
|
+
};
|
|
1670
|
+
return {
|
|
1671
|
+
left: normalizeRegionValue(input.left, base.left),
|
|
1672
|
+
top: normalizeRegionValue(input.top, base.top),
|
|
1673
|
+
width: normalizeRegionValue(input.width, base.width),
|
|
1674
|
+
height: normalizeRegionValue(input.height, base.height),
|
|
1675
|
+
unit: normalizeRegionUnit(input.unit, base.unit)
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
function normalizeRegistration(raw, fallback) {
|
|
1679
|
+
if (!raw || typeof raw !== "object") {
|
|
1680
|
+
return fallback ? {
|
|
1681
|
+
sourceRegion: fallback.sourceRegion ? { ...fallback.sourceRegion } : void 0,
|
|
1682
|
+
targetFrame: fallback.targetFrame,
|
|
1683
|
+
fit: fallback.fit
|
|
1684
|
+
} : void 0;
|
|
1685
|
+
}
|
|
1686
|
+
const input = raw;
|
|
1687
|
+
const normalized = {
|
|
1688
|
+
sourceRegion: normalizeRegistrationRegion(
|
|
1689
|
+
input.sourceRegion,
|
|
1690
|
+
fallback == null ? void 0 : fallback.sourceRegion
|
|
1691
|
+
),
|
|
1692
|
+
targetFrame: normalizeRegistrationFrame(
|
|
1693
|
+
input.targetFrame,
|
|
1694
|
+
(fallback == null ? void 0 : fallback.targetFrame) || "trim"
|
|
1695
|
+
),
|
|
1696
|
+
fit: normalizeFitMode2(input.fit, (fallback == null ? void 0 : fallback.fit) || "stretch")
|
|
1697
|
+
};
|
|
1698
|
+
if (!normalized.sourceRegion) {
|
|
1699
|
+
return void 0;
|
|
1700
|
+
}
|
|
1701
|
+
return normalized;
|
|
1702
|
+
}
|
|
1703
|
+
function cloneRegistration(registration) {
|
|
1704
|
+
if (!registration) return void 0;
|
|
1705
|
+
return {
|
|
1706
|
+
sourceRegion: registration.sourceRegion ? { ...registration.sourceRegion } : void 0,
|
|
1707
|
+
targetFrame: registration.targetFrame,
|
|
1708
|
+
fit: registration.fit
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1639
1711
|
function normalizeLayer(raw, index, fallback) {
|
|
1640
1712
|
const fallbackLayer = fallback || {
|
|
1641
1713
|
id: `layer-${index + 1}`,
|
|
@@ -1649,7 +1721,10 @@ function normalizeLayer(raw, index, fallback) {
|
|
|
1649
1721
|
src: ""
|
|
1650
1722
|
};
|
|
1651
1723
|
if (!raw || typeof raw !== "object") {
|
|
1652
|
-
return {
|
|
1724
|
+
return {
|
|
1725
|
+
...fallbackLayer,
|
|
1726
|
+
registration: cloneRegistration(fallbackLayer.registration)
|
|
1727
|
+
};
|
|
1653
1728
|
}
|
|
1654
1729
|
const input = raw;
|
|
1655
1730
|
const kind = normalizeLayerKind(input.kind, fallbackLayer.kind);
|
|
@@ -1663,7 +1738,8 @@ function normalizeLayer(raw, index, fallback) {
|
|
|
1663
1738
|
enabled: typeof input.enabled === "boolean" ? input.enabled : fallbackLayer.enabled,
|
|
1664
1739
|
exportable: typeof input.exportable === "boolean" ? input.exportable : fallbackLayer.exportable,
|
|
1665
1740
|
color: kind === "color" ? typeof input.color === "string" ? input.color : typeof fallbackLayer.color === "string" ? fallbackLayer.color : "#ffffff" : void 0,
|
|
1666
|
-
src: kind === "image" ? typeof input.src === "string" ? input.src.trim() : typeof fallbackLayer.src === "string" ? fallbackLayer.src : "" : void 0
|
|
1741
|
+
src: kind === "image" ? typeof input.src === "string" ? input.src.trim() : typeof fallbackLayer.src === "string" ? fallbackLayer.src : "" : void 0,
|
|
1742
|
+
registration: kind === "image" ? normalizeRegistration(input.registration, fallbackLayer.registration) : void 0
|
|
1667
1743
|
};
|
|
1668
1744
|
}
|
|
1669
1745
|
function normalizeConfig(raw) {
|
|
@@ -1693,7 +1769,10 @@ function normalizeConfig(raw) {
|
|
|
1693
1769
|
function cloneConfig(config) {
|
|
1694
1770
|
return {
|
|
1695
1771
|
version: config.version,
|
|
1696
|
-
layers: (config.layers || []).map((layer) => ({
|
|
1772
|
+
layers: (config.layers || []).map((layer) => ({
|
|
1773
|
+
...layer,
|
|
1774
|
+
registration: cloneRegistration(layer.registration)
|
|
1775
|
+
}))
|
|
1697
1776
|
};
|
|
1698
1777
|
}
|
|
1699
1778
|
function mergeConfig(base, patch) {
|
|
@@ -1944,6 +2023,41 @@ var BackgroundTool = class {
|
|
|
1944
2023
|
height: layout.trimRect.height
|
|
1945
2024
|
};
|
|
1946
2025
|
}
|
|
2026
|
+
resolveTargetFrameRect(frame) {
|
|
2027
|
+
if (frame === "viewport") {
|
|
2028
|
+
return this.getViewportRect();
|
|
2029
|
+
}
|
|
2030
|
+
const layout = this.resolveSceneLayout();
|
|
2031
|
+
if (!layout) {
|
|
2032
|
+
return frame === "focus" ? this.getViewportRect() : null;
|
|
2033
|
+
}
|
|
2034
|
+
switch (frame) {
|
|
2035
|
+
case "trim":
|
|
2036
|
+
case "focus":
|
|
2037
|
+
return {
|
|
2038
|
+
left: layout.trimRect.left,
|
|
2039
|
+
top: layout.trimRect.top,
|
|
2040
|
+
width: layout.trimRect.width,
|
|
2041
|
+
height: layout.trimRect.height
|
|
2042
|
+
};
|
|
2043
|
+
case "cut":
|
|
2044
|
+
return {
|
|
2045
|
+
left: layout.cutRect.left,
|
|
2046
|
+
top: layout.cutRect.top,
|
|
2047
|
+
width: layout.cutRect.width,
|
|
2048
|
+
height: layout.cutRect.height
|
|
2049
|
+
};
|
|
2050
|
+
case "bleed":
|
|
2051
|
+
return {
|
|
2052
|
+
left: layout.bleedRect.left,
|
|
2053
|
+
top: layout.bleedRect.top,
|
|
2054
|
+
width: layout.bleedRect.width,
|
|
2055
|
+
height: layout.bleedRect.height
|
|
2056
|
+
};
|
|
2057
|
+
default:
|
|
2058
|
+
return null;
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
1947
2061
|
resolveAnchorRect(anchor) {
|
|
1948
2062
|
if (anchor === "focus") {
|
|
1949
2063
|
return this.resolveFocusRect() || this.getViewportRect();
|
|
@@ -1976,6 +2090,53 @@ var BackgroundTool = class {
|
|
|
1976
2090
|
scaleY: scale
|
|
1977
2091
|
};
|
|
1978
2092
|
}
|
|
2093
|
+
resolveRegistrationRegion(region, sourceSize) {
|
|
2094
|
+
const sourceWidth = Math.max(1, Number(sourceSize.width || 0));
|
|
2095
|
+
const sourceHeight = Math.max(1, Number(sourceSize.height || 0));
|
|
2096
|
+
const width = region.unit === "normalized" ? region.width * sourceWidth : region.width;
|
|
2097
|
+
const height = region.unit === "normalized" ? region.height * sourceHeight : region.height;
|
|
2098
|
+
const left = region.unit === "normalized" ? region.left * sourceWidth : region.left;
|
|
2099
|
+
const top = region.unit === "normalized" ? region.top * sourceHeight : region.top;
|
|
2100
|
+
if (!Number.isFinite(left) || !Number.isFinite(top) || !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
|
|
2101
|
+
return null;
|
|
2102
|
+
}
|
|
2103
|
+
return { left, top, width, height };
|
|
2104
|
+
}
|
|
2105
|
+
resolveRegistrationPlacement(layer, sourceSize) {
|
|
2106
|
+
const registration = layer.registration;
|
|
2107
|
+
if (!(registration == null ? void 0 : registration.sourceRegion)) return null;
|
|
2108
|
+
const targetRect = this.resolveTargetFrameRect(
|
|
2109
|
+
registration.targetFrame || "trim"
|
|
2110
|
+
);
|
|
2111
|
+
if (!targetRect) return null;
|
|
2112
|
+
const sourceRegion = this.resolveRegistrationRegion(
|
|
2113
|
+
registration.sourceRegion,
|
|
2114
|
+
sourceSize
|
|
2115
|
+
);
|
|
2116
|
+
if (!sourceRegion) return null;
|
|
2117
|
+
const fit = registration.fit || "stretch";
|
|
2118
|
+
const baseScaleX = targetRect.width / sourceRegion.width;
|
|
2119
|
+
const baseScaleY = targetRect.height / sourceRegion.height;
|
|
2120
|
+
if (fit === "stretch") {
|
|
2121
|
+
return {
|
|
2122
|
+
left: targetRect.left - sourceRegion.left * baseScaleX,
|
|
2123
|
+
top: targetRect.top - sourceRegion.top * baseScaleY,
|
|
2124
|
+
scaleX: baseScaleX,
|
|
2125
|
+
scaleY: baseScaleY
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
const uniformScale = fit === "contain" ? Math.min(baseScaleX, baseScaleY) : Math.max(baseScaleX, baseScaleY);
|
|
2129
|
+
const alignedWidth = sourceRegion.width * uniformScale;
|
|
2130
|
+
const alignedHeight = sourceRegion.height * uniformScale;
|
|
2131
|
+
const offsetLeft = targetRect.left + (targetRect.width - alignedWidth) / 2;
|
|
2132
|
+
const offsetTop = targetRect.top + (targetRect.height - alignedHeight) / 2;
|
|
2133
|
+
return {
|
|
2134
|
+
left: offsetLeft - sourceRegion.left * uniformScale,
|
|
2135
|
+
top: offsetTop - sourceRegion.top * uniformScale,
|
|
2136
|
+
scaleX: uniformScale,
|
|
2137
|
+
scaleY: uniformScale
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
1979
2140
|
buildColorLayerSpec(layer) {
|
|
1980
2141
|
const rect = this.resolveAnchorRect(layer.anchor);
|
|
1981
2142
|
return {
|
|
@@ -2009,8 +2170,11 @@ var BackgroundTool = class {
|
|
|
2009
2170
|
if (!src) return [];
|
|
2010
2171
|
const sourceSize = this.sourceSizeCache.getSourceSize(src);
|
|
2011
2172
|
if (!sourceSize) return [];
|
|
2012
|
-
const
|
|
2013
|
-
|
|
2173
|
+
const placement = this.resolveRegistrationPlacement(layer, sourceSize) || this.resolveImagePlacement(
|
|
2174
|
+
this.resolveAnchorRect(layer.anchor),
|
|
2175
|
+
sourceSize,
|
|
2176
|
+
layer.fit
|
|
2177
|
+
);
|
|
2014
2178
|
return [
|
|
2015
2179
|
{
|
|
2016
2180
|
id: `background.layer.${layer.id}.image`,
|
|
@@ -3075,8 +3239,6 @@ var IMAGE_DEFAULT_CONTROL_CAPABILITIES = [
|
|
|
3075
3239
|
"scale"
|
|
3076
3240
|
];
|
|
3077
3241
|
var IMAGE_MOVE_SNAP_THRESHOLD_PX = 6;
|
|
3078
|
-
var IMAGE_MOVE_SNAP_RELEASE_THRESHOLD_PX = 10;
|
|
3079
|
-
var IMAGE_SNAP_GUIDE_LAYER_ID = "image.snapGuide";
|
|
3080
3242
|
var IMAGE_CONTROL_DESCRIPTORS = [
|
|
3081
3243
|
{
|
|
3082
3244
|
key: "tl",
|
|
@@ -3123,13 +3285,15 @@ var ImageTool = class {
|
|
|
3123
3285
|
this.overlaySpecs = [];
|
|
3124
3286
|
this.activeSnapX = null;
|
|
3125
3287
|
this.activeSnapY = null;
|
|
3288
|
+
this.movingImageId = null;
|
|
3289
|
+
this.hasRenderedSnapGuides = false;
|
|
3126
3290
|
this.subscriptions = new SubscriptionBag();
|
|
3127
3291
|
this.imageControlsByCapabilityKey = /* @__PURE__ */ new Map();
|
|
3128
3292
|
this.onToolActivated = (event) => {
|
|
3129
3293
|
const before = this.isToolActive;
|
|
3130
3294
|
this.syncToolActiveFromWorkbench(event.id);
|
|
3131
3295
|
if (!this.isToolActive) {
|
|
3132
|
-
this.
|
|
3296
|
+
this.endMoveSnapInteraction();
|
|
3133
3297
|
this.setImageFocus(null, {
|
|
3134
3298
|
syncCanvasSelection: true,
|
|
3135
3299
|
skipRender: true
|
|
@@ -3180,7 +3344,7 @@ var ImageTool = class {
|
|
|
3180
3344
|
this.updateImages();
|
|
3181
3345
|
};
|
|
3182
3346
|
this.onSelectionCleared = () => {
|
|
3183
|
-
this.
|
|
3347
|
+
this.endMoveSnapInteraction();
|
|
3184
3348
|
this.setImageFocus(null, {
|
|
3185
3349
|
syncCanvasSelection: false,
|
|
3186
3350
|
skipRender: true
|
|
@@ -3189,7 +3353,8 @@ var ImageTool = class {
|
|
|
3189
3353
|
this.updateImages();
|
|
3190
3354
|
};
|
|
3191
3355
|
this.onSceneLayoutChanged = () => {
|
|
3192
|
-
|
|
3356
|
+
var _a;
|
|
3357
|
+
(_a = this.canvasService) == null ? void 0 : _a.requestRenderAll();
|
|
3193
3358
|
this.updateImages();
|
|
3194
3359
|
};
|
|
3195
3360
|
this.onSceneGeometryChanged = () => {
|
|
@@ -3202,11 +3367,12 @@ var ImageTool = class {
|
|
|
3202
3367
|
const id = (_a = target == null ? void 0 : target.data) == null ? void 0 : _a.id;
|
|
3203
3368
|
const layerId = (_b = target == null ? void 0 : target.data) == null ? void 0 : _b.layerId;
|
|
3204
3369
|
if (typeof id !== "string" || layerId !== IMAGE_OBJECT_LAYER_ID) return;
|
|
3370
|
+
if (this.movingImageId === id) {
|
|
3371
|
+
this.applyMoveSnapToTarget(target);
|
|
3372
|
+
}
|
|
3205
3373
|
const frame = this.getFrameRect();
|
|
3374
|
+
this.endMoveSnapInteraction();
|
|
3206
3375
|
if (!frame.width || !frame.height) return;
|
|
3207
|
-
const matches = this.computeMoveSnapMatches(target, frame);
|
|
3208
|
-
this.applySnapMatchesToTarget(target, matches);
|
|
3209
|
-
this.clearSnapGuides();
|
|
3210
3376
|
const center = target.getCenterPoint ? target.getCenterPoint() : new import_fabric2.Point((_c = target.left) != null ? _c : 0, (_d = target.top) != null ? _d : 0);
|
|
3211
3377
|
const centerScene = this.canvasService ? this.canvasService.toScenePoint({ x: center.x, y: center.y }) : { x: center.x, y: center.y };
|
|
3212
3378
|
const objectScale = Number.isFinite(target == null ? void 0 : target.scaleX) ? target.scaleX : 1;
|
|
@@ -3347,7 +3513,7 @@ var ImageTool = class {
|
|
|
3347
3513
|
this.imageSpecs = [];
|
|
3348
3514
|
this.overlaySpecs = [];
|
|
3349
3515
|
this.imageControlsByCapabilityKey.clear();
|
|
3350
|
-
this.
|
|
3516
|
+
this.endMoveSnapInteraction();
|
|
3351
3517
|
this.unbindCanvasInteractionHandlers();
|
|
3352
3518
|
this.clearRenderedImages();
|
|
3353
3519
|
(_b = this.renderProducerDisposable) == null ? void 0 : _b.dispose();
|
|
@@ -3360,21 +3526,61 @@ var ImageTool = class {
|
|
|
3360
3526
|
}
|
|
3361
3527
|
bindCanvasInteractionHandlers() {
|
|
3362
3528
|
if (!this.canvasService || this.canvasObjectMovingHandler) return;
|
|
3529
|
+
this.canvasMouseUpHandler = (e) => {
|
|
3530
|
+
var _a;
|
|
3531
|
+
const target = this.getActiveImageTarget(e == null ? void 0 : e.target);
|
|
3532
|
+
if (target && typeof ((_a = target == null ? void 0 : target.data) == null ? void 0 : _a.id) === "string" && target.data.id === this.movingImageId) {
|
|
3533
|
+
this.applyMoveSnapToTarget(target);
|
|
3534
|
+
}
|
|
3535
|
+
this.endMoveSnapInteraction();
|
|
3536
|
+
};
|
|
3363
3537
|
this.canvasObjectMovingHandler = (e) => {
|
|
3364
3538
|
this.handleCanvasObjectMoving(e);
|
|
3365
3539
|
};
|
|
3540
|
+
this.canvasBeforeRenderHandler = () => {
|
|
3541
|
+
this.handleCanvasBeforeRender();
|
|
3542
|
+
};
|
|
3543
|
+
this.canvasAfterRenderHandler = () => {
|
|
3544
|
+
this.handleCanvasAfterRender();
|
|
3545
|
+
};
|
|
3546
|
+
this.canvasService.canvas.on("mouse:up", this.canvasMouseUpHandler);
|
|
3366
3547
|
this.canvasService.canvas.on(
|
|
3367
3548
|
"object:moving",
|
|
3368
3549
|
this.canvasObjectMovingHandler
|
|
3369
3550
|
);
|
|
3551
|
+
this.canvasService.canvas.on(
|
|
3552
|
+
"before:render",
|
|
3553
|
+
this.canvasBeforeRenderHandler
|
|
3554
|
+
);
|
|
3555
|
+
this.canvasService.canvas.on("after:render", this.canvasAfterRenderHandler);
|
|
3370
3556
|
}
|
|
3371
3557
|
unbindCanvasInteractionHandlers() {
|
|
3372
|
-
if (!this.canvasService
|
|
3373
|
-
this.
|
|
3374
|
-
"
|
|
3375
|
-
|
|
3376
|
-
)
|
|
3558
|
+
if (!this.canvasService) return;
|
|
3559
|
+
if (this.canvasMouseUpHandler) {
|
|
3560
|
+
this.canvasService.canvas.off("mouse:up", this.canvasMouseUpHandler);
|
|
3561
|
+
}
|
|
3562
|
+
if (this.canvasObjectMovingHandler) {
|
|
3563
|
+
this.canvasService.canvas.off(
|
|
3564
|
+
"object:moving",
|
|
3565
|
+
this.canvasObjectMovingHandler
|
|
3566
|
+
);
|
|
3567
|
+
}
|
|
3568
|
+
if (this.canvasBeforeRenderHandler) {
|
|
3569
|
+
this.canvasService.canvas.off(
|
|
3570
|
+
"before:render",
|
|
3571
|
+
this.canvasBeforeRenderHandler
|
|
3572
|
+
);
|
|
3573
|
+
}
|
|
3574
|
+
if (this.canvasAfterRenderHandler) {
|
|
3575
|
+
this.canvasService.canvas.off(
|
|
3576
|
+
"after:render",
|
|
3577
|
+
this.canvasAfterRenderHandler
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
this.canvasMouseUpHandler = void 0;
|
|
3377
3581
|
this.canvasObjectMovingHandler = void 0;
|
|
3582
|
+
this.canvasBeforeRenderHandler = void 0;
|
|
3583
|
+
this.canvasAfterRenderHandler = void 0;
|
|
3378
3584
|
}
|
|
3379
3585
|
getActiveImageTarget(target) {
|
|
3380
3586
|
var _a, _b;
|
|
@@ -3403,20 +3609,11 @@ var ImageTool = class {
|
|
|
3403
3609
|
if (!this.canvasService) return px;
|
|
3404
3610
|
return this.canvasService.toSceneLength(px);
|
|
3405
3611
|
}
|
|
3406
|
-
pickSnapMatch(candidates
|
|
3612
|
+
pickSnapMatch(candidates) {
|
|
3407
3613
|
if (!candidates.length) return null;
|
|
3408
3614
|
const snapThreshold = this.getSnapThresholdScene(
|
|
3409
3615
|
IMAGE_MOVE_SNAP_THRESHOLD_PX
|
|
3410
3616
|
);
|
|
3411
|
-
const releaseThreshold = this.getSnapThresholdScene(
|
|
3412
|
-
IMAGE_MOVE_SNAP_RELEASE_THRESHOLD_PX
|
|
3413
|
-
);
|
|
3414
|
-
if (previous) {
|
|
3415
|
-
const sticky = candidates.find((candidate) => {
|
|
3416
|
-
return candidate.lineId === previous.lineId && Math.abs(candidate.deltaScene) <= releaseThreshold;
|
|
3417
|
-
});
|
|
3418
|
-
if (sticky) return sticky;
|
|
3419
|
-
}
|
|
3420
3617
|
let best = null;
|
|
3421
3618
|
candidates.forEach((candidate) => {
|
|
3422
3619
|
if (Math.abs(candidate.deltaScene) > snapThreshold) return;
|
|
@@ -3426,8 +3623,7 @@ var ImageTool = class {
|
|
|
3426
3623
|
});
|
|
3427
3624
|
return best;
|
|
3428
3625
|
}
|
|
3429
|
-
computeMoveSnapMatches(
|
|
3430
|
-
const bounds = this.getTargetBoundsScene(target);
|
|
3626
|
+
computeMoveSnapMatches(bounds, frame) {
|
|
3431
3627
|
if (!bounds || frame.width <= 0 || frame.height <= 0) {
|
|
3432
3628
|
return { x: null, y: null };
|
|
3433
3629
|
}
|
|
@@ -3478,8 +3674,8 @@ var ImageTool = class {
|
|
|
3478
3674
|
}
|
|
3479
3675
|
];
|
|
3480
3676
|
return {
|
|
3481
|
-
x: this.pickSnapMatch(xCandidates
|
|
3482
|
-
y: this.pickSnapMatch(yCandidates
|
|
3677
|
+
x: this.pickSnapMatch(xCandidates),
|
|
3678
|
+
y: this.pickSnapMatch(yCandidates)
|
|
3483
3679
|
};
|
|
3484
3680
|
}
|
|
3485
3681
|
areSnapMatchesEqual(a, b) {
|
|
@@ -3488,136 +3684,123 @@ var ImageTool = class {
|
|
|
3488
3684
|
return a.lineId === b.lineId && a.axis === b.axis && a.kind === b.kind;
|
|
3489
3685
|
}
|
|
3490
3686
|
updateSnapMatchState(nextX, nextY) {
|
|
3687
|
+
var _a;
|
|
3491
3688
|
const changed = !this.areSnapMatchesEqual(this.activeSnapX, nextX) || !this.areSnapMatchesEqual(this.activeSnapY, nextY);
|
|
3492
3689
|
this.activeSnapX = nextX;
|
|
3493
3690
|
this.activeSnapY = nextY;
|
|
3494
3691
|
if (changed) {
|
|
3495
|
-
this.
|
|
3692
|
+
(_a = this.canvasService) == null ? void 0 : _a.requestRenderAll();
|
|
3496
3693
|
}
|
|
3497
3694
|
}
|
|
3498
|
-
|
|
3695
|
+
clearSnapPreview() {
|
|
3499
3696
|
var _a;
|
|
3500
3697
|
this.activeSnapX = null;
|
|
3501
3698
|
this.activeSnapY = null;
|
|
3502
|
-
this.
|
|
3503
|
-
this.removeSnapGuideObject("y");
|
|
3699
|
+
this.hasRenderedSnapGuides = false;
|
|
3504
3700
|
(_a = this.canvasService) == null ? void 0 : _a.requestRenderAll();
|
|
3505
3701
|
}
|
|
3506
|
-
|
|
3702
|
+
endMoveSnapInteraction() {
|
|
3703
|
+
this.movingImageId = null;
|
|
3704
|
+
this.clearSnapPreview();
|
|
3705
|
+
}
|
|
3706
|
+
applyMoveSnapToTarget(target) {
|
|
3707
|
+
var _a, _b, _c, _d;
|
|
3708
|
+
if (!this.canvasService) {
|
|
3709
|
+
return { x: null, y: null };
|
|
3710
|
+
}
|
|
3711
|
+
const frame = this.getFrameRect();
|
|
3712
|
+
if (frame.width <= 0 || frame.height <= 0) {
|
|
3713
|
+
return { x: null, y: null };
|
|
3714
|
+
}
|
|
3715
|
+
const bounds = this.getTargetBoundsScene(target);
|
|
3716
|
+
const matches = this.computeMoveSnapMatches(bounds, frame);
|
|
3717
|
+
const deltaScreenX = this.canvasService.toScreenLength(
|
|
3718
|
+
(_b = (_a = matches.x) == null ? void 0 : _a.deltaScene) != null ? _b : 0
|
|
3719
|
+
);
|
|
3720
|
+
const deltaScreenY = this.canvasService.toScreenLength(
|
|
3721
|
+
(_d = (_c = matches.y) == null ? void 0 : _c.deltaScene) != null ? _d : 0
|
|
3722
|
+
);
|
|
3723
|
+
if (deltaScreenX || deltaScreenY) {
|
|
3724
|
+
target.set({
|
|
3725
|
+
left: Number(target.left || 0) + deltaScreenX,
|
|
3726
|
+
top: Number(target.top || 0) + deltaScreenY
|
|
3727
|
+
});
|
|
3728
|
+
target.setCoords();
|
|
3729
|
+
}
|
|
3730
|
+
return matches;
|
|
3731
|
+
}
|
|
3732
|
+
handleCanvasBeforeRender() {
|
|
3507
3733
|
if (!this.canvasService) return;
|
|
3508
|
-
|
|
3509
|
-
const current = axis === "x" ? this.snapGuideXObject : this.snapGuideYObject;
|
|
3510
|
-
if (!current) return;
|
|
3511
|
-
canvas.remove(current);
|
|
3512
|
-
if (axis === "x") {
|
|
3513
|
-
this.snapGuideXObject = void 0;
|
|
3734
|
+
if (!this.hasRenderedSnapGuides && !this.activeSnapX && !this.activeSnapY) {
|
|
3514
3735
|
return;
|
|
3515
3736
|
}
|
|
3516
|
-
this.
|
|
3737
|
+
this.canvasService.canvas.clearContext(
|
|
3738
|
+
this.canvasService.canvas.contextTop
|
|
3739
|
+
);
|
|
3740
|
+
this.hasRenderedSnapGuides = false;
|
|
3517
3741
|
}
|
|
3518
|
-
|
|
3742
|
+
drawSnapGuideLine(from, to) {
|
|
3519
3743
|
if (!this.canvasService) return;
|
|
3520
|
-
const
|
|
3744
|
+
const ctx = this.canvasService.canvas.contextTop;
|
|
3745
|
+
if (!ctx) return;
|
|
3521
3746
|
const color = this.getConfig("image.control.borderColor", "#1677ff") || "#1677ff";
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
selectable: false,
|
|
3531
|
-
evented: false,
|
|
3532
|
-
excludeFromExport: true,
|
|
3533
|
-
objectCaching: false,
|
|
3534
|
-
data: {
|
|
3535
|
-
id: `${IMAGE_SNAP_GUIDE_LAYER_ID}.${axis}`,
|
|
3536
|
-
layerId: IMAGE_SNAP_GUIDE_LAYER_ID,
|
|
3537
|
-
type: "image-snap-guide"
|
|
3538
|
-
}
|
|
3539
|
-
});
|
|
3540
|
-
created.setCoords();
|
|
3541
|
-
canvas.add(created);
|
|
3542
|
-
canvas.bringObjectToFront(created);
|
|
3543
|
-
if (axis === "x") {
|
|
3544
|
-
this.snapGuideXObject = created;
|
|
3545
|
-
return;
|
|
3546
|
-
}
|
|
3547
|
-
this.snapGuideYObject = created;
|
|
3747
|
+
ctx.save();
|
|
3748
|
+
ctx.strokeStyle = color;
|
|
3749
|
+
ctx.lineWidth = 1;
|
|
3750
|
+
ctx.beginPath();
|
|
3751
|
+
ctx.moveTo(from.x, from.y);
|
|
3752
|
+
ctx.lineTo(to.x, to.y);
|
|
3753
|
+
ctx.stroke();
|
|
3754
|
+
ctx.restore();
|
|
3548
3755
|
}
|
|
3549
|
-
|
|
3756
|
+
handleCanvasAfterRender() {
|
|
3550
3757
|
if (!this.canvasService || !this.isImageEditingVisible()) {
|
|
3551
|
-
this.removeSnapGuideObject("x");
|
|
3552
|
-
this.removeSnapGuideObject("y");
|
|
3553
3758
|
return;
|
|
3554
3759
|
}
|
|
3555
3760
|
const frame = this.getFrameRect();
|
|
3556
3761
|
if (frame.width <= 0 || frame.height <= 0) {
|
|
3557
|
-
this.removeSnapGuideObject("x");
|
|
3558
|
-
this.removeSnapGuideObject("y");
|
|
3559
3762
|
return;
|
|
3560
3763
|
}
|
|
3561
3764
|
const frameScreen = this.getFrameRectScreen(frame);
|
|
3765
|
+
let drew = false;
|
|
3562
3766
|
if (this.activeSnapX) {
|
|
3563
3767
|
const x = this.canvasService.toScreenPoint({
|
|
3564
3768
|
x: this.activeSnapX.lineScene,
|
|
3565
3769
|
y: frame.top
|
|
3566
3770
|
}).x;
|
|
3567
|
-
this.
|
|
3568
|
-
|
|
3569
|
-
|
|
3771
|
+
this.drawSnapGuideLine(
|
|
3772
|
+
{ x, y: frameScreen.top },
|
|
3773
|
+
{ x, y: frameScreen.top + frameScreen.height }
|
|
3570
3774
|
);
|
|
3571
|
-
|
|
3572
|
-
this.removeSnapGuideObject("x");
|
|
3775
|
+
drew = true;
|
|
3573
3776
|
}
|
|
3574
3777
|
if (this.activeSnapY) {
|
|
3575
3778
|
const y = this.canvasService.toScreenPoint({
|
|
3576
3779
|
x: frame.left,
|
|
3577
3780
|
y: this.activeSnapY.lineScene
|
|
3578
3781
|
}).y;
|
|
3579
|
-
this.
|
|
3580
|
-
|
|
3581
|
-
|
|
3782
|
+
this.drawSnapGuideLine(
|
|
3783
|
+
{ x: frameScreen.left, y },
|
|
3784
|
+
{ x: frameScreen.left + frameScreen.width, y }
|
|
3582
3785
|
);
|
|
3583
|
-
|
|
3584
|
-
this.removeSnapGuideObject("y");
|
|
3786
|
+
drew = true;
|
|
3585
3787
|
}
|
|
3586
|
-
this.
|
|
3788
|
+
this.hasRenderedSnapGuides = drew;
|
|
3587
3789
|
}
|
|
3588
3790
|
handleCanvasObjectMoving(e) {
|
|
3589
|
-
var _a
|
|
3791
|
+
var _a;
|
|
3590
3792
|
const target = this.getActiveImageTarget(e == null ? void 0 : e.target);
|
|
3591
3793
|
if (!target || !this.canvasService) return;
|
|
3794
|
+
this.movingImageId = typeof ((_a = target == null ? void 0 : target.data) == null ? void 0 : _a.id) === "string" ? target.data.id : null;
|
|
3592
3795
|
const frame = this.getFrameRect();
|
|
3593
3796
|
if (frame.width <= 0 || frame.height <= 0) {
|
|
3594
|
-
this.
|
|
3797
|
+
this.endMoveSnapInteraction();
|
|
3595
3798
|
return;
|
|
3596
3799
|
}
|
|
3597
|
-
const
|
|
3598
|
-
const
|
|
3599
|
-
const deltaY = (_d = (_c = matches.y) == null ? void 0 : _c.deltaScene) != null ? _d : 0;
|
|
3600
|
-
if (deltaX || deltaY) {
|
|
3601
|
-
target.set({
|
|
3602
|
-
left: Number(target.left || 0) + this.canvasService.toScreenLength(deltaX),
|
|
3603
|
-
top: Number(target.top || 0) + this.canvasService.toScreenLength(deltaY)
|
|
3604
|
-
});
|
|
3605
|
-
target.setCoords();
|
|
3606
|
-
}
|
|
3800
|
+
const rawBounds = this.getTargetBoundsScene(target);
|
|
3801
|
+
const matches = this.computeMoveSnapMatches(rawBounds, frame);
|
|
3607
3802
|
this.updateSnapMatchState(matches.x, matches.y);
|
|
3608
3803
|
}
|
|
3609
|
-
applySnapMatchesToTarget(target, matches) {
|
|
3610
|
-
var _a, _b, _c, _d;
|
|
3611
|
-
if (!this.canvasService || !target) return;
|
|
3612
|
-
const deltaX = (_b = (_a = matches.x) == null ? void 0 : _a.deltaScene) != null ? _b : 0;
|
|
3613
|
-
const deltaY = (_d = (_c = matches.y) == null ? void 0 : _c.deltaScene) != null ? _d : 0;
|
|
3614
|
-
if (!deltaX && !deltaY) return;
|
|
3615
|
-
target.set({
|
|
3616
|
-
left: Number(target.left || 0) + this.canvasService.toScreenLength(deltaX),
|
|
3617
|
-
top: Number(target.top || 0) + this.canvasService.toScreenLength(deltaY)
|
|
3618
|
-
});
|
|
3619
|
-
target.setCoords();
|
|
3620
|
-
}
|
|
3621
3804
|
syncToolActiveFromWorkbench(fallbackId) {
|
|
3622
3805
|
var _a;
|
|
3623
3806
|
const wb = (_a = this.context) == null ? void 0 : _a.services.get("WorkbenchService");
|
|
@@ -4241,33 +4424,9 @@ var ImageTool = class {
|
|
|
4241
4424
|
originY: "top",
|
|
4242
4425
|
fill: hatchFill,
|
|
4243
4426
|
opacity: patternFill ? 1 : 0.8,
|
|
4244
|
-
stroke: null,
|
|
4245
|
-
fillRule: "evenodd",
|
|
4246
|
-
selectable: false,
|
|
4247
|
-
evented: false,
|
|
4248
|
-
excludeFromExport: true,
|
|
4249
|
-
objectCaching: false
|
|
4250
|
-
}
|
|
4251
|
-
},
|
|
4252
|
-
{
|
|
4253
|
-
id: "image.cropShapePath",
|
|
4254
|
-
type: "path",
|
|
4255
|
-
data: { id: "image.cropShapePath", zIndex: 6 },
|
|
4256
|
-
layout: {
|
|
4257
|
-
reference: "custom",
|
|
4258
|
-
referenceRect: frameRect,
|
|
4259
|
-
alignX: "start",
|
|
4260
|
-
alignY: "start",
|
|
4261
|
-
offsetX: shapeBounds.x,
|
|
4262
|
-
offsetY: shapeBounds.y
|
|
4263
|
-
},
|
|
4264
|
-
props: {
|
|
4265
|
-
pathData: shapePathData,
|
|
4266
|
-
originX: "left",
|
|
4267
|
-
originY: "top",
|
|
4268
|
-
fill: "rgba(0,0,0,0)",
|
|
4269
4427
|
stroke: "rgba(255, 0, 0, 0.9)",
|
|
4270
4428
|
strokeWidth: (_b = (_a = this.canvasService) == null ? void 0 : _a.toSceneLength(1)) != null ? _b : 1,
|
|
4429
|
+
fillRule: "evenodd",
|
|
4271
4430
|
selectable: false,
|
|
4272
4431
|
evented: false,
|
|
4273
4432
|
excludeFromExport: true,
|
|
@@ -4604,7 +4763,6 @@ var ImageTool = class {
|
|
|
4604
4763
|
isImageSelectionActive: this.isImageSelectionActive,
|
|
4605
4764
|
focusedImageId: this.focusedImageId
|
|
4606
4765
|
});
|
|
4607
|
-
this.updateSnapGuideVisuals();
|
|
4608
4766
|
this.canvasService.requestRenderAll();
|
|
4609
4767
|
}
|
|
4610
4768
|
clampNormalized(value) {
|
|
@@ -5401,225 +5559,668 @@ function createDielineConfigurations(state) {
|
|
|
5401
5559
|
];
|
|
5402
5560
|
}
|
|
5403
5561
|
|
|
5404
|
-
// src/extensions/dieline/
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
this.renderSeq = 0;
|
|
5438
|
-
this.onCanvasResized = () => {
|
|
5439
|
-
this.updateDieline();
|
|
5440
|
-
};
|
|
5441
|
-
if (options) {
|
|
5442
|
-
if (options.mainLine) {
|
|
5443
|
-
Object.assign(this.state.mainLine, options.mainLine);
|
|
5444
|
-
delete options.mainLine;
|
|
5445
|
-
}
|
|
5446
|
-
if (options.offsetLine) {
|
|
5447
|
-
Object.assign(this.state.offsetLine, options.offsetLine);
|
|
5448
|
-
delete options.offsetLine;
|
|
5449
|
-
}
|
|
5450
|
-
if (options.shapeStyle) {
|
|
5451
|
-
this.state.shapeStyle = normalizeShapeStyle(
|
|
5452
|
-
options.shapeStyle,
|
|
5453
|
-
this.state.shapeStyle
|
|
5454
|
-
);
|
|
5455
|
-
delete options.shapeStyle;
|
|
5456
|
-
}
|
|
5457
|
-
Object.assign(this.state, options);
|
|
5458
|
-
this.state.shape = normalizeDielineShape(options.shape, this.state.shape);
|
|
5562
|
+
// src/extensions/dieline/model.ts
|
|
5563
|
+
function createDefaultDielineState() {
|
|
5564
|
+
return {
|
|
5565
|
+
shape: DEFAULT_DIELINE_SHAPE,
|
|
5566
|
+
shapeStyle: { ...DEFAULT_DIELINE_SHAPE_STYLE },
|
|
5567
|
+
width: 500,
|
|
5568
|
+
height: 500,
|
|
5569
|
+
radius: 0,
|
|
5570
|
+
offset: 0,
|
|
5571
|
+
padding: 140,
|
|
5572
|
+
mainLine: {
|
|
5573
|
+
width: 2.7,
|
|
5574
|
+
color: "#FF0000",
|
|
5575
|
+
dashLength: 5,
|
|
5576
|
+
style: "solid"
|
|
5577
|
+
},
|
|
5578
|
+
offsetLine: {
|
|
5579
|
+
width: 2.7,
|
|
5580
|
+
color: "#FF0000",
|
|
5581
|
+
dashLength: 5,
|
|
5582
|
+
style: "solid"
|
|
5583
|
+
},
|
|
5584
|
+
insideColor: "rgba(0,0,0,0)",
|
|
5585
|
+
showBleedLines: true,
|
|
5586
|
+
features: []
|
|
5587
|
+
};
|
|
5588
|
+
}
|
|
5589
|
+
function readDielineState(configService, fallback) {
|
|
5590
|
+
const base = createDefaultDielineState();
|
|
5591
|
+
if (fallback) {
|
|
5592
|
+
Object.assign(base, fallback);
|
|
5593
|
+
if (fallback.mainLine) {
|
|
5594
|
+
base.mainLine = { ...base.mainLine, ...fallback.mainLine };
|
|
5459
5595
|
}
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
var _a;
|
|
5463
|
-
this.context = context;
|
|
5464
|
-
this.canvasService = context.services.get("CanvasService");
|
|
5465
|
-
if (!this.canvasService) {
|
|
5466
|
-
console.warn("CanvasService not found for DielineTool");
|
|
5467
|
-
return;
|
|
5596
|
+
if (fallback.offsetLine) {
|
|
5597
|
+
base.offsetLine = { ...base.offsetLine, ...fallback.offsetLine };
|
|
5468
5598
|
}
|
|
5469
|
-
(
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
"
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
const s = this.state;
|
|
5498
|
-
const sizeState = readSizeState(configService);
|
|
5499
|
-
s.shape = normalizeDielineShape(
|
|
5500
|
-
configService.get("dieline.shape", s.shape),
|
|
5501
|
-
s.shape
|
|
5502
|
-
);
|
|
5503
|
-
s.shapeStyle = normalizeShapeStyle(
|
|
5504
|
-
configService.get("dieline.shapeStyle", s.shapeStyle),
|
|
5505
|
-
s.shapeStyle
|
|
5506
|
-
);
|
|
5507
|
-
s.width = sizeState.actualWidthMm;
|
|
5508
|
-
s.height = sizeState.actualHeightMm;
|
|
5509
|
-
s.radius = parseLengthToMm(
|
|
5510
|
-
configService.get("dieline.radius", s.radius),
|
|
5511
|
-
"mm"
|
|
5512
|
-
);
|
|
5513
|
-
s.padding = sizeState.viewPadding;
|
|
5514
|
-
s.offset = sizeState.cutMode === "outset" ? sizeState.cutMarginMm : sizeState.cutMode === "inset" ? -sizeState.cutMarginMm : 0;
|
|
5515
|
-
s.mainLine.width = configService.get(
|
|
5516
|
-
"dieline.strokeWidth",
|
|
5517
|
-
s.mainLine.width
|
|
5518
|
-
);
|
|
5519
|
-
s.mainLine.color = configService.get(
|
|
5520
|
-
"dieline.strokeColor",
|
|
5521
|
-
s.mainLine.color
|
|
5522
|
-
);
|
|
5523
|
-
s.mainLine.dashLength = configService.get(
|
|
5599
|
+
if (fallback.shapeStyle) {
|
|
5600
|
+
base.shapeStyle = normalizeShapeStyle(fallback.shapeStyle, base.shapeStyle);
|
|
5601
|
+
}
|
|
5602
|
+
}
|
|
5603
|
+
const sizeState = readSizeState(configService);
|
|
5604
|
+
const sourceWidth = Number(configService.get("dieline.customSourceWidthPx", 0));
|
|
5605
|
+
const sourceHeight = Number(
|
|
5606
|
+
configService.get("dieline.customSourceHeightPx", 0)
|
|
5607
|
+
);
|
|
5608
|
+
return {
|
|
5609
|
+
...base,
|
|
5610
|
+
shape: normalizeDielineShape(
|
|
5611
|
+
configService.get("dieline.shape", base.shape),
|
|
5612
|
+
base.shape
|
|
5613
|
+
),
|
|
5614
|
+
shapeStyle: normalizeShapeStyle(
|
|
5615
|
+
configService.get("dieline.shapeStyle", base.shapeStyle),
|
|
5616
|
+
base.shapeStyle
|
|
5617
|
+
),
|
|
5618
|
+
width: sizeState.actualWidthMm,
|
|
5619
|
+
height: sizeState.actualHeightMm,
|
|
5620
|
+
radius: parseLengthToMm(configService.get("dieline.radius", base.radius), "mm"),
|
|
5621
|
+
padding: sizeState.viewPadding,
|
|
5622
|
+
offset: sizeState.cutMode === "outset" ? sizeState.cutMarginMm : sizeState.cutMode === "inset" ? -sizeState.cutMarginMm : 0,
|
|
5623
|
+
mainLine: {
|
|
5624
|
+
width: configService.get("dieline.strokeWidth", base.mainLine.width),
|
|
5625
|
+
color: configService.get("dieline.strokeColor", base.mainLine.color),
|
|
5626
|
+
dashLength: configService.get(
|
|
5524
5627
|
"dieline.dashLength",
|
|
5525
|
-
|
|
5526
|
-
)
|
|
5527
|
-
|
|
5528
|
-
|
|
5628
|
+
base.mainLine.dashLength
|
|
5629
|
+
),
|
|
5630
|
+
style: configService.get("dieline.style", base.mainLine.style)
|
|
5631
|
+
},
|
|
5632
|
+
offsetLine: {
|
|
5633
|
+
width: configService.get(
|
|
5529
5634
|
"dieline.offsetStrokeWidth",
|
|
5530
|
-
|
|
5531
|
-
)
|
|
5532
|
-
|
|
5635
|
+
base.offsetLine.width
|
|
5636
|
+
),
|
|
5637
|
+
color: configService.get(
|
|
5533
5638
|
"dieline.offsetStrokeColor",
|
|
5534
|
-
|
|
5535
|
-
)
|
|
5536
|
-
|
|
5639
|
+
base.offsetLine.color
|
|
5640
|
+
),
|
|
5641
|
+
dashLength: configService.get(
|
|
5537
5642
|
"dieline.offsetDashLength",
|
|
5538
|
-
|
|
5539
|
-
)
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5643
|
+
base.offsetLine.dashLength
|
|
5644
|
+
),
|
|
5645
|
+
style: configService.get("dieline.offsetStyle", base.offsetLine.style)
|
|
5646
|
+
},
|
|
5647
|
+
insideColor: configService.get("dieline.insideColor", base.insideColor),
|
|
5648
|
+
showBleedLines: configService.get(
|
|
5649
|
+
"dieline.showBleedLines",
|
|
5650
|
+
base.showBleedLines
|
|
5651
|
+
),
|
|
5652
|
+
features: configService.get("dieline.features", base.features),
|
|
5653
|
+
pathData: configService.get("dieline.pathData", base.pathData),
|
|
5654
|
+
customSourceWidthPx: Number.isFinite(sourceWidth) && sourceWidth > 0 ? sourceWidth : void 0,
|
|
5655
|
+
customSourceHeightPx: Number.isFinite(sourceHeight) && sourceHeight > 0 ? sourceHeight : void 0
|
|
5656
|
+
};
|
|
5657
|
+
}
|
|
5658
|
+
|
|
5659
|
+
// src/extensions/constraints.ts
|
|
5660
|
+
var ConstraintRegistry = class {
|
|
5661
|
+
static register(type, handler) {
|
|
5662
|
+
this.handlers.set(type, handler);
|
|
5663
|
+
}
|
|
5664
|
+
static apply(x, y, feature, context, constraints) {
|
|
5665
|
+
const list = constraints || feature.constraints;
|
|
5666
|
+
if (!list || list.length === 0) {
|
|
5667
|
+
return { x, y };
|
|
5668
|
+
}
|
|
5669
|
+
let currentX = x;
|
|
5670
|
+
let currentY = y;
|
|
5671
|
+
for (const constraint of list) {
|
|
5672
|
+
const handler = this.handlers.get(constraint.type);
|
|
5673
|
+
if (handler) {
|
|
5674
|
+
const result = handler(currentX, currentY, feature, context, constraint.params || {});
|
|
5675
|
+
currentX = result.x;
|
|
5676
|
+
currentY = result.y;
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
return { x: currentX, y: currentY };
|
|
5680
|
+
}
|
|
5681
|
+
};
|
|
5682
|
+
ConstraintRegistry.handlers = /* @__PURE__ */ new Map();
|
|
5683
|
+
var pathConstraint = (x, y, feature, context, params) => {
|
|
5684
|
+
const { dielineWidth, dielineHeight, geometry } = context;
|
|
5685
|
+
if (!geometry) return { x, y };
|
|
5686
|
+
const minX = geometry.x - geometry.width / 2;
|
|
5687
|
+
const minY = geometry.y - geometry.height / 2;
|
|
5688
|
+
const absX = minX + x * geometry.width;
|
|
5689
|
+
const absY = minY + y * geometry.height;
|
|
5690
|
+
const nearest = getNearestPointOnDieline(
|
|
5691
|
+
{ x: absX, y: absY },
|
|
5692
|
+
geometry
|
|
5693
|
+
);
|
|
5694
|
+
let finalX = nearest.x;
|
|
5695
|
+
let finalY = nearest.y;
|
|
5696
|
+
const hasOffsetParams = params.minOffset !== void 0 || params.maxOffset !== void 0;
|
|
5697
|
+
if (hasOffsetParams && nearest.normal) {
|
|
5698
|
+
const dx = absX - nearest.x;
|
|
5699
|
+
const dy = absY - nearest.y;
|
|
5700
|
+
const nx2 = nearest.normal.x;
|
|
5701
|
+
const ny2 = nearest.normal.y;
|
|
5702
|
+
const dist = dx * nx2 + dy * ny2;
|
|
5703
|
+
const scale = dielineWidth > 0 ? geometry.width / dielineWidth : 1;
|
|
5704
|
+
const rawMin = params.minOffset !== void 0 ? params.minOffset : 0;
|
|
5705
|
+
const rawMax = params.maxOffset !== void 0 ? params.maxOffset : 0;
|
|
5706
|
+
const minOffset = rawMin * scale;
|
|
5707
|
+
const maxOffset = rawMax * scale;
|
|
5708
|
+
const clampedDist = Math.max(minOffset, Math.min(dist, maxOffset));
|
|
5709
|
+
finalX = nearest.x + nx2 * clampedDist;
|
|
5710
|
+
finalY = nearest.y + ny2 * clampedDist;
|
|
5711
|
+
}
|
|
5712
|
+
const nx = geometry.width > 0 ? (finalX - minX) / geometry.width : 0.5;
|
|
5713
|
+
const ny = geometry.height > 0 ? (finalY - minY) / geometry.height : 0.5;
|
|
5714
|
+
return { x: nx, y: ny };
|
|
5715
|
+
};
|
|
5716
|
+
var edgeConstraint = (x, y, feature, context, params) => {
|
|
5717
|
+
const { dielineWidth, dielineHeight } = context;
|
|
5718
|
+
const allowedEdges = params.allowedEdges || [
|
|
5719
|
+
"top",
|
|
5720
|
+
"bottom",
|
|
5721
|
+
"left",
|
|
5722
|
+
"right"
|
|
5723
|
+
];
|
|
5724
|
+
const confine = params.confine || false;
|
|
5725
|
+
const offset = params.offset || 0;
|
|
5726
|
+
const distances = [];
|
|
5727
|
+
if (allowedEdges.includes("top"))
|
|
5728
|
+
distances.push({ edge: "top", dist: y * dielineHeight });
|
|
5729
|
+
if (allowedEdges.includes("bottom"))
|
|
5730
|
+
distances.push({ edge: "bottom", dist: (1 - y) * dielineHeight });
|
|
5731
|
+
if (allowedEdges.includes("left"))
|
|
5732
|
+
distances.push({ edge: "left", dist: x * dielineWidth });
|
|
5733
|
+
if (allowedEdges.includes("right"))
|
|
5734
|
+
distances.push({ edge: "right", dist: (1 - x) * dielineWidth });
|
|
5735
|
+
if (distances.length === 0) return { x, y };
|
|
5736
|
+
distances.sort((a, b) => a.dist - b.dist);
|
|
5737
|
+
const nearest = distances[0].edge;
|
|
5738
|
+
let newX = x;
|
|
5739
|
+
let newY = y;
|
|
5740
|
+
const fw = feature.width || 0;
|
|
5741
|
+
const fh = feature.height || 0;
|
|
5742
|
+
switch (nearest) {
|
|
5743
|
+
case "top":
|
|
5744
|
+
newY = 0 + offset / dielineHeight;
|
|
5745
|
+
if (confine) {
|
|
5746
|
+
const minX = fw / 2 / dielineWidth;
|
|
5747
|
+
const maxX = 1 - minX;
|
|
5748
|
+
newX = Math.max(minX, Math.min(newX, maxX));
|
|
5749
|
+
}
|
|
5750
|
+
break;
|
|
5751
|
+
case "bottom":
|
|
5752
|
+
newY = 1 - offset / dielineHeight;
|
|
5753
|
+
if (confine) {
|
|
5754
|
+
const minX = fw / 2 / dielineWidth;
|
|
5755
|
+
const maxX = 1 - minX;
|
|
5756
|
+
newX = Math.max(minX, Math.min(newX, maxX));
|
|
5757
|
+
}
|
|
5758
|
+
break;
|
|
5759
|
+
case "left":
|
|
5760
|
+
newX = 0 + offset / dielineWidth;
|
|
5761
|
+
if (confine) {
|
|
5762
|
+
const minY = fh / 2 / dielineHeight;
|
|
5763
|
+
const maxY = 1 - minY;
|
|
5764
|
+
newY = Math.max(minY, Math.min(newY, maxY));
|
|
5765
|
+
}
|
|
5766
|
+
break;
|
|
5767
|
+
case "right":
|
|
5768
|
+
newX = 1 - offset / dielineWidth;
|
|
5769
|
+
if (confine) {
|
|
5770
|
+
const minY = fh / 2 / dielineHeight;
|
|
5771
|
+
const maxY = 1 - minY;
|
|
5772
|
+
newY = Math.max(minY, Math.min(newY, maxY));
|
|
5773
|
+
}
|
|
5774
|
+
break;
|
|
5775
|
+
}
|
|
5776
|
+
return { x: newX, y: newY };
|
|
5777
|
+
};
|
|
5778
|
+
var internalConstraint = (x, y, feature, context, params) => {
|
|
5779
|
+
const { dielineWidth, dielineHeight } = context;
|
|
5780
|
+
const margin = params.margin || 0;
|
|
5781
|
+
const fw = feature.width || 0;
|
|
5782
|
+
const fh = feature.height || 0;
|
|
5783
|
+
const minX = (margin + fw / 2) / dielineWidth;
|
|
5784
|
+
const maxX = 1 - (margin + fw / 2) / dielineWidth;
|
|
5785
|
+
const minY = (margin + fh / 2) / dielineHeight;
|
|
5786
|
+
const maxY = 1 - (margin + fh / 2) / dielineHeight;
|
|
5787
|
+
const clampedX = minX > maxX ? 0.5 : Math.max(minX, Math.min(x, maxX));
|
|
5788
|
+
const clampedY = minY > maxY ? 0.5 : Math.max(minY, Math.min(y, maxY));
|
|
5789
|
+
return { x: clampedX, y: clampedY };
|
|
5790
|
+
};
|
|
5791
|
+
var tangentBottomConstraint = (x, y, feature, context, params) => {
|
|
5792
|
+
const { dielineWidth, dielineHeight } = context;
|
|
5793
|
+
const gap = params.gap || 0;
|
|
5794
|
+
const confineX = params.confineX !== false;
|
|
5795
|
+
const extentY = feature.shape === "circle" ? feature.radius || 0 : (feature.height || 0) / 2;
|
|
5796
|
+
const newY = 1 + (extentY + gap) / dielineHeight;
|
|
5797
|
+
let newX = x;
|
|
5798
|
+
if (confineX) {
|
|
5799
|
+
const extentX = feature.shape === "circle" ? feature.radius || 0 : (feature.width || 0) / 2;
|
|
5800
|
+
const minX = extentX / dielineWidth;
|
|
5801
|
+
const maxX = 1 - extentX / dielineWidth;
|
|
5802
|
+
newX = minX > maxX ? 0.5 : Math.max(minX, Math.min(newX, maxX));
|
|
5803
|
+
}
|
|
5804
|
+
return { x: newX, y: newY };
|
|
5805
|
+
};
|
|
5806
|
+
var lowestTangentConstraint = (x, y, feature, context, params) => {
|
|
5807
|
+
const { dielineWidth, dielineHeight, geometry } = context;
|
|
5808
|
+
if (!geometry) return { x, y };
|
|
5809
|
+
const lowest = getLowestPointOnDieline(geometry);
|
|
5810
|
+
const minY = geometry.y - geometry.height / 2;
|
|
5811
|
+
const normY = (lowest.y - minY) / geometry.height;
|
|
5812
|
+
const gap = params.gap || 0;
|
|
5813
|
+
const confineX = params.confineX !== false;
|
|
5814
|
+
const extentY = feature.shape === "circle" ? feature.radius || 0 : (feature.height || 0) / 2;
|
|
5815
|
+
const newY = normY + (extentY + gap) / dielineHeight;
|
|
5816
|
+
let newX = x;
|
|
5817
|
+
if (confineX) {
|
|
5818
|
+
const extentX = feature.shape === "circle" ? feature.radius || 0 : (feature.width || 0) / 2;
|
|
5819
|
+
const minX = extentX / dielineWidth;
|
|
5820
|
+
const maxX = 1 - extentX / dielineWidth;
|
|
5821
|
+
newX = minX > maxX ? 0.5 : Math.max(minX, Math.min(newX, maxX));
|
|
5822
|
+
}
|
|
5823
|
+
return { x: newX, y: newY };
|
|
5824
|
+
};
|
|
5825
|
+
ConstraintRegistry.register("path", pathConstraint);
|
|
5826
|
+
ConstraintRegistry.register("edge", edgeConstraint);
|
|
5827
|
+
ConstraintRegistry.register("internal", internalConstraint);
|
|
5828
|
+
ConstraintRegistry.register("tangent-bottom", tangentBottomConstraint);
|
|
5829
|
+
ConstraintRegistry.register("lowest-tangent", lowestTangentConstraint);
|
|
5830
|
+
|
|
5831
|
+
// src/extensions/featureCoordinates.ts
|
|
5832
|
+
function resolveFeaturePosition2(feature, geometry) {
|
|
5833
|
+
const { x, y, width, height } = geometry;
|
|
5834
|
+
const left = x - width / 2;
|
|
5835
|
+
const top = y - height / 2;
|
|
5836
|
+
return {
|
|
5837
|
+
x: left + feature.x * width,
|
|
5838
|
+
y: top + feature.y * height
|
|
5839
|
+
};
|
|
5840
|
+
}
|
|
5841
|
+
function normalizePointInGeometry(point, geometry) {
|
|
5842
|
+
const left = geometry.x - geometry.width / 2;
|
|
5843
|
+
const top = geometry.y - geometry.height / 2;
|
|
5844
|
+
return {
|
|
5845
|
+
x: geometry.width > 0 ? (point.x - left) / geometry.width : 0.5,
|
|
5846
|
+
y: geometry.height > 0 ? (point.y - top) / geometry.height : 0.5
|
|
5847
|
+
};
|
|
5848
|
+
}
|
|
5849
|
+
|
|
5850
|
+
// src/extensions/featurePlacement.ts
|
|
5851
|
+
function scaleFeatureForRender(feature, scale, x, y) {
|
|
5852
|
+
return {
|
|
5853
|
+
...feature,
|
|
5854
|
+
x,
|
|
5855
|
+
y,
|
|
5856
|
+
width: feature.width !== void 0 ? feature.width * scale : void 0,
|
|
5857
|
+
height: feature.height !== void 0 ? feature.height * scale : void 0,
|
|
5858
|
+
radius: feature.radius !== void 0 ? feature.radius * scale : void 0
|
|
5859
|
+
};
|
|
5860
|
+
}
|
|
5861
|
+
function resolveFeaturePlacements(features, geometry) {
|
|
5862
|
+
const dielineWidth = geometry.scale > 0 ? geometry.width / geometry.scale : geometry.width;
|
|
5863
|
+
const dielineHeight = geometry.scale > 0 ? geometry.height / geometry.scale : geometry.height;
|
|
5864
|
+
return (features || []).map((feature) => {
|
|
5865
|
+
var _a;
|
|
5866
|
+
const activeConstraints = (_a = feature.constraints) == null ? void 0 : _a.filter(
|
|
5867
|
+
(constraint) => !constraint.validateOnly
|
|
5868
|
+
);
|
|
5869
|
+
const constrained = ConstraintRegistry.apply(
|
|
5870
|
+
feature.x,
|
|
5871
|
+
feature.y,
|
|
5872
|
+
feature,
|
|
5873
|
+
{
|
|
5874
|
+
dielineWidth,
|
|
5875
|
+
dielineHeight,
|
|
5876
|
+
geometry
|
|
5877
|
+
},
|
|
5878
|
+
activeConstraints
|
|
5879
|
+
);
|
|
5880
|
+
const center = resolveFeaturePosition2(
|
|
5881
|
+
{
|
|
5882
|
+
...feature,
|
|
5883
|
+
x: constrained.x,
|
|
5884
|
+
y: constrained.y
|
|
5885
|
+
},
|
|
5886
|
+
geometry
|
|
5887
|
+
);
|
|
5888
|
+
return {
|
|
5889
|
+
feature,
|
|
5890
|
+
normalizedX: constrained.x,
|
|
5891
|
+
normalizedY: constrained.y,
|
|
5892
|
+
centerX: center.x,
|
|
5893
|
+
centerY: center.y
|
|
5894
|
+
};
|
|
5895
|
+
});
|
|
5896
|
+
}
|
|
5897
|
+
function projectPlacedFeatures(placements, geometry, scale) {
|
|
5898
|
+
return placements.map((placement) => {
|
|
5899
|
+
const normalized = normalizePointInGeometry(
|
|
5900
|
+
{ x: placement.centerX, y: placement.centerY },
|
|
5901
|
+
geometry
|
|
5902
|
+
);
|
|
5903
|
+
return scaleFeatureForRender(
|
|
5904
|
+
placement.feature,
|
|
5905
|
+
scale,
|
|
5906
|
+
normalized.x,
|
|
5907
|
+
normalized.y
|
|
5908
|
+
);
|
|
5909
|
+
});
|
|
5910
|
+
}
|
|
5911
|
+
|
|
5912
|
+
// src/extensions/dieline/renderBuilder.ts
|
|
5913
|
+
var DEFAULT_IDS = {
|
|
5914
|
+
inside: "dieline.inside",
|
|
5915
|
+
bleedZone: "dieline.bleed-zone",
|
|
5916
|
+
offsetBorder: "dieline.offset-border",
|
|
5917
|
+
border: "dieline.border",
|
|
5918
|
+
clip: "dieline.clip.image",
|
|
5919
|
+
clipSource: "dieline.effect.clip-path"
|
|
5920
|
+
};
|
|
5921
|
+
function buildDielineRenderBundle(options) {
|
|
5922
|
+
const ids = { ...DEFAULT_IDS, ...options.ids || {} };
|
|
5923
|
+
const {
|
|
5924
|
+
state,
|
|
5925
|
+
sceneLayout,
|
|
5926
|
+
canvasWidth,
|
|
5927
|
+
canvasHeight,
|
|
5928
|
+
hasImages,
|
|
5929
|
+
createHatchPattern,
|
|
5930
|
+
includeImageClipEffect = true,
|
|
5931
|
+
clipTargetPassIds = [IMAGE_OBJECT_LAYER_ID],
|
|
5932
|
+
clipVisibility
|
|
5933
|
+
} = options;
|
|
5934
|
+
const { shape, shapeStyle, radius, mainLine, offsetLine, insideColor } = state;
|
|
5935
|
+
const scale = sceneLayout.scale;
|
|
5936
|
+
const cx = sceneLayout.trimRect.centerX;
|
|
5937
|
+
const cy = sceneLayout.trimRect.centerY;
|
|
5938
|
+
const visualWidth = sceneLayout.trimRect.width;
|
|
5939
|
+
const visualHeight = sceneLayout.trimRect.height;
|
|
5940
|
+
const visualRadius = radius * scale;
|
|
5941
|
+
const cutW = sceneLayout.cutRect.width;
|
|
5942
|
+
const cutH = sceneLayout.cutRect.height;
|
|
5943
|
+
const visualOffset = (cutW - visualWidth) / 2;
|
|
5944
|
+
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
5945
|
+
const placements = resolveFeaturePlacements(state.features || [], {
|
|
5946
|
+
shape,
|
|
5947
|
+
shapeStyle,
|
|
5948
|
+
pathData: state.pathData,
|
|
5949
|
+
customSourceWidthPx: state.customSourceWidthPx,
|
|
5950
|
+
customSourceHeightPx: state.customSourceHeightPx,
|
|
5951
|
+
canvasWidth,
|
|
5952
|
+
canvasHeight,
|
|
5953
|
+
x: cx,
|
|
5954
|
+
y: cy,
|
|
5955
|
+
width: visualWidth,
|
|
5956
|
+
height: visualHeight,
|
|
5957
|
+
radius: visualRadius,
|
|
5958
|
+
scale
|
|
5959
|
+
});
|
|
5960
|
+
const absoluteFeatures = projectPlacedFeatures(
|
|
5961
|
+
placements,
|
|
5962
|
+
{
|
|
5963
|
+
x: cx,
|
|
5964
|
+
y: cy,
|
|
5965
|
+
width: visualWidth,
|
|
5966
|
+
height: visualHeight
|
|
5967
|
+
},
|
|
5968
|
+
scale
|
|
5969
|
+
);
|
|
5970
|
+
const cutFeatures = projectPlacedFeatures(
|
|
5971
|
+
placements.filter((placement) => !placement.feature.skipCut),
|
|
5972
|
+
{
|
|
5973
|
+
x: cx,
|
|
5974
|
+
y: cy,
|
|
5975
|
+
width: cutW,
|
|
5976
|
+
height: cutH
|
|
5977
|
+
},
|
|
5978
|
+
scale
|
|
5979
|
+
);
|
|
5980
|
+
const common = {
|
|
5981
|
+
shape,
|
|
5982
|
+
shapeStyle,
|
|
5983
|
+
pathData: state.pathData,
|
|
5984
|
+
customSourceWidthPx: state.customSourceWidthPx,
|
|
5985
|
+
customSourceHeightPx: state.customSourceHeightPx,
|
|
5986
|
+
canvasWidth,
|
|
5987
|
+
canvasHeight
|
|
5988
|
+
};
|
|
5989
|
+
const specs = [];
|
|
5990
|
+
if (insideColor && insideColor !== "transparent" && insideColor !== "rgba(0,0,0,0)" && !hasImages) {
|
|
5991
|
+
specs.push({
|
|
5992
|
+
id: ids.inside,
|
|
5993
|
+
type: "path",
|
|
5994
|
+
space: "screen",
|
|
5995
|
+
data: { id: ids.inside, type: "dieline" },
|
|
5996
|
+
props: {
|
|
5997
|
+
pathData: generateDielinePath({
|
|
5998
|
+
...common,
|
|
5999
|
+
width: cutW,
|
|
6000
|
+
height: cutH,
|
|
6001
|
+
radius: cutR,
|
|
6002
|
+
x: cx,
|
|
6003
|
+
y: cy,
|
|
6004
|
+
features: cutFeatures
|
|
6005
|
+
}),
|
|
6006
|
+
fill: insideColor,
|
|
6007
|
+
stroke: null,
|
|
6008
|
+
selectable: false,
|
|
6009
|
+
evented: false,
|
|
6010
|
+
originX: "left",
|
|
6011
|
+
originY: "top"
|
|
6012
|
+
}
|
|
6013
|
+
});
|
|
6014
|
+
}
|
|
6015
|
+
if (Math.abs(visualOffset) > 1e-4) {
|
|
6016
|
+
const trimPathInput = {
|
|
6017
|
+
...common,
|
|
6018
|
+
width: visualWidth,
|
|
6019
|
+
height: visualHeight,
|
|
6020
|
+
radius: visualRadius,
|
|
6021
|
+
x: cx,
|
|
6022
|
+
y: cy,
|
|
6023
|
+
features: cutFeatures
|
|
6024
|
+
};
|
|
6025
|
+
const cutPathInput = {
|
|
6026
|
+
...common,
|
|
6027
|
+
width: cutW,
|
|
6028
|
+
height: cutH,
|
|
6029
|
+
radius: cutR,
|
|
6030
|
+
x: cx,
|
|
6031
|
+
y: cy,
|
|
6032
|
+
features: cutFeatures
|
|
6033
|
+
};
|
|
6034
|
+
if (state.showBleedLines !== false) {
|
|
6035
|
+
const pattern = createHatchPattern == null ? void 0 : createHatchPattern(mainLine.color);
|
|
6036
|
+
if (pattern) {
|
|
6037
|
+
specs.push({
|
|
6038
|
+
id: ids.bleedZone,
|
|
6039
|
+
type: "path",
|
|
6040
|
+
space: "screen",
|
|
6041
|
+
data: { id: ids.bleedZone, type: "dieline" },
|
|
6042
|
+
props: {
|
|
6043
|
+
pathData: generateBleedZonePath(
|
|
6044
|
+
trimPathInput,
|
|
6045
|
+
cutPathInput,
|
|
6046
|
+
visualOffset
|
|
6047
|
+
),
|
|
6048
|
+
fill: pattern,
|
|
6049
|
+
stroke: null,
|
|
6050
|
+
selectable: false,
|
|
6051
|
+
evented: false,
|
|
6052
|
+
objectCaching: false,
|
|
6053
|
+
originX: "left",
|
|
6054
|
+
originY: "top"
|
|
6055
|
+
}
|
|
6056
|
+
});
|
|
6057
|
+
}
|
|
6058
|
+
}
|
|
6059
|
+
specs.push({
|
|
6060
|
+
id: ids.offsetBorder,
|
|
6061
|
+
type: "path",
|
|
6062
|
+
space: "screen",
|
|
6063
|
+
data: { id: ids.offsetBorder, type: "dieline" },
|
|
6064
|
+
props: {
|
|
6065
|
+
pathData: generateDielinePath(cutPathInput),
|
|
6066
|
+
fill: null,
|
|
6067
|
+
stroke: offsetLine.style === "hidden" ? null : offsetLine.color,
|
|
6068
|
+
strokeWidth: offsetLine.width,
|
|
6069
|
+
strokeDashArray: offsetLine.style === "dashed" ? [offsetLine.dashLength, offsetLine.dashLength] : void 0,
|
|
6070
|
+
selectable: false,
|
|
6071
|
+
evented: false,
|
|
6072
|
+
originX: "left",
|
|
6073
|
+
originY: "top"
|
|
6074
|
+
}
|
|
6075
|
+
});
|
|
6076
|
+
}
|
|
6077
|
+
specs.push({
|
|
6078
|
+
id: ids.border,
|
|
6079
|
+
type: "path",
|
|
6080
|
+
space: "screen",
|
|
6081
|
+
data: { id: ids.border, type: "dieline" },
|
|
6082
|
+
props: {
|
|
6083
|
+
pathData: generateDielinePath({
|
|
6084
|
+
...common,
|
|
6085
|
+
width: visualWidth,
|
|
6086
|
+
height: visualHeight,
|
|
6087
|
+
radius: visualRadius,
|
|
6088
|
+
x: cx,
|
|
6089
|
+
y: cy,
|
|
6090
|
+
features: absoluteFeatures
|
|
6091
|
+
}),
|
|
6092
|
+
fill: "transparent",
|
|
6093
|
+
stroke: mainLine.style === "hidden" ? null : mainLine.color,
|
|
6094
|
+
strokeWidth: mainLine.width,
|
|
6095
|
+
strokeDashArray: mainLine.style === "dashed" ? [mainLine.dashLength, mainLine.dashLength] : void 0,
|
|
6096
|
+
selectable: false,
|
|
6097
|
+
evented: false,
|
|
6098
|
+
originX: "left",
|
|
6099
|
+
originY: "top"
|
|
6100
|
+
}
|
|
6101
|
+
});
|
|
6102
|
+
if (!includeImageClipEffect) {
|
|
6103
|
+
return { specs, effects: [] };
|
|
6104
|
+
}
|
|
6105
|
+
const clipPathData = generateDielinePath({
|
|
6106
|
+
...common,
|
|
6107
|
+
width: cutW,
|
|
6108
|
+
height: cutH,
|
|
6109
|
+
radius: cutR,
|
|
6110
|
+
x: cx,
|
|
6111
|
+
y: cy,
|
|
6112
|
+
features: cutFeatures
|
|
6113
|
+
});
|
|
6114
|
+
if (!clipPathData) {
|
|
6115
|
+
return { specs, effects: [] };
|
|
6116
|
+
}
|
|
6117
|
+
return {
|
|
6118
|
+
specs,
|
|
6119
|
+
effects: [
|
|
6120
|
+
{
|
|
6121
|
+
type: "clipPath",
|
|
6122
|
+
id: ids.clip,
|
|
6123
|
+
visibility: clipVisibility,
|
|
6124
|
+
targetPassIds: clipTargetPassIds,
|
|
6125
|
+
source: {
|
|
6126
|
+
id: ids.clipSource,
|
|
6127
|
+
type: "path",
|
|
6128
|
+
space: "screen",
|
|
6129
|
+
data: {
|
|
6130
|
+
id: ids.clipSource,
|
|
6131
|
+
type: "dieline-effect",
|
|
6132
|
+
effect: "clipPath"
|
|
6133
|
+
},
|
|
6134
|
+
props: {
|
|
6135
|
+
pathData: clipPathData,
|
|
6136
|
+
fill: "#000000",
|
|
6137
|
+
stroke: null,
|
|
6138
|
+
originX: "left",
|
|
6139
|
+
originY: "top",
|
|
6140
|
+
selectable: false,
|
|
6141
|
+
evented: false,
|
|
6142
|
+
excludeFromExport: true
|
|
6143
|
+
}
|
|
5568
6144
|
}
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
6145
|
+
}
|
|
6146
|
+
]
|
|
6147
|
+
};
|
|
6148
|
+
}
|
|
6149
|
+
|
|
6150
|
+
// src/extensions/dieline/DielineTool.ts
|
|
6151
|
+
var DielineTool = class {
|
|
6152
|
+
constructor(options) {
|
|
6153
|
+
this.id = "pooder.kit.dieline";
|
|
6154
|
+
this.metadata = {
|
|
6155
|
+
name: "DielineTool"
|
|
6156
|
+
};
|
|
6157
|
+
this.state = createDefaultDielineState();
|
|
6158
|
+
this.specs = [];
|
|
6159
|
+
this.effects = [];
|
|
6160
|
+
this.renderSeq = 0;
|
|
6161
|
+
this.onCanvasResized = () => {
|
|
6162
|
+
this.updateDieline();
|
|
6163
|
+
};
|
|
6164
|
+
if (options) {
|
|
6165
|
+
if (options.mainLine) {
|
|
6166
|
+
Object.assign(this.state.mainLine, options.mainLine);
|
|
6167
|
+
delete options.mainLine;
|
|
6168
|
+
}
|
|
6169
|
+
if (options.offsetLine) {
|
|
6170
|
+
Object.assign(this.state.offsetLine, options.offsetLine);
|
|
6171
|
+
delete options.offsetLine;
|
|
6172
|
+
}
|
|
6173
|
+
if (options.shapeStyle) {
|
|
6174
|
+
this.state.shapeStyle = normalizeShapeStyle(
|
|
6175
|
+
options.shapeStyle,
|
|
6176
|
+
this.state.shapeStyle
|
|
6177
|
+
);
|
|
6178
|
+
delete options.shapeStyle;
|
|
6179
|
+
}
|
|
6180
|
+
Object.assign(this.state, options);
|
|
6181
|
+
this.state.shape = normalizeDielineShape(options.shape, this.state.shape);
|
|
6182
|
+
}
|
|
6183
|
+
}
|
|
6184
|
+
activate(context) {
|
|
6185
|
+
var _a;
|
|
6186
|
+
this.context = context;
|
|
6187
|
+
this.canvasService = context.services.get("CanvasService");
|
|
6188
|
+
if (!this.canvasService) {
|
|
6189
|
+
console.warn("CanvasService not found for DielineTool");
|
|
6190
|
+
return;
|
|
6191
|
+
}
|
|
6192
|
+
(_a = this.renderProducerDisposable) == null ? void 0 : _a.dispose();
|
|
6193
|
+
this.renderProducerDisposable = this.canvasService.registerRenderProducer(
|
|
6194
|
+
this.id,
|
|
6195
|
+
() => ({
|
|
6196
|
+
passes: [
|
|
6197
|
+
{
|
|
6198
|
+
id: DIELINE_LAYER_ID,
|
|
6199
|
+
stack: 700,
|
|
6200
|
+
order: 0,
|
|
6201
|
+
replace: true,
|
|
6202
|
+
visibility: {
|
|
6203
|
+
op: "not",
|
|
6204
|
+
expr: {
|
|
6205
|
+
op: "activeToolIn",
|
|
6206
|
+
ids: ["pooder.kit.image", "pooder.kit.white-ink"]
|
|
6207
|
+
}
|
|
6208
|
+
},
|
|
6209
|
+
effects: this.effects,
|
|
6210
|
+
objects: this.specs
|
|
5622
6211
|
}
|
|
6212
|
+
]
|
|
6213
|
+
}),
|
|
6214
|
+
{ priority: 250 }
|
|
6215
|
+
);
|
|
6216
|
+
const configService = context.services.get(
|
|
6217
|
+
"ConfigurationService"
|
|
6218
|
+
);
|
|
6219
|
+
if (configService) {
|
|
6220
|
+
Object.assign(this.state, readDielineState(configService, this.state));
|
|
6221
|
+
configService.onAnyChange((e) => {
|
|
6222
|
+
if (e.key.startsWith("size.") || e.key.startsWith("dieline.")) {
|
|
6223
|
+
Object.assign(this.state, readDielineState(configService, this.state));
|
|
5623
6224
|
this.updateDieline();
|
|
5624
6225
|
}
|
|
5625
6226
|
});
|
|
@@ -5663,299 +6264,61 @@ var DielineTool = class {
|
|
|
5663
6264
|
return void 0;
|
|
5664
6265
|
}
|
|
5665
6266
|
const size = 20;
|
|
5666
|
-
const canvas = document.createElement("canvas");
|
|
5667
|
-
canvas.width = size;
|
|
5668
|
-
canvas.height = size;
|
|
5669
|
-
const ctx = canvas.getContext("2d");
|
|
5670
|
-
if (ctx) {
|
|
5671
|
-
ctx.clearRect(0, 0, size, size);
|
|
5672
|
-
ctx.strokeStyle = color;
|
|
5673
|
-
ctx.lineWidth = 1;
|
|
5674
|
-
ctx.beginPath();
|
|
5675
|
-
ctx.moveTo(0, size);
|
|
5676
|
-
ctx.lineTo(size, 0);
|
|
5677
|
-
ctx.stroke();
|
|
5678
|
-
}
|
|
5679
|
-
return new import_fabric3.Pattern({ source: canvas, repetition: "repeat" });
|
|
5680
|
-
}
|
|
5681
|
-
getConfigService() {
|
|
5682
|
-
var _a;
|
|
5683
|
-
return (_a = this.context) == null ? void 0 : _a.services.get(
|
|
5684
|
-
"ConfigurationService"
|
|
5685
|
-
);
|
|
5686
|
-
}
|
|
5687
|
-
hasImageItems() {
|
|
5688
|
-
const configService = this.getConfigService();
|
|
5689
|
-
if (!configService) return false;
|
|
5690
|
-
const items = configService.get("image.items", []);
|
|
5691
|
-
return Array.isArray(items) && items.length > 0;
|
|
5692
|
-
}
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
const cutW = sceneLayout.cutRect.width;
|
|
5722
|
-
const cutH = sceneLayout.cutRect.height;
|
|
5723
|
-
const visualOffset = (cutW - visualWidth) / 2;
|
|
5724
|
-
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
5725
|
-
const absoluteFeatures = (features || []).map((f) => ({
|
|
5726
|
-
...f,
|
|
5727
|
-
x: f.x,
|
|
5728
|
-
y: f.y,
|
|
5729
|
-
width: (f.width || 0) * scale,
|
|
5730
|
-
height: (f.height || 0) * scale,
|
|
5731
|
-
radius: (f.radius || 0) * scale
|
|
5732
|
-
}));
|
|
5733
|
-
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
5734
|
-
const specs = [];
|
|
5735
|
-
if (insideColor && insideColor !== "transparent" && insideColor !== "rgba(0,0,0,0)" && !hasImages) {
|
|
5736
|
-
const productPathData = generateDielinePath({
|
|
5737
|
-
shape,
|
|
5738
|
-
width: cutW,
|
|
5739
|
-
height: cutH,
|
|
5740
|
-
radius: cutR,
|
|
5741
|
-
x: cx,
|
|
5742
|
-
y: cy,
|
|
5743
|
-
features: cutFeatures,
|
|
5744
|
-
shapeStyle,
|
|
5745
|
-
pathData: this.state.pathData,
|
|
5746
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5747
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5748
|
-
canvasWidth: canvasW,
|
|
5749
|
-
canvasHeight: canvasH
|
|
5750
|
-
});
|
|
5751
|
-
specs.push({
|
|
5752
|
-
id: "dieline.inside",
|
|
5753
|
-
type: "path",
|
|
5754
|
-
space: "screen",
|
|
5755
|
-
data: { id: "dieline.inside", type: "dieline" },
|
|
5756
|
-
props: {
|
|
5757
|
-
pathData: productPathData,
|
|
5758
|
-
fill: insideColor,
|
|
5759
|
-
stroke: null,
|
|
5760
|
-
selectable: false,
|
|
5761
|
-
evented: false,
|
|
5762
|
-
originX: "left",
|
|
5763
|
-
originY: "top"
|
|
5764
|
-
}
|
|
5765
|
-
});
|
|
5766
|
-
}
|
|
5767
|
-
if (Math.abs(visualOffset) > 1e-4) {
|
|
5768
|
-
const bleedPathData = generateBleedZonePath(
|
|
5769
|
-
{
|
|
5770
|
-
shape,
|
|
5771
|
-
width: visualWidth,
|
|
5772
|
-
height: visualHeight,
|
|
5773
|
-
radius: visualRadius,
|
|
5774
|
-
x: cx,
|
|
5775
|
-
y: cy,
|
|
5776
|
-
features: cutFeatures,
|
|
5777
|
-
shapeStyle,
|
|
5778
|
-
pathData: this.state.pathData,
|
|
5779
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5780
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5781
|
-
canvasWidth: canvasW,
|
|
5782
|
-
canvasHeight: canvasH
|
|
5783
|
-
},
|
|
5784
|
-
{
|
|
5785
|
-
shape,
|
|
5786
|
-
width: cutW,
|
|
5787
|
-
height: cutH,
|
|
5788
|
-
radius: cutR,
|
|
5789
|
-
x: cx,
|
|
5790
|
-
y: cy,
|
|
5791
|
-
features: cutFeatures,
|
|
5792
|
-
shapeStyle,
|
|
5793
|
-
pathData: this.state.pathData,
|
|
5794
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5795
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5796
|
-
canvasWidth: canvasW,
|
|
5797
|
-
canvasHeight: canvasH
|
|
5798
|
-
},
|
|
5799
|
-
visualOffset
|
|
5800
|
-
);
|
|
5801
|
-
if (showBleedLines !== false) {
|
|
5802
|
-
const pattern = this.createHatchPattern(mainLine.color);
|
|
5803
|
-
if (pattern) {
|
|
5804
|
-
specs.push({
|
|
5805
|
-
id: "dieline.bleed-zone",
|
|
5806
|
-
type: "path",
|
|
5807
|
-
space: "screen",
|
|
5808
|
-
data: { id: "dieline.bleed-zone", type: "dieline" },
|
|
5809
|
-
props: {
|
|
5810
|
-
pathData: bleedPathData,
|
|
5811
|
-
fill: pattern,
|
|
5812
|
-
stroke: null,
|
|
5813
|
-
selectable: false,
|
|
5814
|
-
evented: false,
|
|
5815
|
-
objectCaching: false,
|
|
5816
|
-
originX: "left",
|
|
5817
|
-
originY: "top"
|
|
5818
|
-
}
|
|
5819
|
-
});
|
|
5820
|
-
}
|
|
5821
|
-
}
|
|
5822
|
-
const offsetPathData = generateDielinePath({
|
|
5823
|
-
shape,
|
|
5824
|
-
width: cutW,
|
|
5825
|
-
height: cutH,
|
|
5826
|
-
radius: cutR,
|
|
5827
|
-
x: cx,
|
|
5828
|
-
y: cy,
|
|
5829
|
-
features: cutFeatures,
|
|
5830
|
-
shapeStyle,
|
|
5831
|
-
pathData: this.state.pathData,
|
|
5832
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5833
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5834
|
-
canvasWidth: canvasW,
|
|
5835
|
-
canvasHeight: canvasH
|
|
5836
|
-
});
|
|
5837
|
-
specs.push({
|
|
5838
|
-
id: "dieline.offset-border",
|
|
5839
|
-
type: "path",
|
|
5840
|
-
space: "screen",
|
|
5841
|
-
data: { id: "dieline.offset-border", type: "dieline" },
|
|
5842
|
-
props: {
|
|
5843
|
-
pathData: offsetPathData,
|
|
5844
|
-
fill: null,
|
|
5845
|
-
stroke: offsetLine.style === "hidden" ? null : offsetLine.color,
|
|
5846
|
-
strokeWidth: offsetLine.width,
|
|
5847
|
-
strokeDashArray: offsetLine.style === "dashed" ? [offsetLine.dashLength, offsetLine.dashLength] : void 0,
|
|
5848
|
-
selectable: false,
|
|
5849
|
-
evented: false,
|
|
5850
|
-
originX: "left",
|
|
5851
|
-
originY: "top"
|
|
5852
|
-
}
|
|
5853
|
-
});
|
|
5854
|
-
}
|
|
5855
|
-
const borderPathData = generateDielinePath({
|
|
5856
|
-
shape,
|
|
5857
|
-
width: visualWidth,
|
|
5858
|
-
height: visualHeight,
|
|
5859
|
-
radius: visualRadius,
|
|
5860
|
-
x: cx,
|
|
5861
|
-
y: cy,
|
|
5862
|
-
features: absoluteFeatures,
|
|
5863
|
-
shapeStyle,
|
|
5864
|
-
pathData: this.state.pathData,
|
|
5865
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5866
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5867
|
-
canvasWidth: canvasW,
|
|
5868
|
-
canvasHeight: canvasH
|
|
5869
|
-
});
|
|
5870
|
-
specs.push({
|
|
5871
|
-
id: "dieline.border",
|
|
5872
|
-
type: "path",
|
|
5873
|
-
space: "screen",
|
|
5874
|
-
data: { id: "dieline.border", type: "dieline" },
|
|
5875
|
-
props: {
|
|
5876
|
-
pathData: borderPathData,
|
|
5877
|
-
fill: "transparent",
|
|
5878
|
-
stroke: mainLine.style === "hidden" ? null : mainLine.color,
|
|
5879
|
-
strokeWidth: mainLine.width,
|
|
5880
|
-
strokeDashArray: mainLine.style === "dashed" ? [mainLine.dashLength, mainLine.dashLength] : void 0,
|
|
5881
|
-
selectable: false,
|
|
5882
|
-
evented: false,
|
|
5883
|
-
originX: "left",
|
|
5884
|
-
originY: "top"
|
|
5885
|
-
}
|
|
5886
|
-
});
|
|
5887
|
-
return specs;
|
|
5888
|
-
}
|
|
5889
|
-
buildImageClipEffects(sceneLayout) {
|
|
5890
|
-
var _a, _b;
|
|
5891
|
-
const { shape, shapeStyle, radius, features } = this.state;
|
|
5892
|
-
const canvasW = sceneLayout.canvasWidth || ((_a = this.canvasService) == null ? void 0 : _a.canvas.width) || 800;
|
|
5893
|
-
const canvasH = sceneLayout.canvasHeight || ((_b = this.canvasService) == null ? void 0 : _b.canvas.height) || 600;
|
|
5894
|
-
const scale = sceneLayout.scale;
|
|
5895
|
-
const cx = sceneLayout.trimRect.centerX;
|
|
5896
|
-
const cy = sceneLayout.trimRect.centerY;
|
|
5897
|
-
const visualWidth = sceneLayout.trimRect.width;
|
|
5898
|
-
const visualRadius = radius * scale;
|
|
5899
|
-
const cutW = sceneLayout.cutRect.width;
|
|
5900
|
-
const cutH = sceneLayout.cutRect.height;
|
|
5901
|
-
const visualOffset = (cutW - visualWidth) / 2;
|
|
5902
|
-
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
5903
|
-
const absoluteFeatures = (features || []).map((f) => ({
|
|
5904
|
-
...f,
|
|
5905
|
-
x: f.x,
|
|
5906
|
-
y: f.y,
|
|
5907
|
-
width: (f.width || 0) * scale,
|
|
5908
|
-
height: (f.height || 0) * scale,
|
|
5909
|
-
radius: (f.radius || 0) * scale
|
|
5910
|
-
}));
|
|
5911
|
-
const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
|
|
5912
|
-
const clipPathData = generateDielinePath({
|
|
5913
|
-
shape,
|
|
5914
|
-
width: cutW,
|
|
5915
|
-
height: cutH,
|
|
5916
|
-
radius: cutR,
|
|
5917
|
-
x: cx,
|
|
5918
|
-
y: cy,
|
|
5919
|
-
features: cutFeatures,
|
|
5920
|
-
shapeStyle,
|
|
5921
|
-
pathData: this.state.pathData,
|
|
5922
|
-
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
5923
|
-
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
5924
|
-
canvasWidth: canvasW,
|
|
5925
|
-
canvasHeight: canvasH
|
|
5926
|
-
});
|
|
5927
|
-
if (!clipPathData) return [];
|
|
5928
|
-
return [
|
|
5929
|
-
{
|
|
5930
|
-
type: "clipPath",
|
|
5931
|
-
id: "dieline.clip.image",
|
|
5932
|
-
visibility: {
|
|
5933
|
-
op: "not",
|
|
5934
|
-
expr: { op: "anySessionActive" }
|
|
5935
|
-
},
|
|
5936
|
-
targetPassIds: [IMAGE_OBJECT_LAYER_ID],
|
|
5937
|
-
source: {
|
|
5938
|
-
id: "dieline.effect.clip-path",
|
|
5939
|
-
type: "path",
|
|
5940
|
-
space: "screen",
|
|
5941
|
-
data: {
|
|
5942
|
-
id: "dieline.effect.clip-path",
|
|
5943
|
-
type: "dieline-effect",
|
|
5944
|
-
effect: "clipPath"
|
|
5945
|
-
},
|
|
5946
|
-
props: {
|
|
5947
|
-
pathData: clipPathData,
|
|
5948
|
-
fill: "#000000",
|
|
5949
|
-
stroke: null,
|
|
5950
|
-
originX: "left",
|
|
5951
|
-
originY: "top",
|
|
5952
|
-
selectable: false,
|
|
5953
|
-
evented: false,
|
|
5954
|
-
excludeFromExport: true
|
|
5955
|
-
}
|
|
5956
|
-
}
|
|
5957
|
-
}
|
|
5958
|
-
];
|
|
6267
|
+
const canvas = document.createElement("canvas");
|
|
6268
|
+
canvas.width = size;
|
|
6269
|
+
canvas.height = size;
|
|
6270
|
+
const ctx = canvas.getContext("2d");
|
|
6271
|
+
if (ctx) {
|
|
6272
|
+
ctx.clearRect(0, 0, size, size);
|
|
6273
|
+
ctx.strokeStyle = color;
|
|
6274
|
+
ctx.lineWidth = 1;
|
|
6275
|
+
ctx.beginPath();
|
|
6276
|
+
ctx.moveTo(0, size);
|
|
6277
|
+
ctx.lineTo(size, 0);
|
|
6278
|
+
ctx.stroke();
|
|
6279
|
+
}
|
|
6280
|
+
return new import_fabric3.Pattern({ source: canvas, repetition: "repeat" });
|
|
6281
|
+
}
|
|
6282
|
+
getConfigService() {
|
|
6283
|
+
var _a;
|
|
6284
|
+
return (_a = this.context) == null ? void 0 : _a.services.get(
|
|
6285
|
+
"ConfigurationService"
|
|
6286
|
+
);
|
|
6287
|
+
}
|
|
6288
|
+
hasImageItems() {
|
|
6289
|
+
const configService = this.getConfigService();
|
|
6290
|
+
if (!configService) return false;
|
|
6291
|
+
const items = configService.get("image.items", []);
|
|
6292
|
+
return Array.isArray(items) && items.length > 0;
|
|
6293
|
+
}
|
|
6294
|
+
buildDielineSpecs(sceneLayout) {
|
|
6295
|
+
var _a, _b;
|
|
6296
|
+
const hasImages = this.hasImageItems();
|
|
6297
|
+
return buildDielineRenderBundle({
|
|
6298
|
+
state: this.state,
|
|
6299
|
+
sceneLayout,
|
|
6300
|
+
canvasWidth: sceneLayout.canvasWidth || ((_a = this.canvasService) == null ? void 0 : _a.canvas.width) || 800,
|
|
6301
|
+
canvasHeight: sceneLayout.canvasHeight || ((_b = this.canvasService) == null ? void 0 : _b.canvas.height) || 600,
|
|
6302
|
+
hasImages,
|
|
6303
|
+
createHatchPattern: (color) => this.createHatchPattern(color),
|
|
6304
|
+
includeImageClipEffect: false
|
|
6305
|
+
}).specs;
|
|
6306
|
+
}
|
|
6307
|
+
buildImageClipEffects(sceneLayout) {
|
|
6308
|
+
var _a, _b;
|
|
6309
|
+
return buildDielineRenderBundle({
|
|
6310
|
+
state: this.state,
|
|
6311
|
+
sceneLayout,
|
|
6312
|
+
canvasWidth: sceneLayout.canvasWidth || ((_a = this.canvasService) == null ? void 0 : _a.canvas.width) || 800,
|
|
6313
|
+
canvasHeight: sceneLayout.canvasHeight || ((_b = this.canvasService) == null ? void 0 : _b.canvas.height) || 600,
|
|
6314
|
+
hasImages: this.hasImageItems(),
|
|
6315
|
+
includeImageClipEffect: true,
|
|
6316
|
+
clipTargetPassIds: [IMAGE_OBJECT_LAYER_ID],
|
|
6317
|
+
clipVisibility: {
|
|
6318
|
+
op: "not",
|
|
6319
|
+
expr: { op: "anySessionActive" }
|
|
6320
|
+
}
|
|
6321
|
+
}).effects;
|
|
5959
6322
|
}
|
|
5960
6323
|
updateDieline(_emitEvent = true) {
|
|
5961
6324
|
void this.updateDielineAsync();
|
|
@@ -5965,7 +6328,7 @@ var DielineTool = class {
|
|
|
5965
6328
|
const configService = this.getConfigService();
|
|
5966
6329
|
if (!configService) return;
|
|
5967
6330
|
const seq = ++this.renderSeq;
|
|
5968
|
-
this.
|
|
6331
|
+
Object.assign(this.state, readDielineState(configService, this.state));
|
|
5969
6332
|
const sceneLayout = computeSceneLayout(
|
|
5970
6333
|
this.canvasService,
|
|
5971
6334
|
readSizeState(configService)
|
|
@@ -6020,7 +6383,7 @@ var DielineTool = class {
|
|
|
6020
6383
|
);
|
|
6021
6384
|
return null;
|
|
6022
6385
|
}
|
|
6023
|
-
this.
|
|
6386
|
+
this.state = readDielineState(configService, this.state);
|
|
6024
6387
|
const sceneLayout = computeSceneLayout(
|
|
6025
6388
|
this.canvasService,
|
|
6026
6389
|
readSizeState(configService)
|
|
@@ -6042,15 +6405,31 @@ var DielineTool = class {
|
|
|
6042
6405
|
const visualRadius = radius * scale;
|
|
6043
6406
|
const visualOffset = (cutW - sceneLayout.trimRect.width) / 2;
|
|
6044
6407
|
const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
|
|
6045
|
-
const
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6408
|
+
const placements = resolveFeaturePlacements(features || [], {
|
|
6409
|
+
shape,
|
|
6410
|
+
shapeStyle,
|
|
6411
|
+
pathData,
|
|
6412
|
+
customSourceWidthPx: this.state.customSourceWidthPx,
|
|
6413
|
+
customSourceHeightPx: this.state.customSourceHeightPx,
|
|
6414
|
+
canvasWidth: canvasW,
|
|
6415
|
+
canvasHeight: canvasH,
|
|
6416
|
+
x: cx,
|
|
6417
|
+
y: cy,
|
|
6418
|
+
width: sceneLayout.trimRect.width,
|
|
6419
|
+
height: sceneLayout.trimRect.height,
|
|
6420
|
+
radius: visualRadius,
|
|
6421
|
+
scale
|
|
6422
|
+
});
|
|
6423
|
+
const cutFeatures = projectPlacedFeatures(
|
|
6424
|
+
placements.filter((placement) => !placement.feature.skipCut),
|
|
6425
|
+
{
|
|
6426
|
+
x: cx,
|
|
6427
|
+
y: cy,
|
|
6428
|
+
width: cutW,
|
|
6429
|
+
height: cutH
|
|
6430
|
+
},
|
|
6431
|
+
scale
|
|
6432
|
+
);
|
|
6054
6433
|
const generatedPathData = generateDielinePath({
|
|
6055
6434
|
shape,
|
|
6056
6435
|
width: cutW,
|
|
@@ -6072,278 +6451,107 @@ var DielineTool = class {
|
|
|
6072
6451
|
left: cx,
|
|
6073
6452
|
top: cy,
|
|
6074
6453
|
absolutePositioned: true
|
|
6075
|
-
});
|
|
6076
|
-
const pathOffsetX = Number((_a = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _a.x);
|
|
6077
|
-
const pathOffsetY = Number((_b = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _b.y);
|
|
6078
|
-
const centerX = Number.isFinite(pathOffsetX) ? pathOffsetX : cx;
|
|
6079
|
-
const centerY = Number.isFinite(pathOffsetY) ? pathOffsetY : cy;
|
|
6080
|
-
clipPath.set({
|
|
6081
|
-
originX: "center",
|
|
6082
|
-
originY: "center",
|
|
6083
|
-
left: centerX,
|
|
6084
|
-
top: centerY,
|
|
6085
|
-
absolutePositioned: true
|
|
6086
|
-
});
|
|
6087
|
-
clipPath.setCoords();
|
|
6088
|
-
const pathBounds = clipPath.getBoundingRect();
|
|
6089
|
-
if (!Number.isFinite(pathBounds.left) || !Number.isFinite(pathBounds.top) || !Number.isFinite(pathBounds.width) || !Number.isFinite(pathBounds.height) || pathBounds.width <= 0 || pathBounds.height <= 0) {
|
|
6090
|
-
console.warn(
|
|
6091
|
-
"[DielineTool] exportCutImage returned null: invalid-cut-bounds",
|
|
6092
|
-
{
|
|
6093
|
-
bounds: pathBounds
|
|
6094
|
-
}
|
|
6095
|
-
);
|
|
6096
|
-
return null;
|
|
6097
|
-
}
|
|
6098
|
-
const exportBounds = pathBounds;
|
|
6099
|
-
const sourceImages = this.canvasService.canvas.getObjects().filter((obj) => {
|
|
6100
|
-
var _a2;
|
|
6101
|
-
return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID;
|
|
6102
|
-
});
|
|
6103
|
-
if (!sourceImages.length) {
|
|
6104
|
-
console.warn(
|
|
6105
|
-
"[DielineTool] exportCutImage returned null: no-image-objects-on-canvas"
|
|
6106
|
-
);
|
|
6107
|
-
return null;
|
|
6108
|
-
}
|
|
6109
|
-
const sourceCanvasWidth = Number(
|
|
6110
|
-
this.canvasService.canvas.width || sceneLayout.canvasWidth || canvasW
|
|
6111
|
-
);
|
|
6112
|
-
const sourceCanvasHeight = Number(
|
|
6113
|
-
this.canvasService.canvas.height || sceneLayout.canvasHeight || canvasH
|
|
6114
|
-
);
|
|
6115
|
-
const el = document.createElement("canvas");
|
|
6116
|
-
const exportCanvas = new import_fabric3.Canvas(el, {
|
|
6117
|
-
renderOnAddRemove: false,
|
|
6118
|
-
selection: false,
|
|
6119
|
-
enableRetinaScaling: false,
|
|
6120
|
-
preserveObjectStacking: true
|
|
6121
|
-
});
|
|
6122
|
-
exportCanvas.setDimensions({
|
|
6123
|
-
width: Math.max(1, sourceCanvasWidth),
|
|
6124
|
-
height: Math.max(1, sourceCanvasHeight)
|
|
6125
|
-
});
|
|
6126
|
-
try {
|
|
6127
|
-
for (const source of sourceImages) {
|
|
6128
|
-
const clone = await source.clone();
|
|
6129
|
-
clone.set({
|
|
6130
|
-
selectable: false,
|
|
6131
|
-
evented: false
|
|
6132
|
-
});
|
|
6133
|
-
clone.setCoords();
|
|
6134
|
-
exportCanvas.add(clone);
|
|
6135
|
-
}
|
|
6136
|
-
exportCanvas.clipPath = clipPath;
|
|
6137
|
-
exportCanvas.renderAll();
|
|
6138
|
-
const dataUrl = exportCanvas.toDataURL({
|
|
6139
|
-
format: "png",
|
|
6140
|
-
multiplier: 2,
|
|
6141
|
-
left: exportBounds.left,
|
|
6142
|
-
top: exportBounds.top,
|
|
6143
|
-
width: exportBounds.width,
|
|
6144
|
-
height: exportBounds.height
|
|
6145
|
-
});
|
|
6146
|
-
if (debug) {
|
|
6147
|
-
console.info("[DielineTool] exportCutImage success", {
|
|
6148
|
-
sourceCount: sourceImages.length,
|
|
6149
|
-
bounds: exportBounds,
|
|
6150
|
-
rawPathBounds: pathBounds,
|
|
6151
|
-
pathOffset: {
|
|
6152
|
-
x: Number.isFinite(pathOffsetX) ? pathOffsetX : null,
|
|
6153
|
-
y: Number.isFinite(pathOffsetY) ? pathOffsetY : null
|
|
6154
|
-
},
|
|
6155
|
-
clipPathCenter: {
|
|
6156
|
-
x: centerX,
|
|
6157
|
-
y: centerY
|
|
6158
|
-
},
|
|
6159
|
-
cutRect: sceneLayout.cutRect,
|
|
6160
|
-
canvasSize: {
|
|
6161
|
-
width: Math.max(1, sourceCanvasWidth),
|
|
6162
|
-
height: Math.max(1, sourceCanvasHeight)
|
|
6163
|
-
}
|
|
6164
|
-
});
|
|
6165
|
-
}
|
|
6166
|
-
return dataUrl;
|
|
6167
|
-
} finally {
|
|
6168
|
-
exportCanvas.dispose();
|
|
6169
|
-
}
|
|
6170
|
-
}
|
|
6171
|
-
};
|
|
6172
|
-
|
|
6173
|
-
// src/extensions/feature/FeatureTool.ts
|
|
6174
|
-
var import_core5 = require("@pooder/core");
|
|
6175
|
-
|
|
6176
|
-
// src/extensions/constraints.ts
|
|
6177
|
-
var ConstraintRegistry = class {
|
|
6178
|
-
static register(type, handler) {
|
|
6179
|
-
this.handlers.set(type, handler);
|
|
6180
|
-
}
|
|
6181
|
-
static apply(x, y, feature, context, constraints) {
|
|
6182
|
-
const list = constraints || feature.constraints;
|
|
6183
|
-
if (!list || list.length === 0) {
|
|
6184
|
-
return { x, y };
|
|
6185
|
-
}
|
|
6186
|
-
let currentX = x;
|
|
6187
|
-
let currentY = y;
|
|
6188
|
-
for (const constraint of list) {
|
|
6189
|
-
const handler = this.handlers.get(constraint.type);
|
|
6190
|
-
if (handler) {
|
|
6191
|
-
const result = handler(currentX, currentY, feature, context, constraint.params || {});
|
|
6192
|
-
currentX = result.x;
|
|
6193
|
-
currentY = result.y;
|
|
6194
|
-
}
|
|
6195
|
-
}
|
|
6196
|
-
return { x: currentX, y: currentY };
|
|
6197
|
-
}
|
|
6198
|
-
};
|
|
6199
|
-
ConstraintRegistry.handlers = /* @__PURE__ */ new Map();
|
|
6200
|
-
var pathConstraint = (x, y, feature, context, params) => {
|
|
6201
|
-
const { dielineWidth, dielineHeight, geometry } = context;
|
|
6202
|
-
if (!geometry) return { x, y };
|
|
6203
|
-
const minX = geometry.x - geometry.width / 2;
|
|
6204
|
-
const minY = geometry.y - geometry.height / 2;
|
|
6205
|
-
const absX = minX + x * geometry.width;
|
|
6206
|
-
const absY = minY + y * geometry.height;
|
|
6207
|
-
const nearest = getNearestPointOnDieline(
|
|
6208
|
-
{ x: absX, y: absY },
|
|
6209
|
-
geometry
|
|
6210
|
-
);
|
|
6211
|
-
let finalX = nearest.x;
|
|
6212
|
-
let finalY = nearest.y;
|
|
6213
|
-
const hasOffsetParams = params.minOffset !== void 0 || params.maxOffset !== void 0;
|
|
6214
|
-
if (hasOffsetParams && nearest.normal) {
|
|
6215
|
-
const dx = absX - nearest.x;
|
|
6216
|
-
const dy = absY - nearest.y;
|
|
6217
|
-
const nx2 = nearest.normal.x;
|
|
6218
|
-
const ny2 = nearest.normal.y;
|
|
6219
|
-
const dist = dx * nx2 + dy * ny2;
|
|
6220
|
-
const scale = dielineWidth > 0 ? geometry.width / dielineWidth : 1;
|
|
6221
|
-
const rawMin = params.minOffset !== void 0 ? params.minOffset : 0;
|
|
6222
|
-
const rawMax = params.maxOffset !== void 0 ? params.maxOffset : 0;
|
|
6223
|
-
const minOffset = rawMin * scale;
|
|
6224
|
-
const maxOffset = rawMax * scale;
|
|
6225
|
-
const clampedDist = Math.max(minOffset, Math.min(dist, maxOffset));
|
|
6226
|
-
finalX = nearest.x + nx2 * clampedDist;
|
|
6227
|
-
finalY = nearest.y + ny2 * clampedDist;
|
|
6228
|
-
}
|
|
6229
|
-
const nx = geometry.width > 0 ? (finalX - minX) / geometry.width : 0.5;
|
|
6230
|
-
const ny = geometry.height > 0 ? (finalY - minY) / geometry.height : 0.5;
|
|
6231
|
-
return { x: nx, y: ny };
|
|
6232
|
-
};
|
|
6233
|
-
var edgeConstraint = (x, y, feature, context, params) => {
|
|
6234
|
-
const { dielineWidth, dielineHeight } = context;
|
|
6235
|
-
const allowedEdges = params.allowedEdges || [
|
|
6236
|
-
"top",
|
|
6237
|
-
"bottom",
|
|
6238
|
-
"left",
|
|
6239
|
-
"right"
|
|
6240
|
-
];
|
|
6241
|
-
const confine = params.confine || false;
|
|
6242
|
-
const offset = params.offset || 0;
|
|
6243
|
-
const distances = [];
|
|
6244
|
-
if (allowedEdges.includes("top"))
|
|
6245
|
-
distances.push({ edge: "top", dist: y * dielineHeight });
|
|
6246
|
-
if (allowedEdges.includes("bottom"))
|
|
6247
|
-
distances.push({ edge: "bottom", dist: (1 - y) * dielineHeight });
|
|
6248
|
-
if (allowedEdges.includes("left"))
|
|
6249
|
-
distances.push({ edge: "left", dist: x * dielineWidth });
|
|
6250
|
-
if (allowedEdges.includes("right"))
|
|
6251
|
-
distances.push({ edge: "right", dist: (1 - x) * dielineWidth });
|
|
6252
|
-
if (distances.length === 0) return { x, y };
|
|
6253
|
-
distances.sort((a, b) => a.dist - b.dist);
|
|
6254
|
-
const nearest = distances[0].edge;
|
|
6255
|
-
let newX = x;
|
|
6256
|
-
let newY = y;
|
|
6257
|
-
const fw = feature.width || 0;
|
|
6258
|
-
const fh = feature.height || 0;
|
|
6259
|
-
switch (nearest) {
|
|
6260
|
-
case "top":
|
|
6261
|
-
newY = 0 + offset / dielineHeight;
|
|
6262
|
-
if (confine) {
|
|
6263
|
-
const minX = fw / 2 / dielineWidth;
|
|
6264
|
-
const maxX = 1 - minX;
|
|
6265
|
-
newX = Math.max(minX, Math.min(newX, maxX));
|
|
6266
|
-
}
|
|
6267
|
-
break;
|
|
6268
|
-
case "bottom":
|
|
6269
|
-
newY = 1 - offset / dielineHeight;
|
|
6270
|
-
if (confine) {
|
|
6271
|
-
const minX = fw / 2 / dielineWidth;
|
|
6272
|
-
const maxX = 1 - minX;
|
|
6273
|
-
newX = Math.max(minX, Math.min(newX, maxX));
|
|
6274
|
-
}
|
|
6275
|
-
break;
|
|
6276
|
-
case "left":
|
|
6277
|
-
newX = 0 + offset / dielineWidth;
|
|
6278
|
-
if (confine) {
|
|
6279
|
-
const minY = fh / 2 / dielineHeight;
|
|
6280
|
-
const maxY = 1 - minY;
|
|
6281
|
-
newY = Math.max(minY, Math.min(newY, maxY));
|
|
6454
|
+
});
|
|
6455
|
+
const pathOffsetX = Number((_a = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _a.x);
|
|
6456
|
+
const pathOffsetY = Number((_b = clipPath == null ? void 0 : clipPath.pathOffset) == null ? void 0 : _b.y);
|
|
6457
|
+
const centerX = Number.isFinite(pathOffsetX) ? pathOffsetX : cx;
|
|
6458
|
+
const centerY = Number.isFinite(pathOffsetY) ? pathOffsetY : cy;
|
|
6459
|
+
clipPath.set({
|
|
6460
|
+
originX: "center",
|
|
6461
|
+
originY: "center",
|
|
6462
|
+
left: centerX,
|
|
6463
|
+
top: centerY,
|
|
6464
|
+
absolutePositioned: true
|
|
6465
|
+
});
|
|
6466
|
+
clipPath.setCoords();
|
|
6467
|
+
const pathBounds = clipPath.getBoundingRect();
|
|
6468
|
+
if (!Number.isFinite(pathBounds.left) || !Number.isFinite(pathBounds.top) || !Number.isFinite(pathBounds.width) || !Number.isFinite(pathBounds.height) || pathBounds.width <= 0 || pathBounds.height <= 0) {
|
|
6469
|
+
console.warn(
|
|
6470
|
+
"[DielineTool] exportCutImage returned null: invalid-cut-bounds",
|
|
6471
|
+
{
|
|
6472
|
+
bounds: pathBounds
|
|
6473
|
+
}
|
|
6474
|
+
);
|
|
6475
|
+
return null;
|
|
6476
|
+
}
|
|
6477
|
+
const exportBounds = pathBounds;
|
|
6478
|
+
const sourceImages = this.canvasService.canvas.getObjects().filter((obj) => {
|
|
6479
|
+
var _a2;
|
|
6480
|
+
return ((_a2 = obj == null ? void 0 : obj.data) == null ? void 0 : _a2.layerId) === IMAGE_OBJECT_LAYER_ID;
|
|
6481
|
+
});
|
|
6482
|
+
if (!sourceImages.length) {
|
|
6483
|
+
console.warn(
|
|
6484
|
+
"[DielineTool] exportCutImage returned null: no-image-objects-on-canvas"
|
|
6485
|
+
);
|
|
6486
|
+
return null;
|
|
6487
|
+
}
|
|
6488
|
+
const sourceCanvasWidth = Number(
|
|
6489
|
+
this.canvasService.canvas.width || sceneLayout.canvasWidth || canvasW
|
|
6490
|
+
);
|
|
6491
|
+
const sourceCanvasHeight = Number(
|
|
6492
|
+
this.canvasService.canvas.height || sceneLayout.canvasHeight || canvasH
|
|
6493
|
+
);
|
|
6494
|
+
const el = document.createElement("canvas");
|
|
6495
|
+
const exportCanvas = new import_fabric3.Canvas(el, {
|
|
6496
|
+
renderOnAddRemove: false,
|
|
6497
|
+
selection: false,
|
|
6498
|
+
enableRetinaScaling: false,
|
|
6499
|
+
preserveObjectStacking: true
|
|
6500
|
+
});
|
|
6501
|
+
exportCanvas.setDimensions({
|
|
6502
|
+
width: Math.max(1, sourceCanvasWidth),
|
|
6503
|
+
height: Math.max(1, sourceCanvasHeight)
|
|
6504
|
+
});
|
|
6505
|
+
try {
|
|
6506
|
+
for (const source of sourceImages) {
|
|
6507
|
+
const clone = await source.clone();
|
|
6508
|
+
clone.set({
|
|
6509
|
+
selectable: false,
|
|
6510
|
+
evented: false
|
|
6511
|
+
});
|
|
6512
|
+
clone.setCoords();
|
|
6513
|
+
exportCanvas.add(clone);
|
|
6282
6514
|
}
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6515
|
+
exportCanvas.clipPath = clipPath;
|
|
6516
|
+
exportCanvas.renderAll();
|
|
6517
|
+
const dataUrl = exportCanvas.toDataURL({
|
|
6518
|
+
format: "png",
|
|
6519
|
+
multiplier: 2,
|
|
6520
|
+
left: exportBounds.left,
|
|
6521
|
+
top: exportBounds.top,
|
|
6522
|
+
width: exportBounds.width,
|
|
6523
|
+
height: exportBounds.height
|
|
6524
|
+
});
|
|
6525
|
+
if (debug) {
|
|
6526
|
+
console.info("[DielineTool] exportCutImage success", {
|
|
6527
|
+
sourceCount: sourceImages.length,
|
|
6528
|
+
bounds: exportBounds,
|
|
6529
|
+
rawPathBounds: pathBounds,
|
|
6530
|
+
pathOffset: {
|
|
6531
|
+
x: Number.isFinite(pathOffsetX) ? pathOffsetX : null,
|
|
6532
|
+
y: Number.isFinite(pathOffsetY) ? pathOffsetY : null
|
|
6533
|
+
},
|
|
6534
|
+
clipPathCenter: {
|
|
6535
|
+
x: centerX,
|
|
6536
|
+
y: centerY
|
|
6537
|
+
},
|
|
6538
|
+
cutRect: sceneLayout.cutRect,
|
|
6539
|
+
canvasSize: {
|
|
6540
|
+
width: Math.max(1, sourceCanvasWidth),
|
|
6541
|
+
height: Math.max(1, sourceCanvasHeight)
|
|
6542
|
+
}
|
|
6543
|
+
});
|
|
6290
6544
|
}
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
}
|
|
6295
|
-
var internalConstraint = (x, y, feature, context, params) => {
|
|
6296
|
-
const { dielineWidth, dielineHeight } = context;
|
|
6297
|
-
const margin = params.margin || 0;
|
|
6298
|
-
const fw = feature.width || 0;
|
|
6299
|
-
const fh = feature.height || 0;
|
|
6300
|
-
const minX = (margin + fw / 2) / dielineWidth;
|
|
6301
|
-
const maxX = 1 - (margin + fw / 2) / dielineWidth;
|
|
6302
|
-
const minY = (margin + fh / 2) / dielineHeight;
|
|
6303
|
-
const maxY = 1 - (margin + fh / 2) / dielineHeight;
|
|
6304
|
-
const clampedX = minX > maxX ? 0.5 : Math.max(minX, Math.min(x, maxX));
|
|
6305
|
-
const clampedY = minY > maxY ? 0.5 : Math.max(minY, Math.min(y, maxY));
|
|
6306
|
-
return { x: clampedX, y: clampedY };
|
|
6307
|
-
};
|
|
6308
|
-
var tangentBottomConstraint = (x, y, feature, context, params) => {
|
|
6309
|
-
const { dielineWidth, dielineHeight } = context;
|
|
6310
|
-
const gap = params.gap || 0;
|
|
6311
|
-
const confineX = params.confineX !== false;
|
|
6312
|
-
const extentY = feature.shape === "circle" ? feature.radius || 0 : (feature.height || 0) / 2;
|
|
6313
|
-
const newY = 1 + (extentY + gap) / dielineHeight;
|
|
6314
|
-
let newX = x;
|
|
6315
|
-
if (confineX) {
|
|
6316
|
-
const extentX = feature.shape === "circle" ? feature.radius || 0 : (feature.width || 0) / 2;
|
|
6317
|
-
const minX = extentX / dielineWidth;
|
|
6318
|
-
const maxX = 1 - extentX / dielineWidth;
|
|
6319
|
-
newX = minX > maxX ? 0.5 : Math.max(minX, Math.min(newX, maxX));
|
|
6320
|
-
}
|
|
6321
|
-
return { x: newX, y: newY };
|
|
6322
|
-
};
|
|
6323
|
-
var lowestTangentConstraint = (x, y, feature, context, params) => {
|
|
6324
|
-
const { dielineWidth, dielineHeight, geometry } = context;
|
|
6325
|
-
if (!geometry) return { x, y };
|
|
6326
|
-
const lowest = getLowestPointOnDieline(geometry);
|
|
6327
|
-
const minY = geometry.y - geometry.height / 2;
|
|
6328
|
-
const normY = (lowest.y - minY) / geometry.height;
|
|
6329
|
-
const gap = params.gap || 0;
|
|
6330
|
-
const confineX = params.confineX !== false;
|
|
6331
|
-
const extentY = feature.shape === "circle" ? feature.radius || 0 : (feature.height || 0) / 2;
|
|
6332
|
-
const newY = normY + (extentY + gap) / dielineHeight;
|
|
6333
|
-
let newX = x;
|
|
6334
|
-
if (confineX) {
|
|
6335
|
-
const extentX = feature.shape === "circle" ? feature.radius || 0 : (feature.width || 0) / 2;
|
|
6336
|
-
const minX = extentX / dielineWidth;
|
|
6337
|
-
const maxX = 1 - extentX / dielineWidth;
|
|
6338
|
-
newX = minX > maxX ? 0.5 : Math.max(minX, Math.min(newX, maxX));
|
|
6545
|
+
return dataUrl;
|
|
6546
|
+
} finally {
|
|
6547
|
+
exportCanvas.dispose();
|
|
6548
|
+
}
|
|
6339
6549
|
}
|
|
6340
|
-
return { x: newX, y: newY };
|
|
6341
6550
|
};
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
ConstraintRegistry.register("lowest-tangent", lowestTangentConstraint);
|
|
6551
|
+
|
|
6552
|
+
// src/extensions/feature/FeatureTool.ts
|
|
6553
|
+
var import_core5 = require("@pooder/core");
|
|
6554
|
+
var import_fabric4 = require("fabric");
|
|
6347
6555
|
|
|
6348
6556
|
// src/extensions/featureComplete.ts
|
|
6349
6557
|
function validateFeaturesStrict(features, context) {
|
|
@@ -6386,7 +6594,9 @@ var FeatureTool = class {
|
|
|
6386
6594
|
this.isFeatureSessionActive = false;
|
|
6387
6595
|
this.sessionOriginalFeatures = null;
|
|
6388
6596
|
this.hasWorkingChanges = false;
|
|
6389
|
-
this.
|
|
6597
|
+
this.markerSpecs = [];
|
|
6598
|
+
this.sessionDielineSpecs = [];
|
|
6599
|
+
this.sessionDielineEffects = [];
|
|
6390
6600
|
this.renderSeq = 0;
|
|
6391
6601
|
this.subscriptions = new SubscriptionBag();
|
|
6392
6602
|
this.handleMoving = null;
|
|
@@ -6396,7 +6606,7 @@ var FeatureTool = class {
|
|
|
6396
6606
|
this.onToolActivated = (event) => {
|
|
6397
6607
|
this.isToolActive = event.id === this.id;
|
|
6398
6608
|
if (!this.isToolActive) {
|
|
6399
|
-
this.
|
|
6609
|
+
this.suspendFeatureSession();
|
|
6400
6610
|
}
|
|
6401
6611
|
this.updateVisibility();
|
|
6402
6612
|
};
|
|
@@ -6416,16 +6626,38 @@ var FeatureTool = class {
|
|
|
6416
6626
|
(_a = this.renderProducerDisposable) == null ? void 0 : _a.dispose();
|
|
6417
6627
|
this.renderProducerDisposable = this.canvasService.registerRenderProducer(
|
|
6418
6628
|
this.id,
|
|
6419
|
-
() =>
|
|
6420
|
-
passes
|
|
6629
|
+
() => {
|
|
6630
|
+
const passes = [
|
|
6421
6631
|
{
|
|
6422
6632
|
id: FEATURE_OVERLAY_LAYER_ID,
|
|
6423
6633
|
stack: 880,
|
|
6424
6634
|
order: 0,
|
|
6425
|
-
|
|
6635
|
+
replace: true,
|
|
6636
|
+
objects: this.markerSpecs
|
|
6426
6637
|
}
|
|
6427
|
-
]
|
|
6428
|
-
|
|
6638
|
+
];
|
|
6639
|
+
if (this.isSessionVisible()) {
|
|
6640
|
+
passes.push(
|
|
6641
|
+
{
|
|
6642
|
+
id: DIELINE_LAYER_ID,
|
|
6643
|
+
stack: 700,
|
|
6644
|
+
order: 0,
|
|
6645
|
+
replace: false,
|
|
6646
|
+
visibility: { op: "const", value: false },
|
|
6647
|
+
objects: []
|
|
6648
|
+
},
|
|
6649
|
+
{
|
|
6650
|
+
id: FEATURE_DIELINE_LAYER_ID,
|
|
6651
|
+
stack: 705,
|
|
6652
|
+
order: 0,
|
|
6653
|
+
replace: true,
|
|
6654
|
+
effects: this.sessionDielineEffects,
|
|
6655
|
+
objects: this.sessionDielineSpecs
|
|
6656
|
+
}
|
|
6657
|
+
);
|
|
6658
|
+
}
|
|
6659
|
+
return { passes };
|
|
6660
|
+
},
|
|
6429
6661
|
{ priority: 350 }
|
|
6430
6662
|
);
|
|
6431
6663
|
const configService = context.services.get(
|
|
@@ -6440,12 +6672,22 @@ var FeatureTool = class {
|
|
|
6440
6672
|
(e) => {
|
|
6441
6673
|
if (this.isUpdatingConfig) return;
|
|
6442
6674
|
if (e.key === "dieline.features") {
|
|
6443
|
-
if (this.isFeatureSessionActive)
|
|
6675
|
+
if (this.isFeatureSessionActive && this.hasFeatureSessionDraft()) {
|
|
6676
|
+
return;
|
|
6677
|
+
}
|
|
6678
|
+
if (this.hasFeatureSessionDraft()) {
|
|
6679
|
+
this.clearFeatureSessionState();
|
|
6680
|
+
}
|
|
6444
6681
|
const next = e.value || [];
|
|
6445
6682
|
this.workingFeatures = this.cloneFeatures(next);
|
|
6446
6683
|
this.hasWorkingChanges = false;
|
|
6447
6684
|
this.redraw();
|
|
6448
6685
|
this.emitWorkingChange();
|
|
6686
|
+
return;
|
|
6687
|
+
}
|
|
6688
|
+
if (e.key.startsWith("size.") || e.key.startsWith("dieline.")) {
|
|
6689
|
+
void this.refreshGeometry();
|
|
6690
|
+
this.redraw({ enforceConstraints: true });
|
|
6449
6691
|
}
|
|
6450
6692
|
}
|
|
6451
6693
|
);
|
|
@@ -6461,7 +6703,8 @@ var FeatureTool = class {
|
|
|
6461
6703
|
deactivate(context) {
|
|
6462
6704
|
var _a;
|
|
6463
6705
|
this.subscriptions.disposeAll();
|
|
6464
|
-
this.
|
|
6706
|
+
this.restoreCommittedFeaturesToConfig();
|
|
6707
|
+
this.clearFeatureSessionState();
|
|
6465
6708
|
(_a = this.dirtyTrackerDisposable) == null ? void 0 : _a.dispose();
|
|
6466
6709
|
this.dirtyTrackerDisposable = void 0;
|
|
6467
6710
|
this.teardown();
|
|
@@ -6471,6 +6714,9 @@ var FeatureTool = class {
|
|
|
6471
6714
|
updateVisibility() {
|
|
6472
6715
|
this.redraw();
|
|
6473
6716
|
}
|
|
6717
|
+
isSessionVisible() {
|
|
6718
|
+
return this.isToolActive && this.isFeatureSessionActive;
|
|
6719
|
+
}
|
|
6474
6720
|
contribute() {
|
|
6475
6721
|
return {
|
|
6476
6722
|
[import_core5.ContributionPointIds.TOOLS]: [
|
|
@@ -6497,15 +6743,16 @@ var FeatureTool = class {
|
|
|
6497
6743
|
if (this.isFeatureSessionActive) {
|
|
6498
6744
|
return { ok: true };
|
|
6499
6745
|
}
|
|
6500
|
-
|
|
6501
|
-
|
|
6746
|
+
if (!this.hasFeatureSessionDraft()) {
|
|
6747
|
+
const original = this.getCommittedFeatures();
|
|
6748
|
+
this.sessionOriginalFeatures = this.cloneFeatures(original);
|
|
6749
|
+
this.setWorkingFeatures(this.cloneFeatures(original));
|
|
6750
|
+
this.hasWorkingChanges = false;
|
|
6751
|
+
}
|
|
6502
6752
|
this.isFeatureSessionActive = true;
|
|
6503
6753
|
await this.refreshGeometry();
|
|
6504
|
-
this.setWorkingFeatures(this.cloneFeatures(original));
|
|
6505
|
-
this.hasWorkingChanges = false;
|
|
6506
6754
|
this.redraw();
|
|
6507
6755
|
this.emitWorkingChange();
|
|
6508
|
-
this.updateCommittedFeatures([]);
|
|
6509
6756
|
return { ok: true };
|
|
6510
6757
|
}
|
|
6511
6758
|
},
|
|
@@ -6541,25 +6788,6 @@ var FeatureTool = class {
|
|
|
6541
6788
|
return true;
|
|
6542
6789
|
}
|
|
6543
6790
|
},
|
|
6544
|
-
{
|
|
6545
|
-
command: "getWorkingFeatures",
|
|
6546
|
-
title: "Get Working Features",
|
|
6547
|
-
handler: () => {
|
|
6548
|
-
return this.cloneFeatures(this.workingFeatures);
|
|
6549
|
-
}
|
|
6550
|
-
},
|
|
6551
|
-
{
|
|
6552
|
-
command: "setWorkingFeatures",
|
|
6553
|
-
title: "Set Working Features",
|
|
6554
|
-
handler: async (features) => {
|
|
6555
|
-
await this.refreshGeometry();
|
|
6556
|
-
this.setWorkingFeatures(this.cloneFeatures(features || []));
|
|
6557
|
-
this.hasWorkingChanges = true;
|
|
6558
|
-
this.redraw();
|
|
6559
|
-
this.emitWorkingChange();
|
|
6560
|
-
return { ok: true };
|
|
6561
|
-
}
|
|
6562
|
-
},
|
|
6563
6791
|
{
|
|
6564
6792
|
command: "rollbackFeatureSession",
|
|
6565
6793
|
title: "Rollback Feature Session",
|
|
@@ -6626,17 +6854,24 @@ var FeatureTool = class {
|
|
|
6626
6854
|
this.isUpdatingConfig = false;
|
|
6627
6855
|
}
|
|
6628
6856
|
}
|
|
6857
|
+
hasFeatureSessionDraft() {
|
|
6858
|
+
return Array.isArray(this.sessionOriginalFeatures);
|
|
6859
|
+
}
|
|
6629
6860
|
clearFeatureSessionState() {
|
|
6630
6861
|
this.isFeatureSessionActive = false;
|
|
6631
6862
|
this.sessionOriginalFeatures = null;
|
|
6632
6863
|
}
|
|
6633
|
-
|
|
6634
|
-
if (!this.
|
|
6864
|
+
restoreCommittedFeaturesToConfig() {
|
|
6865
|
+
if (!this.hasFeatureSessionDraft()) return;
|
|
6635
6866
|
const original = this.cloneFeatures(
|
|
6636
6867
|
this.sessionOriginalFeatures || this.getCommittedFeatures()
|
|
6637
6868
|
);
|
|
6638
6869
|
this.updateCommittedFeatures(original);
|
|
6639
|
-
|
|
6870
|
+
}
|
|
6871
|
+
suspendFeatureSession() {
|
|
6872
|
+
if (!this.isFeatureSessionActive) return;
|
|
6873
|
+
this.restoreCommittedFeaturesToConfig();
|
|
6874
|
+
this.isFeatureSessionActive = false;
|
|
6640
6875
|
}
|
|
6641
6876
|
emitWorkingChange() {
|
|
6642
6877
|
var _a;
|
|
@@ -6658,7 +6893,7 @@ var FeatureTool = class {
|
|
|
6658
6893
|
}
|
|
6659
6894
|
async resetWorkingFeaturesFromSource() {
|
|
6660
6895
|
const next = this.cloneFeatures(
|
|
6661
|
-
this.
|
|
6896
|
+
this.sessionOriginalFeatures || this.getCommittedFeatures()
|
|
6662
6897
|
);
|
|
6663
6898
|
await this.refreshGeometry();
|
|
6664
6899
|
this.setWorkingFeatures(next);
|
|
@@ -6882,11 +7117,35 @@ var FeatureTool = class {
|
|
|
6882
7117
|
this.handleSceneGeometryChange = null;
|
|
6883
7118
|
}
|
|
6884
7119
|
this.renderSeq += 1;
|
|
6885
|
-
this.
|
|
7120
|
+
this.markerSpecs = [];
|
|
7121
|
+
this.sessionDielineSpecs = [];
|
|
7122
|
+
this.sessionDielineEffects = [];
|
|
6886
7123
|
(_a = this.renderProducerDisposable) == null ? void 0 : _a.dispose();
|
|
6887
7124
|
this.renderProducerDisposable = void 0;
|
|
6888
7125
|
void this.canvasService.flushRenderFromProducers();
|
|
6889
7126
|
}
|
|
7127
|
+
createHatchPattern(color = "rgba(0, 0, 0, 0.3)") {
|
|
7128
|
+
if (typeof document === "undefined") {
|
|
7129
|
+
return void 0;
|
|
7130
|
+
}
|
|
7131
|
+
const size = 20;
|
|
7132
|
+
const canvas = document.createElement("canvas");
|
|
7133
|
+
canvas.width = size;
|
|
7134
|
+
canvas.height = size;
|
|
7135
|
+
const ctx = canvas.getContext("2d");
|
|
7136
|
+
if (ctx) {
|
|
7137
|
+
ctx.clearRect(0, 0, size, size);
|
|
7138
|
+
ctx.strokeStyle = color;
|
|
7139
|
+
ctx.lineWidth = 1;
|
|
7140
|
+
ctx.beginPath();
|
|
7141
|
+
ctx.moveTo(0, size);
|
|
7142
|
+
ctx.lineTo(size, 0);
|
|
7143
|
+
ctx.stroke();
|
|
7144
|
+
}
|
|
7145
|
+
return new import_fabric4.Pattern({
|
|
7146
|
+
source: canvas
|
|
7147
|
+
});
|
|
7148
|
+
}
|
|
6890
7149
|
getDraggableMarkerTarget(target) {
|
|
6891
7150
|
var _a, _b;
|
|
6892
7151
|
if (!this.isFeatureSessionActive || !this.isToolActive) return null;
|
|
@@ -6962,6 +7221,7 @@ var FeatureTool = class {
|
|
|
6962
7221
|
next[index] = updatedFeature;
|
|
6963
7222
|
this.setWorkingFeatures(next);
|
|
6964
7223
|
this.hasWorkingChanges = true;
|
|
7224
|
+
this.redraw();
|
|
6965
7225
|
this.emitWorkingChange();
|
|
6966
7226
|
}
|
|
6967
7227
|
syncGroupFromCanvas(target) {
|
|
@@ -7000,6 +7260,7 @@ var FeatureTool = class {
|
|
|
7000
7260
|
if (!changed) return;
|
|
7001
7261
|
this.setWorkingFeatures(next);
|
|
7002
7262
|
this.hasWorkingChanges = true;
|
|
7263
|
+
this.redraw();
|
|
7003
7264
|
this.emitWorkingChange();
|
|
7004
7265
|
}
|
|
7005
7266
|
redraw(options = {}) {
|
|
@@ -7008,7 +7269,10 @@ var FeatureTool = class {
|
|
|
7008
7269
|
async redrawAsync(options = {}) {
|
|
7009
7270
|
if (!this.canvasService) return;
|
|
7010
7271
|
const seq = ++this.renderSeq;
|
|
7011
|
-
this.
|
|
7272
|
+
this.markerSpecs = this.buildMarkerSpecs();
|
|
7273
|
+
const sessionRender = this.buildSessionDielineRender();
|
|
7274
|
+
this.sessionDielineSpecs = sessionRender.specs;
|
|
7275
|
+
this.sessionDielineEffects = sessionRender.effects;
|
|
7012
7276
|
if (seq !== this.renderSeq) return;
|
|
7013
7277
|
await this.canvasService.flushRenderFromProducers();
|
|
7014
7278
|
if (seq !== this.renderSeq) return;
|
|
@@ -7016,15 +7280,77 @@ var FeatureTool = class {
|
|
|
7016
7280
|
this.enforceConstraints();
|
|
7017
7281
|
}
|
|
7018
7282
|
}
|
|
7019
|
-
|
|
7283
|
+
buildSessionDielineRender() {
|
|
7284
|
+
if (!this.isSessionVisible() || !this.canvasService) {
|
|
7285
|
+
return { specs: [], effects: [] };
|
|
7286
|
+
}
|
|
7287
|
+
const configService = this.getConfigService();
|
|
7288
|
+
if (!configService) {
|
|
7289
|
+
return { specs: [], effects: [] };
|
|
7290
|
+
}
|
|
7291
|
+
const sceneLayout = computeSceneLayout(
|
|
7292
|
+
this.canvasService,
|
|
7293
|
+
readSizeState(configService)
|
|
7294
|
+
);
|
|
7295
|
+
if (!sceneLayout) {
|
|
7296
|
+
return { specs: [], effects: [] };
|
|
7297
|
+
}
|
|
7298
|
+
const state = readDielineState(configService);
|
|
7299
|
+
state.features = this.cloneFeatures(this.workingFeatures);
|
|
7300
|
+
return buildDielineRenderBundle({
|
|
7301
|
+
state,
|
|
7302
|
+
sceneLayout,
|
|
7303
|
+
canvasWidth: sceneLayout.canvasWidth || this.canvasService.canvas.width || 800,
|
|
7304
|
+
canvasHeight: sceneLayout.canvasHeight || this.canvasService.canvas.height || 600,
|
|
7305
|
+
hasImages: this.hasImageItems(),
|
|
7306
|
+
createHatchPattern: (color) => this.createHatchPattern(color),
|
|
7307
|
+
clipTargetPassIds: [IMAGE_OBJECT_LAYER_ID],
|
|
7308
|
+
clipVisibility: { op: "const", value: true },
|
|
7309
|
+
ids: {
|
|
7310
|
+
inside: "feature.session.dieline.inside",
|
|
7311
|
+
bleedZone: "feature.session.dieline.bleed-zone",
|
|
7312
|
+
offsetBorder: "feature.session.dieline.offset-border",
|
|
7313
|
+
border: "feature.session.dieline.border",
|
|
7314
|
+
clip: "feature.session.dieline.clip.image",
|
|
7315
|
+
clipSource: "feature.session.dieline.effect.clip-path"
|
|
7316
|
+
}
|
|
7317
|
+
});
|
|
7318
|
+
}
|
|
7319
|
+
hasImageItems() {
|
|
7320
|
+
const configService = this.getConfigService();
|
|
7321
|
+
if (!configService) return false;
|
|
7322
|
+
const items = configService.get("image.items", []);
|
|
7323
|
+
return Array.isArray(items) && items.length > 0;
|
|
7324
|
+
}
|
|
7325
|
+
buildMarkerSpecs() {
|
|
7020
7326
|
if (!this.isFeatureSessionActive || !this.currentGeometry || this.workingFeatures.length === 0) {
|
|
7021
7327
|
return [];
|
|
7022
7328
|
}
|
|
7023
7329
|
const groups = /* @__PURE__ */ new Map();
|
|
7024
7330
|
const singles = [];
|
|
7025
|
-
|
|
7331
|
+
const placements = resolveFeaturePlacements(
|
|
7332
|
+
this.workingFeatures,
|
|
7333
|
+
{
|
|
7334
|
+
shape: this.currentGeometry.shape,
|
|
7335
|
+
shapeStyle: this.currentGeometry.shapeStyle,
|
|
7336
|
+
pathData: this.currentGeometry.pathData,
|
|
7337
|
+
customSourceWidthPx: this.currentGeometry.customSourceWidthPx,
|
|
7338
|
+
customSourceHeightPx: this.currentGeometry.customSourceHeightPx,
|
|
7339
|
+
x: this.currentGeometry.x,
|
|
7340
|
+
y: this.currentGeometry.y,
|
|
7341
|
+
width: this.currentGeometry.width,
|
|
7342
|
+
height: this.currentGeometry.height,
|
|
7343
|
+
radius: this.currentGeometry.radius,
|
|
7344
|
+
scale: this.currentGeometry.scale || 1
|
|
7345
|
+
}
|
|
7346
|
+
);
|
|
7347
|
+
placements.forEach((placement, index) => {
|
|
7348
|
+
const feature = placement.feature;
|
|
7026
7349
|
const geometry = this.getGeometryForFeature(this.currentGeometry, feature);
|
|
7027
|
-
const position =
|
|
7350
|
+
const position = {
|
|
7351
|
+
x: placement.centerX,
|
|
7352
|
+
y: placement.centerY
|
|
7353
|
+
};
|
|
7028
7354
|
const scale = geometry.scale || 1;
|
|
7029
7355
|
const marker = {
|
|
7030
7356
|
feature,
|
|
@@ -7289,7 +7615,7 @@ var FeatureTool = class {
|
|
|
7289
7615
|
|
|
7290
7616
|
// src/extensions/film/FilmTool.ts
|
|
7291
7617
|
var import_core6 = require("@pooder/core");
|
|
7292
|
-
var
|
|
7618
|
+
var import_fabric5 = require("fabric");
|
|
7293
7619
|
var FILM_IMAGE_ID = "film-image";
|
|
7294
7620
|
var DEFAULT_WIDTH2 = 800;
|
|
7295
7621
|
var DEFAULT_HEIGHT2 = 600;
|
|
@@ -7463,7 +7789,7 @@ var FilmTool = class {
|
|
|
7463
7789
|
}
|
|
7464
7790
|
async loadImageSize(src) {
|
|
7465
7791
|
try {
|
|
7466
|
-
const image = await
|
|
7792
|
+
const image = await import_fabric5.FabricImage.fromURL(src, {
|
|
7467
7793
|
crossOrigin: "anonymous"
|
|
7468
7794
|
});
|
|
7469
7795
|
const width = Number((image == null ? void 0 : image.width) || 0);
|
|
@@ -7595,11 +7921,12 @@ var EXTENSION_LINE_LENGTH = 5;
|
|
|
7595
7921
|
var MIN_ARROW_SIZE = 4;
|
|
7596
7922
|
var THICKNESS_TO_STROKE_WIDTH_RATIO = 20;
|
|
7597
7923
|
var DEFAULT_THICKNESS = 20;
|
|
7598
|
-
var DEFAULT_GAP =
|
|
7924
|
+
var DEFAULT_GAP = 65;
|
|
7599
7925
|
var DEFAULT_FONT_SIZE = 10;
|
|
7600
7926
|
var DEFAULT_BACKGROUND_COLOR = "#f0f0f0";
|
|
7601
7927
|
var DEFAULT_TEXT_COLOR = "#333333";
|
|
7602
7928
|
var DEFAULT_LINE_COLOR = "#999999";
|
|
7929
|
+
var RULER_DEBUG_KEY = "ruler.debug";
|
|
7603
7930
|
var RULER_THICKNESS_MIN = 10;
|
|
7604
7931
|
var RULER_THICKNESS_MAX = 100;
|
|
7605
7932
|
var RULER_GAP_MIN = 0;
|
|
@@ -7618,6 +7945,7 @@ var RulerTool = class {
|
|
|
7618
7945
|
this.textColor = DEFAULT_TEXT_COLOR;
|
|
7619
7946
|
this.lineColor = DEFAULT_LINE_COLOR;
|
|
7620
7947
|
this.fontSize = DEFAULT_FONT_SIZE;
|
|
7948
|
+
this.debugEnabled = false;
|
|
7621
7949
|
this.renderSeq = 0;
|
|
7622
7950
|
this.numericProps = /* @__PURE__ */ new Set(["thickness", "gap", "fontSize"]);
|
|
7623
7951
|
this.specs = [];
|
|
@@ -7666,7 +7994,14 @@ var RulerTool = class {
|
|
|
7666
7994
|
this.syncConfig(configService);
|
|
7667
7995
|
configService.onAnyChange((e) => {
|
|
7668
7996
|
let shouldUpdate = false;
|
|
7669
|
-
if (e.key
|
|
7997
|
+
if (e.key === RULER_DEBUG_KEY) {
|
|
7998
|
+
this.debugEnabled = e.value === true;
|
|
7999
|
+
this.log("config:update", {
|
|
8000
|
+
key: e.key,
|
|
8001
|
+
raw: e.value,
|
|
8002
|
+
normalized: this.debugEnabled
|
|
8003
|
+
});
|
|
8004
|
+
} else if (e.key.startsWith("ruler.")) {
|
|
7670
8005
|
const prop = e.key.split(".")[1];
|
|
7671
8006
|
if (prop && prop in this) {
|
|
7672
8007
|
if (this.numericProps.has(prop)) {
|
|
@@ -7753,6 +8088,12 @@ var RulerTool = class {
|
|
|
7753
8088
|
min: RULER_FONT_SIZE_MIN,
|
|
7754
8089
|
max: RULER_FONT_SIZE_MAX,
|
|
7755
8090
|
default: DEFAULT_FONT_SIZE
|
|
8091
|
+
},
|
|
8092
|
+
{
|
|
8093
|
+
id: RULER_DEBUG_KEY,
|
|
8094
|
+
type: "boolean",
|
|
8095
|
+
label: "Ruler Debug Log",
|
|
8096
|
+
default: false
|
|
7756
8097
|
}
|
|
7757
8098
|
],
|
|
7758
8099
|
[import_core8.ContributionPointIds.COMMANDS]: [
|
|
@@ -7789,7 +8130,11 @@ var RulerTool = class {
|
|
|
7789
8130
|
]
|
|
7790
8131
|
};
|
|
7791
8132
|
}
|
|
8133
|
+
isDebugEnabled() {
|
|
8134
|
+
return this.debugEnabled;
|
|
8135
|
+
}
|
|
7792
8136
|
log(step, payload) {
|
|
8137
|
+
if (!this.isDebugEnabled()) return;
|
|
7793
8138
|
if (payload) {
|
|
7794
8139
|
console.debug(`[RulerTool] ${step}`, payload);
|
|
7795
8140
|
return;
|
|
@@ -7818,6 +8163,7 @@ var RulerTool = class {
|
|
|
7818
8163
|
configService.get("ruler.fontSize", this.fontSize),
|
|
7819
8164
|
DEFAULT_FONT_SIZE
|
|
7820
8165
|
);
|
|
8166
|
+
this.debugEnabled = configService.get(RULER_DEBUG_KEY, this.debugEnabled) === true;
|
|
7821
8167
|
this.log("config:loaded", {
|
|
7822
8168
|
thickness: this.thickness,
|
|
7823
8169
|
gap: this.gap,
|
|
@@ -9458,7 +9804,7 @@ var SceneLayoutService = class {
|
|
|
9458
9804
|
};
|
|
9459
9805
|
|
|
9460
9806
|
// src/services/CanvasService.ts
|
|
9461
|
-
var
|
|
9807
|
+
var import_fabric6 = require("fabric");
|
|
9462
9808
|
var import_core11 = require("@pooder/core");
|
|
9463
9809
|
|
|
9464
9810
|
// src/services/ViewportSystem.ts
|
|
@@ -9634,10 +9980,10 @@ var CanvasService = class {
|
|
|
9634
9980
|
if (this.producerApplyInProgress) return;
|
|
9635
9981
|
this.scheduleManagedPassVisibilityRefresh();
|
|
9636
9982
|
};
|
|
9637
|
-
if (el instanceof
|
|
9983
|
+
if (el instanceof import_fabric6.Canvas) {
|
|
9638
9984
|
this.canvas = el;
|
|
9639
9985
|
} else {
|
|
9640
|
-
this.canvas = new
|
|
9986
|
+
this.canvas = new import_fabric6.Canvas(el, {
|
|
9641
9987
|
preserveObjectStacking: true,
|
|
9642
9988
|
...options
|
|
9643
9989
|
});
|
|
@@ -10532,7 +10878,7 @@ var CanvasService = class {
|
|
|
10532
10878
|
var _a, _b;
|
|
10533
10879
|
if (spec.type === "rect") {
|
|
10534
10880
|
const props = this.resolveFabricProps(spec, spec.props || {});
|
|
10535
|
-
const rect = new
|
|
10881
|
+
const rect = new import_fabric6.Rect({
|
|
10536
10882
|
...props,
|
|
10537
10883
|
data: { ...spec.data || {}, id: spec.id }
|
|
10538
10884
|
});
|
|
@@ -10543,7 +10889,7 @@ var CanvasService = class {
|
|
|
10543
10889
|
const pathData = this.readPathDataFromSpec(spec);
|
|
10544
10890
|
if (!pathData) return void 0;
|
|
10545
10891
|
const props = this.resolveFabricProps(spec, spec.props || {});
|
|
10546
|
-
const path = new
|
|
10892
|
+
const path = new import_fabric6.Path(pathData, {
|
|
10547
10893
|
...props,
|
|
10548
10894
|
data: { ...spec.data || {}, id: spec.id }
|
|
10549
10895
|
});
|
|
@@ -10552,7 +10898,7 @@ var CanvasService = class {
|
|
|
10552
10898
|
}
|
|
10553
10899
|
if (spec.type === "image") {
|
|
10554
10900
|
if (!spec.src) return void 0;
|
|
10555
|
-
const image = await
|
|
10901
|
+
const image = await import_fabric6.Image.fromURL(spec.src, { crossOrigin: "anonymous" });
|
|
10556
10902
|
const props = this.resolveFabricProps(spec, spec.props || {});
|
|
10557
10903
|
image.set({
|
|
10558
10904
|
...props,
|
|
@@ -10564,7 +10910,7 @@ var CanvasService = class {
|
|
|
10564
10910
|
if (spec.type === "text") {
|
|
10565
10911
|
const content = String((_b = (_a = spec.props) == null ? void 0 : _a.text) != null ? _b : "");
|
|
10566
10912
|
const props = this.resolveFabricProps(spec, spec.props || {});
|
|
10567
|
-
const text = new
|
|
10913
|
+
const text = new import_fabric6.Text(content, {
|
|
10568
10914
|
...props,
|
|
10569
10915
|
data: { ...spec.data || {}, id: spec.id }
|
|
10570
10916
|
});
|
|
@@ -10590,11 +10936,13 @@ var CanvasService = class {
|
|
|
10590
10936
|
WhiteInkTool,
|
|
10591
10937
|
computeImageCoverScale,
|
|
10592
10938
|
computeWhiteInkCoverScale,
|
|
10939
|
+
createDefaultDielineState,
|
|
10593
10940
|
createDielineCommands,
|
|
10594
10941
|
createDielineConfigurations,
|
|
10595
10942
|
createImageCommands,
|
|
10596
10943
|
createImageConfigurations,
|
|
10597
10944
|
createWhiteInkCommands,
|
|
10598
10945
|
createWhiteInkConfigurations,
|
|
10599
|
-
evaluateVisibilityExpr
|
|
10946
|
+
evaluateVisibilityExpr,
|
|
10947
|
+
readDielineState
|
|
10600
10948
|
});
|