@pooder/kit 6.0.0 → 6.0.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.js +1 -1
- package/.test-dist/src/extensions/dieline.js +4 -0
- package/.test-dist/src/extensions/image.js +182 -7
- package/.test-dist/src/services/CanvasService.js +34 -13
- package/.test-dist/src/services/visibility.js +3 -0
- package/.test-dist/tests/run.js +2 -0
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +229 -20
- package/dist/index.mjs +232 -21
- package/package.json +1 -1
- package/src/extensions/dieline.ts +4 -0
- package/src/extensions/image.ts +240 -7
- package/src/services/CanvasService.ts +43 -12
- package/src/services/renderSpec.ts +2 -0
- package/src/services/visibility.ts +5 -0
- package/tests/run.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -1589,6 +1589,34 @@ function getPathBounds(pathData) {
|
|
|
1589
1589
|
// src/extensions/image.ts
|
|
1590
1590
|
var IMAGE_OBJECT_LAYER_ID = "image.user";
|
|
1591
1591
|
var IMAGE_OVERLAY_LAYER_ID = "image-overlay";
|
|
1592
|
+
var IMAGE_DEFAULT_CONTROL_CAPABILITIES = [
|
|
1593
|
+
"rotate",
|
|
1594
|
+
"scale"
|
|
1595
|
+
];
|
|
1596
|
+
var IMAGE_CONTROL_DESCRIPTORS = [
|
|
1597
|
+
{
|
|
1598
|
+
key: "tl",
|
|
1599
|
+
capability: "rotate",
|
|
1600
|
+
create: () => new import_fabric2.Control({
|
|
1601
|
+
x: -0.5,
|
|
1602
|
+
y: -0.5,
|
|
1603
|
+
actionName: "rotate",
|
|
1604
|
+
actionHandler: import_fabric2.controlsUtils.rotationWithSnapping,
|
|
1605
|
+
cursorStyleHandler: import_fabric2.controlsUtils.rotationStyleHandler
|
|
1606
|
+
})
|
|
1607
|
+
},
|
|
1608
|
+
{
|
|
1609
|
+
key: "br",
|
|
1610
|
+
capability: "scale",
|
|
1611
|
+
create: () => new import_fabric2.Control({
|
|
1612
|
+
x: 0.5,
|
|
1613
|
+
y: 0.5,
|
|
1614
|
+
actionName: "scale",
|
|
1615
|
+
actionHandler: import_fabric2.controlsUtils.scalingEqually,
|
|
1616
|
+
cursorStyleHandler: import_fabric2.controlsUtils.scaleCursorStyleHandler
|
|
1617
|
+
})
|
|
1618
|
+
}
|
|
1619
|
+
];
|
|
1592
1620
|
var ImageTool = class {
|
|
1593
1621
|
constructor() {
|
|
1594
1622
|
this.id = "pooder.kit.image";
|
|
@@ -1607,6 +1635,7 @@ var ImageTool = class {
|
|
|
1607
1635
|
this.renderSeq = 0;
|
|
1608
1636
|
this.imageSpecs = [];
|
|
1609
1637
|
this.overlaySpecs = [];
|
|
1638
|
+
this.imageControlsByCapabilityKey = /* @__PURE__ */ new Map();
|
|
1610
1639
|
this.onToolActivated = (event) => {
|
|
1611
1640
|
const before = this.isToolActive;
|
|
1612
1641
|
this.syncToolActiveFromWorkbench(event.id);
|
|
@@ -1771,7 +1800,10 @@ var ImageTool = class {
|
|
|
1771
1800
|
this.updateImages();
|
|
1772
1801
|
return;
|
|
1773
1802
|
}
|
|
1774
|
-
if (e.key.startsWith("size.") || e.key.startsWith("image.frame.")) {
|
|
1803
|
+
if (e.key.startsWith("size.") || e.key.startsWith("image.frame.") || e.key.startsWith("image.control.")) {
|
|
1804
|
+
if (e.key.startsWith("image.control.")) {
|
|
1805
|
+
this.imageControlsByCapabilityKey.clear();
|
|
1806
|
+
}
|
|
1775
1807
|
this.updateImages();
|
|
1776
1808
|
}
|
|
1777
1809
|
});
|
|
@@ -1799,6 +1831,7 @@ var ImageTool = class {
|
|
|
1799
1831
|
this.cropShapeHatchPatternKey = void 0;
|
|
1800
1832
|
this.imageSpecs = [];
|
|
1801
1833
|
this.overlaySpecs = [];
|
|
1834
|
+
this.imageControlsByCapabilityKey.clear();
|
|
1802
1835
|
this.clearRenderedImages();
|
|
1803
1836
|
(_b = this.renderProducerDisposable) == null ? void 0 : _b.dispose();
|
|
1804
1837
|
this.renderProducerDisposable = void 0;
|
|
@@ -1821,6 +1854,90 @@ var ImageTool = class {
|
|
|
1821
1854
|
isImageEditingVisible() {
|
|
1822
1855
|
return this.isToolActive || this.isImageSelectionActive || !!this.focusedImageId;
|
|
1823
1856
|
}
|
|
1857
|
+
getEnabledImageControlCapabilities() {
|
|
1858
|
+
return IMAGE_DEFAULT_CONTROL_CAPABILITIES;
|
|
1859
|
+
}
|
|
1860
|
+
getImageControls(capabilities) {
|
|
1861
|
+
const normalized = [...new Set(capabilities)].sort();
|
|
1862
|
+
const cacheKey = normalized.join("|");
|
|
1863
|
+
const cached = this.imageControlsByCapabilityKey.get(cacheKey);
|
|
1864
|
+
if (cached) {
|
|
1865
|
+
return cached;
|
|
1866
|
+
}
|
|
1867
|
+
const enabled = new Set(normalized);
|
|
1868
|
+
const controls = {};
|
|
1869
|
+
IMAGE_CONTROL_DESCRIPTORS.forEach((descriptor) => {
|
|
1870
|
+
if (!enabled.has(descriptor.capability)) return;
|
|
1871
|
+
controls[descriptor.key] = descriptor.create();
|
|
1872
|
+
});
|
|
1873
|
+
this.imageControlsByCapabilityKey.set(cacheKey, controls);
|
|
1874
|
+
return controls;
|
|
1875
|
+
}
|
|
1876
|
+
getImageControlVisualConfig() {
|
|
1877
|
+
var _a, _b, _c, _d;
|
|
1878
|
+
const cornerSizeRaw = Number(
|
|
1879
|
+
(_a = this.getConfig("image.control.cornerSize", 14)) != null ? _a : 14
|
|
1880
|
+
);
|
|
1881
|
+
const touchCornerSizeRaw = Number(
|
|
1882
|
+
(_b = this.getConfig("image.control.touchCornerSize", 24)) != null ? _b : 24
|
|
1883
|
+
);
|
|
1884
|
+
const borderScaleFactorRaw = Number(
|
|
1885
|
+
(_c = this.getConfig("image.control.borderScaleFactor", 1.5)) != null ? _c : 1.5
|
|
1886
|
+
);
|
|
1887
|
+
const paddingRaw = Number(
|
|
1888
|
+
(_d = this.getConfig("image.control.padding", 0)) != null ? _d : 0
|
|
1889
|
+
);
|
|
1890
|
+
const cornerStyleRaw = this.getConfig(
|
|
1891
|
+
"image.control.cornerStyle",
|
|
1892
|
+
"circle"
|
|
1893
|
+
) || "circle";
|
|
1894
|
+
const cornerStyle = cornerStyleRaw === "rect" ? "rect" : "circle";
|
|
1895
|
+
return {
|
|
1896
|
+
cornerSize: Number.isFinite(cornerSizeRaw) ? Math.max(4, Math.min(64, cornerSizeRaw)) : 14,
|
|
1897
|
+
touchCornerSize: Number.isFinite(touchCornerSizeRaw) ? Math.max(8, Math.min(96, touchCornerSizeRaw)) : 24,
|
|
1898
|
+
cornerStyle,
|
|
1899
|
+
cornerColor: this.getConfig("image.control.cornerColor", "#ffffff") || "#ffffff",
|
|
1900
|
+
cornerStrokeColor: this.getConfig("image.control.cornerStrokeColor", "#1677ff") || "#1677ff",
|
|
1901
|
+
transparentCorners: !!this.getConfig(
|
|
1902
|
+
"image.control.transparentCorners",
|
|
1903
|
+
false
|
|
1904
|
+
),
|
|
1905
|
+
borderColor: this.getConfig("image.control.borderColor", "#1677ff") || "#1677ff",
|
|
1906
|
+
borderScaleFactor: Number.isFinite(borderScaleFactorRaw) ? Math.max(0.5, Math.min(8, borderScaleFactorRaw)) : 1.5,
|
|
1907
|
+
padding: Number.isFinite(paddingRaw) ? Math.max(0, Math.min(64, paddingRaw)) : 0
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
applyImageObjectInteractionState(obj) {
|
|
1911
|
+
var _a;
|
|
1912
|
+
if (!obj) return;
|
|
1913
|
+
const visible = this.isImageEditingVisible();
|
|
1914
|
+
const visual = this.getImageControlVisualConfig();
|
|
1915
|
+
obj.set({
|
|
1916
|
+
selectable: visible,
|
|
1917
|
+
evented: visible,
|
|
1918
|
+
hasControls: visible,
|
|
1919
|
+
hasBorders: visible,
|
|
1920
|
+
lockScalingFlip: true,
|
|
1921
|
+
cornerSize: visual.cornerSize,
|
|
1922
|
+
touchCornerSize: visual.touchCornerSize,
|
|
1923
|
+
cornerStyle: visual.cornerStyle,
|
|
1924
|
+
cornerColor: visual.cornerColor,
|
|
1925
|
+
cornerStrokeColor: visual.cornerStrokeColor,
|
|
1926
|
+
transparentCorners: visual.transparentCorners,
|
|
1927
|
+
borderColor: visual.borderColor,
|
|
1928
|
+
borderScaleFactor: visual.borderScaleFactor,
|
|
1929
|
+
padding: visual.padding
|
|
1930
|
+
});
|
|
1931
|
+
obj.controls = this.getImageControls(
|
|
1932
|
+
this.getEnabledImageControlCapabilities()
|
|
1933
|
+
);
|
|
1934
|
+
(_a = obj.setCoords) == null ? void 0 : _a.call(obj);
|
|
1935
|
+
}
|
|
1936
|
+
refreshImageObjectInteractionState() {
|
|
1937
|
+
this.getImageObjects().forEach(
|
|
1938
|
+
(obj) => this.applyImageObjectInteractionState(obj)
|
|
1939
|
+
);
|
|
1940
|
+
}
|
|
1824
1941
|
isDebugEnabled() {
|
|
1825
1942
|
return !!this.getConfig("image.debug", false);
|
|
1826
1943
|
}
|
|
@@ -1863,6 +1980,73 @@ var ImageTool = class {
|
|
|
1863
1980
|
label: "Image Debug Log",
|
|
1864
1981
|
default: false
|
|
1865
1982
|
},
|
|
1983
|
+
{
|
|
1984
|
+
id: "image.control.cornerSize",
|
|
1985
|
+
type: "number",
|
|
1986
|
+
label: "Image Control Corner Size",
|
|
1987
|
+
min: 4,
|
|
1988
|
+
max: 64,
|
|
1989
|
+
step: 1,
|
|
1990
|
+
default: 14
|
|
1991
|
+
},
|
|
1992
|
+
{
|
|
1993
|
+
id: "image.control.touchCornerSize",
|
|
1994
|
+
type: "number",
|
|
1995
|
+
label: "Image Control Touch Corner Size",
|
|
1996
|
+
min: 8,
|
|
1997
|
+
max: 96,
|
|
1998
|
+
step: 1,
|
|
1999
|
+
default: 24
|
|
2000
|
+
},
|
|
2001
|
+
{
|
|
2002
|
+
id: "image.control.cornerStyle",
|
|
2003
|
+
type: "select",
|
|
2004
|
+
label: "Image Control Corner Style",
|
|
2005
|
+
options: ["circle", "rect"],
|
|
2006
|
+
default: "circle"
|
|
2007
|
+
},
|
|
2008
|
+
{
|
|
2009
|
+
id: "image.control.cornerColor",
|
|
2010
|
+
type: "color",
|
|
2011
|
+
label: "Image Control Corner Color",
|
|
2012
|
+
default: "#ffffff"
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
id: "image.control.cornerStrokeColor",
|
|
2016
|
+
type: "color",
|
|
2017
|
+
label: "Image Control Corner Stroke Color",
|
|
2018
|
+
default: "#1677ff"
|
|
2019
|
+
},
|
|
2020
|
+
{
|
|
2021
|
+
id: "image.control.transparentCorners",
|
|
2022
|
+
type: "boolean",
|
|
2023
|
+
label: "Image Control Transparent Corners",
|
|
2024
|
+
default: false
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
id: "image.control.borderColor",
|
|
2028
|
+
type: "color",
|
|
2029
|
+
label: "Image Control Border Color",
|
|
2030
|
+
default: "#1677ff"
|
|
2031
|
+
},
|
|
2032
|
+
{
|
|
2033
|
+
id: "image.control.borderScaleFactor",
|
|
2034
|
+
type: "number",
|
|
2035
|
+
label: "Image Control Border Width",
|
|
2036
|
+
min: 0.5,
|
|
2037
|
+
max: 8,
|
|
2038
|
+
step: 0.1,
|
|
2039
|
+
default: 1.5
|
|
2040
|
+
},
|
|
2041
|
+
{
|
|
2042
|
+
id: "image.control.padding",
|
|
2043
|
+
type: "number",
|
|
2044
|
+
label: "Image Control Padding",
|
|
2045
|
+
min: 0,
|
|
2046
|
+
max: 64,
|
|
2047
|
+
step: 1,
|
|
2048
|
+
default: 0
|
|
2049
|
+
},
|
|
1866
2050
|
{
|
|
1867
2051
|
id: "image.frame.strokeColor",
|
|
1868
2052
|
type: "color",
|
|
@@ -2100,12 +2284,7 @@ var ImageTool = class {
|
|
|
2100
2284
|
} else {
|
|
2101
2285
|
const obj = this.getImageObject(id);
|
|
2102
2286
|
if (obj) {
|
|
2103
|
-
|
|
2104
|
-
selectable: true,
|
|
2105
|
-
evented: true,
|
|
2106
|
-
hasControls: true,
|
|
2107
|
-
hasBorders: true
|
|
2108
|
-
});
|
|
2287
|
+
this.applyImageObjectInteractionState(obj);
|
|
2109
2288
|
canvas.setActiveObject(obj);
|
|
2110
2289
|
}
|
|
2111
2290
|
}
|
|
@@ -2902,6 +3081,7 @@ var ImageTool = class {
|
|
|
2902
3081
|
this.overlaySpecs = this.buildOverlaySpecs(frame, sceneGeometry);
|
|
2903
3082
|
await this.canvasService.flushRenderFromProducers();
|
|
2904
3083
|
if (seq !== this.renderSeq) return;
|
|
3084
|
+
this.refreshImageObjectInteractionState();
|
|
2905
3085
|
renderItems.forEach((item) => {
|
|
2906
3086
|
if (!this.getImageObject(item.id)) return;
|
|
2907
3087
|
const resolver = this.loadResolvers.get(item.id);
|
|
@@ -5253,6 +5433,10 @@ var DielineTool = class {
|
|
|
5253
5433
|
{
|
|
5254
5434
|
type: "clipPath",
|
|
5255
5435
|
id: "dieline.clip.image",
|
|
5436
|
+
visibility: {
|
|
5437
|
+
op: "not",
|
|
5438
|
+
expr: { op: "anySessionActive" }
|
|
5439
|
+
},
|
|
5256
5440
|
targetPassIds: [IMAGE_OBJECT_LAYER_ID2],
|
|
5257
5441
|
source: {
|
|
5258
5442
|
id: "dieline.effect.clip-path",
|
|
@@ -8890,6 +9074,9 @@ function evaluateVisibilityExpr(expr, context) {
|
|
|
8890
9074
|
if (!toolId) return false;
|
|
8891
9075
|
return context.isSessionActive ? context.isSessionActive(toolId) : false;
|
|
8892
9076
|
}
|
|
9077
|
+
if (expr.op === "anySessionActive") {
|
|
9078
|
+
return context.hasAnyActiveSession ? context.hasAnyActiveSession() : false;
|
|
9079
|
+
}
|
|
8893
9080
|
if (expr.op === "layerExists") {
|
|
8894
9081
|
return layerState(context, expr.layerId).exists === true;
|
|
8895
9082
|
}
|
|
@@ -8923,6 +9110,7 @@ var CanvasService = class {
|
|
|
8923
9110
|
this.visibilityRefreshScheduled = false;
|
|
8924
9111
|
this.managedProducerPassIds = /* @__PURE__ */ new Set();
|
|
8925
9112
|
this.managedPassMetas = /* @__PURE__ */ new Map();
|
|
9113
|
+
this.managedPassEffects = [];
|
|
8926
9114
|
this.canvasForwardersBound = false;
|
|
8927
9115
|
this.forwardSelectionCreated = (e) => {
|
|
8928
9116
|
var _a;
|
|
@@ -8950,9 +9138,11 @@ var CanvasService = class {
|
|
|
8950
9138
|
};
|
|
8951
9139
|
this.onToolActivated = () => {
|
|
8952
9140
|
this.applyManagedPassVisibility();
|
|
9141
|
+
void this.applyManagedPassEffects(void 0, { render: true });
|
|
8953
9142
|
};
|
|
8954
9143
|
this.onToolSessionChanged = () => {
|
|
8955
9144
|
this.applyManagedPassVisibility();
|
|
9145
|
+
void this.applyManagedPassEffects(void 0, { render: true });
|
|
8956
9146
|
};
|
|
8957
9147
|
this.onCanvasObjectChanged = () => {
|
|
8958
9148
|
if (this.producerApplyInProgress) return;
|
|
@@ -9017,6 +9207,7 @@ var CanvasService = class {
|
|
|
9017
9207
|
this.renderProducers.clear();
|
|
9018
9208
|
this.managedProducerPassIds.clear();
|
|
9019
9209
|
this.managedPassMetas.clear();
|
|
9210
|
+
this.managedPassEffects = [];
|
|
9020
9211
|
this.context = void 0;
|
|
9021
9212
|
this.workbenchService = void 0;
|
|
9022
9213
|
this.toolSessionService = void 0;
|
|
@@ -9123,6 +9314,7 @@ var CanvasService = class {
|
|
|
9123
9314
|
return {
|
|
9124
9315
|
type: "clipPath",
|
|
9125
9316
|
key,
|
|
9317
|
+
visibility: effect.visibility,
|
|
9126
9318
|
source: {
|
|
9127
9319
|
...source,
|
|
9128
9320
|
id: sourceId
|
|
@@ -9230,22 +9422,30 @@ var CanvasService = class {
|
|
|
9230
9422
|
});
|
|
9231
9423
|
return state;
|
|
9232
9424
|
}
|
|
9233
|
-
|
|
9425
|
+
isSessionActive(toolId) {
|
|
9426
|
+
if (!this.toolSessionService) return false;
|
|
9427
|
+
return this.toolSessionService.getState(toolId).status === "active";
|
|
9428
|
+
}
|
|
9429
|
+
hasAnyActiveSession() {
|
|
9234
9430
|
var _a, _b;
|
|
9431
|
+
return (_b = (_a = this.toolSessionService) == null ? void 0 : _a.hasAnyActiveSession()) != null ? _b : false;
|
|
9432
|
+
}
|
|
9433
|
+
buildVisibilityEvalContext(layers) {
|
|
9434
|
+
var _a, _b;
|
|
9435
|
+
return {
|
|
9436
|
+
activeToolId: (_b = (_a = this.workbenchService) == null ? void 0 : _a.activeToolId) != null ? _b : null,
|
|
9437
|
+
isSessionActive: (toolId) => this.isSessionActive(toolId),
|
|
9438
|
+
hasAnyActiveSession: () => this.hasAnyActiveSession(),
|
|
9439
|
+
layers
|
|
9440
|
+
};
|
|
9441
|
+
}
|
|
9442
|
+
applyManagedPassVisibility(options = {}) {
|
|
9235
9443
|
if (!this.managedPassMetas.size) return false;
|
|
9236
9444
|
const layers = this.getPassRuntimeState();
|
|
9237
|
-
const
|
|
9238
|
-
const isSessionActive = (toolId) => {
|
|
9239
|
-
if (!this.toolSessionService) return false;
|
|
9240
|
-
return this.toolSessionService.getState(toolId).status === "active";
|
|
9241
|
-
};
|
|
9445
|
+
const context = this.buildVisibilityEvalContext(layers);
|
|
9242
9446
|
let changed = false;
|
|
9243
9447
|
this.managedPassMetas.forEach((meta) => {
|
|
9244
|
-
const visible = evaluateVisibilityExpr(meta.visibility,
|
|
9245
|
-
activeToolId,
|
|
9246
|
-
isSessionActive,
|
|
9247
|
-
layers
|
|
9248
|
-
});
|
|
9448
|
+
const visible = evaluateVisibilityExpr(meta.visibility, context);
|
|
9249
9449
|
changed = this.setPassVisibility(meta.id, visible) || changed;
|
|
9250
9450
|
});
|
|
9251
9451
|
if (changed && options.render !== false) {
|
|
@@ -9313,18 +9513,24 @@ var CanvasService = class {
|
|
|
9313
9513
|
}
|
|
9314
9514
|
this.managedProducerPassIds = nextPassIds;
|
|
9315
9515
|
this.managedPassMetas = nextManagedPassMetas;
|
|
9516
|
+
this.managedPassEffects = nextEffects;
|
|
9316
9517
|
this.syncManagedPassStacking(Array.from(nextManagedPassMetas.values()));
|
|
9317
|
-
await this.applyManagedPassEffects(nextEffects);
|
|
9518
|
+
await this.applyManagedPassEffects(nextEffects, { render: false });
|
|
9318
9519
|
this.applyManagedPassVisibility({ render: false });
|
|
9319
9520
|
} finally {
|
|
9320
9521
|
this.producerApplyInProgress = false;
|
|
9321
9522
|
}
|
|
9322
9523
|
this.requestRenderAll();
|
|
9323
9524
|
}
|
|
9324
|
-
async applyManagedPassEffects(effects) {
|
|
9525
|
+
async applyManagedPassEffects(effects = this.managedPassEffects, options = {}) {
|
|
9325
9526
|
const effectTargetMap = /* @__PURE__ */ new Map();
|
|
9527
|
+
const layers = this.getPassRuntimeState();
|
|
9528
|
+
const visibilityContext = this.buildVisibilityEvalContext(layers);
|
|
9326
9529
|
for (const effect of effects) {
|
|
9327
9530
|
if (effect.type !== "clipPath") continue;
|
|
9531
|
+
if (!evaluateVisibilityExpr(effect.visibility, visibilityContext)) {
|
|
9532
|
+
continue;
|
|
9533
|
+
}
|
|
9328
9534
|
effect.targetPassIds.forEach((targetPassId) => {
|
|
9329
9535
|
this.getPassCanvasObjects(targetPassId).forEach((obj) => {
|
|
9330
9536
|
effectTargetMap.set(obj, effect);
|
|
@@ -9356,6 +9562,9 @@ var CanvasService = class {
|
|
|
9356
9562
|
targetEffect.key
|
|
9357
9563
|
);
|
|
9358
9564
|
}
|
|
9565
|
+
if (options.render !== false) {
|
|
9566
|
+
this.requestRenderAll();
|
|
9567
|
+
}
|
|
9359
9568
|
}
|
|
9360
9569
|
getObject(id, passId) {
|
|
9361
9570
|
const normalizedId = String(id || "").trim();
|