@pooder/kit 6.2.2 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.test-dist/src/extensions/image/ImageTool.js +134 -119
- package/.test-dist/src/extensions/image/commands.js +60 -40
- package/.test-dist/src/extensions/image/imageOperations.js +75 -0
- package/.test-dist/src/extensions/image/index.js +1 -0
- package/.test-dist/src/extensions/image/model.js +4 -0
- package/.test-dist/tests/run.js +39 -5
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +250 -163
- package/dist/index.d.ts +250 -163
- package/dist/index.js +265 -157
- package/dist/index.mjs +261 -156
- package/package.json +1 -1
- package/src/extensions/image/ImageTool.ts +172 -145
- package/src/extensions/image/commands.ts +69 -48
- package/src/extensions/image/imageOperations.ts +135 -0
- package/src/extensions/image/index.ts +1 -0
- package/src/extensions/image/model.ts +13 -1
- package/tests/run.ts +49 -8
package/dist/index.js
CHANGED
|
@@ -1074,6 +1074,7 @@ __export(index_exports, {
|
|
|
1074
1074
|
ViewportSystem: () => ViewportSystem,
|
|
1075
1075
|
WhiteInkTool: () => WhiteInkTool,
|
|
1076
1076
|
computeImageCoverScale: () => getCoverScale,
|
|
1077
|
+
computeImageOperationUpdates: () => computeImageOperationUpdates,
|
|
1077
1078
|
computeWhiteInkCoverScale: () => getCoverScale,
|
|
1078
1079
|
createDefaultDielineState: () => createDefaultDielineState,
|
|
1079
1080
|
createDielineCommands: () => createDielineCommands,
|
|
@@ -1083,7 +1084,9 @@ __export(index_exports, {
|
|
|
1083
1084
|
createWhiteInkCommands: () => createWhiteInkCommands,
|
|
1084
1085
|
createWhiteInkConfigurations: () => createWhiteInkConfigurations,
|
|
1085
1086
|
evaluateVisibilityExpr: () => evaluateVisibilityExpr,
|
|
1086
|
-
|
|
1087
|
+
hasAnyImageInViewState: () => hasAnyImageInViewState,
|
|
1088
|
+
readDielineState: () => readDielineState,
|
|
1089
|
+
resolveImageOperationArea: () => resolveImageOperationArea
|
|
1087
1090
|
});
|
|
1088
1091
|
module.exports = __toCommonJS(index_exports);
|
|
1089
1092
|
|
|
@@ -2349,30 +2352,35 @@ function createImageCommands(tool) {
|
|
|
2349
2352
|
}
|
|
2350
2353
|
},
|
|
2351
2354
|
{
|
|
2352
|
-
command: "
|
|
2353
|
-
id: "
|
|
2354
|
-
title: "
|
|
2355
|
+
command: "applyImageOperation",
|
|
2356
|
+
id: "applyImageOperation",
|
|
2357
|
+
title: "Apply Image Operation",
|
|
2358
|
+
handler: async (id, operation, options = {}) => {
|
|
2359
|
+
await tool.applyImageOperation(id, operation, options);
|
|
2360
|
+
}
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
command: "getImageViewState",
|
|
2364
|
+
id: "getImageViewState",
|
|
2365
|
+
title: "Get Image View State",
|
|
2355
2366
|
handler: () => {
|
|
2356
|
-
return tool.
|
|
2367
|
+
return tool.getImageViewState();
|
|
2357
2368
|
}
|
|
2358
2369
|
},
|
|
2359
2370
|
{
|
|
2360
|
-
command: "
|
|
2361
|
-
id: "
|
|
2362
|
-
title: "Set
|
|
2363
|
-
handler: (id, updates) => {
|
|
2364
|
-
tool.
|
|
2371
|
+
command: "setImageTransform",
|
|
2372
|
+
id: "setImageTransform",
|
|
2373
|
+
title: "Set Image Transform",
|
|
2374
|
+
handler: async (id, updates, options = {}) => {
|
|
2375
|
+
await tool.setImageTransform(id, updates, options);
|
|
2365
2376
|
}
|
|
2366
2377
|
},
|
|
2367
2378
|
{
|
|
2368
|
-
command: "
|
|
2369
|
-
id: "
|
|
2370
|
-
title: "Reset
|
|
2379
|
+
command: "imageSessionReset",
|
|
2380
|
+
id: "imageSessionReset",
|
|
2381
|
+
title: "Reset Image Session",
|
|
2371
2382
|
handler: () => {
|
|
2372
|
-
tool.
|
|
2373
|
-
tool.hasWorkingChanges = false;
|
|
2374
|
-
tool.updateImages();
|
|
2375
|
-
tool.emitWorkingChange();
|
|
2383
|
+
tool.resetImageSession();
|
|
2376
2384
|
}
|
|
2377
2385
|
},
|
|
2378
2386
|
{
|
|
@@ -2391,22 +2399,6 @@ function createImageCommands(tool) {
|
|
|
2391
2399
|
return await tool.exportUserCroppedImage(options);
|
|
2392
2400
|
}
|
|
2393
2401
|
},
|
|
2394
|
-
{
|
|
2395
|
-
command: "fitImageToArea",
|
|
2396
|
-
id: "fitImageToArea",
|
|
2397
|
-
title: "Fit Image to Area",
|
|
2398
|
-
handler: async (id, area) => {
|
|
2399
|
-
await tool.fitImageToArea(id, area);
|
|
2400
|
-
}
|
|
2401
|
-
},
|
|
2402
|
-
{
|
|
2403
|
-
command: "fitImageToDefaultArea",
|
|
2404
|
-
id: "fitImageToDefaultArea",
|
|
2405
|
-
title: "Fit Image to Default Area",
|
|
2406
|
-
handler: async (id) => {
|
|
2407
|
-
await tool.fitImageToDefaultArea(id);
|
|
2408
|
-
}
|
|
2409
|
-
},
|
|
2410
2402
|
{
|
|
2411
2403
|
command: "focusImage",
|
|
2412
2404
|
id: "focusImage",
|
|
@@ -2420,9 +2412,10 @@ function createImageCommands(tool) {
|
|
|
2420
2412
|
id: "removeImage",
|
|
2421
2413
|
title: "Remove Image",
|
|
2422
2414
|
handler: (id) => {
|
|
2423
|
-
const
|
|
2424
|
-
const
|
|
2425
|
-
|
|
2415
|
+
const sourceItems = tool.isToolActive ? tool.workingItems : tool.items;
|
|
2416
|
+
const removed = sourceItems.find((item) => item.id === id);
|
|
2417
|
+
const next = sourceItems.filter((item) => item.id !== id);
|
|
2418
|
+
if (next.length !== sourceItems.length) {
|
|
2426
2419
|
tool.purgeSourceSizeCacheForItem(removed);
|
|
2427
2420
|
if (tool.focusedImageId === id) {
|
|
2428
2421
|
tool.setImageFocus(null, {
|
|
@@ -2430,6 +2423,13 @@ function createImageCommands(tool) {
|
|
|
2430
2423
|
skipRender: true
|
|
2431
2424
|
});
|
|
2432
2425
|
}
|
|
2426
|
+
if (tool.isToolActive) {
|
|
2427
|
+
tool.workingItems = tool.cloneItems(next);
|
|
2428
|
+
tool.hasWorkingChanges = true;
|
|
2429
|
+
tool.updateImages();
|
|
2430
|
+
tool.emitWorkingChange(id);
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
2433
|
tool.updateConfig(next);
|
|
2434
2434
|
}
|
|
2435
2435
|
}
|
|
@@ -2452,6 +2452,13 @@ function createImageCommands(tool) {
|
|
|
2452
2452
|
syncCanvasSelection: true,
|
|
2453
2453
|
skipRender: true
|
|
2454
2454
|
});
|
|
2455
|
+
if (tool.isToolActive) {
|
|
2456
|
+
tool.workingItems = [];
|
|
2457
|
+
tool.hasWorkingChanges = true;
|
|
2458
|
+
tool.updateImages();
|
|
2459
|
+
tool.emitWorkingChange();
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2455
2462
|
tool.updateConfig([]);
|
|
2456
2463
|
}
|
|
2457
2464
|
},
|
|
@@ -2460,11 +2467,19 @@ function createImageCommands(tool) {
|
|
|
2460
2467
|
id: "bringToFront",
|
|
2461
2468
|
title: "Bring Image to Front",
|
|
2462
2469
|
handler: (id) => {
|
|
2463
|
-
const
|
|
2464
|
-
|
|
2465
|
-
|
|
2470
|
+
const sourceItems = tool.isToolActive ? tool.workingItems : tool.items;
|
|
2471
|
+
const index = sourceItems.findIndex((item) => item.id === id);
|
|
2472
|
+
if (index !== -1 && index < sourceItems.length - 1) {
|
|
2473
|
+
const next = [...sourceItems];
|
|
2466
2474
|
const [item] = next.splice(index, 1);
|
|
2467
2475
|
next.push(item);
|
|
2476
|
+
if (tool.isToolActive) {
|
|
2477
|
+
tool.workingItems = tool.cloneItems(next);
|
|
2478
|
+
tool.hasWorkingChanges = true;
|
|
2479
|
+
tool.updateImages();
|
|
2480
|
+
tool.emitWorkingChange(id);
|
|
2481
|
+
return;
|
|
2482
|
+
}
|
|
2468
2483
|
tool.updateConfig(next);
|
|
2469
2484
|
}
|
|
2470
2485
|
}
|
|
@@ -2474,11 +2489,19 @@ function createImageCommands(tool) {
|
|
|
2474
2489
|
id: "sendToBack",
|
|
2475
2490
|
title: "Send Image to Back",
|
|
2476
2491
|
handler: (id) => {
|
|
2477
|
-
const
|
|
2492
|
+
const sourceItems = tool.isToolActive ? tool.workingItems : tool.items;
|
|
2493
|
+
const index = sourceItems.findIndex((item) => item.id === id);
|
|
2478
2494
|
if (index > 0) {
|
|
2479
|
-
const next = [...
|
|
2495
|
+
const next = [...sourceItems];
|
|
2480
2496
|
const [item] = next.splice(index, 1);
|
|
2481
2497
|
next.unshift(item);
|
|
2498
|
+
if (tool.isToolActive) {
|
|
2499
|
+
tool.workingItems = tool.cloneItems(next);
|
|
2500
|
+
tool.hasWorkingChanges = true;
|
|
2501
|
+
tool.updateImages();
|
|
2502
|
+
tool.emitWorkingChange(id);
|
|
2503
|
+
return;
|
|
2504
|
+
}
|
|
2482
2505
|
tool.updateConfig(next);
|
|
2483
2506
|
}
|
|
2484
2507
|
}
|
|
@@ -2614,6 +2637,78 @@ function createImageConfigurations() {
|
|
|
2614
2637
|
];
|
|
2615
2638
|
}
|
|
2616
2639
|
|
|
2640
|
+
// src/extensions/image/imageOperations.ts
|
|
2641
|
+
function clampNormalizedAnchor(value) {
|
|
2642
|
+
return Math.max(-1, Math.min(2, value));
|
|
2643
|
+
}
|
|
2644
|
+
function toNormalizedAnchor(center, start, size) {
|
|
2645
|
+
return clampNormalizedAnchor((center - start) / Math.max(1, size));
|
|
2646
|
+
}
|
|
2647
|
+
function resolveAbsoluteScale(operation, area, source) {
|
|
2648
|
+
const widthScale = Math.max(1, area.width) / Math.max(1, source.width);
|
|
2649
|
+
const heightScale = Math.max(1, area.height) / Math.max(1, source.height);
|
|
2650
|
+
switch (operation.type) {
|
|
2651
|
+
case "cover":
|
|
2652
|
+
return Math.max(widthScale, heightScale);
|
|
2653
|
+
case "contain":
|
|
2654
|
+
return Math.min(widthScale, heightScale);
|
|
2655
|
+
case "maximizeWidth":
|
|
2656
|
+
return widthScale;
|
|
2657
|
+
case "maximizeHeight":
|
|
2658
|
+
return heightScale;
|
|
2659
|
+
default:
|
|
2660
|
+
return null;
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
function resolveImageOperationArea(args) {
|
|
2664
|
+
const spec = args.area || { type: "frame" };
|
|
2665
|
+
if (spec.type === "custom") {
|
|
2666
|
+
return {
|
|
2667
|
+
width: Math.max(1, spec.width),
|
|
2668
|
+
height: Math.max(1, spec.height),
|
|
2669
|
+
centerX: spec.centerX,
|
|
2670
|
+
centerY: spec.centerY
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
if (spec.type === "viewport") {
|
|
2674
|
+
return {
|
|
2675
|
+
width: Math.max(1, args.viewport.width),
|
|
2676
|
+
height: Math.max(1, args.viewport.height),
|
|
2677
|
+
centerX: args.viewport.left + args.viewport.width / 2,
|
|
2678
|
+
centerY: args.viewport.top + args.viewport.height / 2
|
|
2679
|
+
};
|
|
2680
|
+
}
|
|
2681
|
+
return {
|
|
2682
|
+
width: Math.max(1, args.frame.width),
|
|
2683
|
+
height: Math.max(1, args.frame.height),
|
|
2684
|
+
centerX: args.frame.left + args.frame.width / 2,
|
|
2685
|
+
centerY: args.frame.top + args.frame.height / 2
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
function computeImageOperationUpdates(args) {
|
|
2689
|
+
const { frame, source, operation, area } = args;
|
|
2690
|
+
if (operation.type === "resetTransform") {
|
|
2691
|
+
return {
|
|
2692
|
+
scale: 1,
|
|
2693
|
+
left: 0.5,
|
|
2694
|
+
top: 0.5,
|
|
2695
|
+
angle: 0
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2698
|
+
const left = toNormalizedAnchor(area.centerX, frame.left, frame.width);
|
|
2699
|
+
const top = toNormalizedAnchor(area.centerY, frame.top, frame.height);
|
|
2700
|
+
if (operation.type === "center") {
|
|
2701
|
+
return { left, top };
|
|
2702
|
+
}
|
|
2703
|
+
const absoluteScale = resolveAbsoluteScale(operation, area, source);
|
|
2704
|
+
const coverScale = getCoverScale(frame, source);
|
|
2705
|
+
return {
|
|
2706
|
+
scale: Math.max(0.05, (absoluteScale || coverScale) / coverScale),
|
|
2707
|
+
left,
|
|
2708
|
+
top
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2617
2712
|
// src/extensions/geometry.ts
|
|
2618
2713
|
var import_paper = __toESM(require("paper"));
|
|
2619
2714
|
|
|
@@ -3648,6 +3743,7 @@ var ImageTool = class {
|
|
|
3648
3743
|
this.clearRenderedImages();
|
|
3649
3744
|
(_b = this.renderProducerDisposable) == null ? void 0 : _b.dispose();
|
|
3650
3745
|
this.renderProducerDisposable = void 0;
|
|
3746
|
+
this.emitImageStateChange();
|
|
3651
3747
|
if (this.canvasService) {
|
|
3652
3748
|
void this.canvasService.flushRenderFromProducers();
|
|
3653
3749
|
this.canvasService = void 0;
|
|
@@ -4057,9 +4153,9 @@ var ImageTool = class {
|
|
|
4057
4153
|
name: "Image",
|
|
4058
4154
|
interaction: "session",
|
|
4059
4155
|
commands: {
|
|
4060
|
-
begin: "
|
|
4156
|
+
begin: "imageSessionReset",
|
|
4061
4157
|
commit: "completeImages",
|
|
4062
|
-
rollback: "
|
|
4158
|
+
rollback: "imageSessionReset"
|
|
4063
4159
|
},
|
|
4064
4160
|
session: {
|
|
4065
4161
|
autoBegin: true,
|
|
@@ -4093,6 +4189,28 @@ var ImageTool = class {
|
|
|
4093
4189
|
cloneItems(items) {
|
|
4094
4190
|
return this.normalizeItems((items || []).map((i) => ({ ...i })));
|
|
4095
4191
|
}
|
|
4192
|
+
getViewItems() {
|
|
4193
|
+
return this.isToolActive ? this.workingItems : this.items;
|
|
4194
|
+
}
|
|
4195
|
+
getImageViewState() {
|
|
4196
|
+
this.syncToolActiveFromWorkbench();
|
|
4197
|
+
const items = this.cloneItems(this.getViewItems());
|
|
4198
|
+
const focusedItem = this.focusedImageId == null ? null : items.find((item) => item.id === this.focusedImageId) || null;
|
|
4199
|
+
return {
|
|
4200
|
+
items,
|
|
4201
|
+
hasAnyImage: items.length > 0,
|
|
4202
|
+
focusedId: this.focusedImageId,
|
|
4203
|
+
focusedItem,
|
|
4204
|
+
isToolActive: this.isToolActive,
|
|
4205
|
+
isImageSelectionActive: this.isImageSelectionActive,
|
|
4206
|
+
hasWorkingChanges: this.hasWorkingChanges,
|
|
4207
|
+
source: this.isToolActive ? "working" : "committed"
|
|
4208
|
+
};
|
|
4209
|
+
}
|
|
4210
|
+
emitImageStateChange() {
|
|
4211
|
+
var _a;
|
|
4212
|
+
(_a = this.context) == null ? void 0 : _a.eventBus.emit("image:state:change", this.getImageViewState());
|
|
4213
|
+
}
|
|
4096
4214
|
emitWorkingChange(changedId = null) {
|
|
4097
4215
|
var _a;
|
|
4098
4216
|
(_a = this.context) == null ? void 0 : _a.eventBus.emit("image:working:change", {
|
|
@@ -4128,10 +4246,13 @@ var ImageTool = class {
|
|
|
4128
4246
|
}
|
|
4129
4247
|
if (!options.skipRender) {
|
|
4130
4248
|
this.updateImages();
|
|
4249
|
+
} else {
|
|
4250
|
+
this.emitImageStateChange();
|
|
4131
4251
|
}
|
|
4132
4252
|
return { ok: true, id };
|
|
4133
4253
|
}
|
|
4134
|
-
async addImageEntry(url, options,
|
|
4254
|
+
async addImageEntry(url, options, operation) {
|
|
4255
|
+
this.syncToolActiveFromWorkbench();
|
|
4135
4256
|
const id = this.generateId();
|
|
4136
4257
|
const newItem = this.normalizeItem({
|
|
4137
4258
|
id,
|
|
@@ -4139,13 +4260,20 @@ var ImageTool = class {
|
|
|
4139
4260
|
opacity: 1,
|
|
4140
4261
|
...options
|
|
4141
4262
|
});
|
|
4142
|
-
const sessionDirtyBeforeAdd = this.isToolActive && this.hasWorkingChanges;
|
|
4143
4263
|
const waitLoaded = this.waitImageLoaded(id, true);
|
|
4144
|
-
|
|
4145
|
-
|
|
4264
|
+
if (this.isToolActive) {
|
|
4265
|
+
this.workingItems = this.cloneItems([...this.workingItems, newItem]);
|
|
4266
|
+
this.hasWorkingChanges = true;
|
|
4267
|
+
this.updateImages();
|
|
4268
|
+
this.emitWorkingChange(id);
|
|
4269
|
+
} else {
|
|
4270
|
+
this.updateConfig([...this.items, newItem]);
|
|
4271
|
+
}
|
|
4146
4272
|
const loaded = await waitLoaded;
|
|
4147
|
-
if (loaded &&
|
|
4148
|
-
await this.
|
|
4273
|
+
if (loaded && operation) {
|
|
4274
|
+
await this.applyImageOperation(id, operation, {
|
|
4275
|
+
target: this.isToolActive ? "working" : "config"
|
|
4276
|
+
});
|
|
4149
4277
|
}
|
|
4150
4278
|
if (loaded) {
|
|
4151
4279
|
this.setImageFocus(id);
|
|
@@ -4153,8 +4281,8 @@ var ImageTool = class {
|
|
|
4153
4281
|
return id;
|
|
4154
4282
|
}
|
|
4155
4283
|
async upsertImageEntry(url, options = {}) {
|
|
4284
|
+
this.syncToolActiveFromWorkbench();
|
|
4156
4285
|
const mode = options.mode || (options.id ? "replace" : "add");
|
|
4157
|
-
const fitOnAdd = options.fitOnAdd !== false;
|
|
4158
4286
|
if (mode === "replace") {
|
|
4159
4287
|
if (!options.id) {
|
|
4160
4288
|
throw new Error("replace-target-id-required");
|
|
@@ -4163,19 +4291,31 @@ var ImageTool = class {
|
|
|
4163
4291
|
if (!this.hasImageItem(targetId)) {
|
|
4164
4292
|
throw new Error("replace-target-not-found");
|
|
4165
4293
|
}
|
|
4166
|
-
|
|
4294
|
+
if (this.isToolActive) {
|
|
4295
|
+
const current = this.workingItems.find((item) => item.id === targetId) || this.items.find((item) => item.id === targetId);
|
|
4296
|
+
this.purgeSourceSizeCacheForItem(current);
|
|
4297
|
+
this.updateImageInWorking(targetId, {
|
|
4298
|
+
url,
|
|
4299
|
+
sourceUrl: url,
|
|
4300
|
+
committedUrl: void 0
|
|
4301
|
+
});
|
|
4302
|
+
} else {
|
|
4303
|
+
await this.updateImageInConfig(targetId, { url });
|
|
4304
|
+
}
|
|
4305
|
+
const loaded = await this.waitImageLoaded(targetId, true);
|
|
4306
|
+
if (loaded && options.operation) {
|
|
4307
|
+
await this.applyImageOperation(targetId, options.operation, {
|
|
4308
|
+
target: this.isToolActive ? "working" : "config"
|
|
4309
|
+
});
|
|
4310
|
+
}
|
|
4311
|
+
if (loaded) {
|
|
4312
|
+
this.setImageFocus(targetId);
|
|
4313
|
+
}
|
|
4167
4314
|
return { id: targetId, mode: "replace" };
|
|
4168
4315
|
}
|
|
4169
|
-
const id = await this.addImageEntry(url, options.addOptions,
|
|
4316
|
+
const id = await this.addImageEntry(url, options.addOptions, options.operation);
|
|
4170
4317
|
return { id, mode: "add" };
|
|
4171
4318
|
}
|
|
4172
|
-
addItemToWorkingSessionIfNeeded(item, sessionDirtyBeforeAdd) {
|
|
4173
|
-
if (!sessionDirtyBeforeAdd || !this.isToolActive) return;
|
|
4174
|
-
if (this.workingItems.some((existing) => existing.id === item.id)) return;
|
|
4175
|
-
this.workingItems = this.cloneItems([...this.workingItems, item]);
|
|
4176
|
-
this.updateImages();
|
|
4177
|
-
this.emitWorkingChange(item.id);
|
|
4178
|
-
}
|
|
4179
4319
|
async updateImage(id, updates, options = {}) {
|
|
4180
4320
|
this.syncToolActiveFromWorkbench();
|
|
4181
4321
|
const target = options.target || "auto";
|
|
@@ -4240,34 +4380,6 @@ var ImageTool = class {
|
|
|
4240
4380
|
}
|
|
4241
4381
|
return this.canvasService.toScreenRect(frame || this.getFrameRect());
|
|
4242
4382
|
}
|
|
4243
|
-
async resolveDefaultFitArea() {
|
|
4244
|
-
if (!this.canvasService) return null;
|
|
4245
|
-
const frame = this.getFrameRect();
|
|
4246
|
-
if (frame.width <= 0 || frame.height <= 0) return null;
|
|
4247
|
-
return {
|
|
4248
|
-
width: Math.max(1, frame.width),
|
|
4249
|
-
height: Math.max(1, frame.height),
|
|
4250
|
-
left: frame.left + frame.width / 2,
|
|
4251
|
-
top: frame.top + frame.height / 2
|
|
4252
|
-
};
|
|
4253
|
-
}
|
|
4254
|
-
async fitImageToDefaultArea(id) {
|
|
4255
|
-
if (!this.canvasService) return;
|
|
4256
|
-
const area = await this.resolveDefaultFitArea();
|
|
4257
|
-
if (area) {
|
|
4258
|
-
await this.fitImageToArea(id, area);
|
|
4259
|
-
return;
|
|
4260
|
-
}
|
|
4261
|
-
const viewport = this.canvasService.getSceneViewportRect();
|
|
4262
|
-
const canvasW = Math.max(1, viewport.width || 0);
|
|
4263
|
-
const canvasH = Math.max(1, viewport.height || 0);
|
|
4264
|
-
await this.fitImageToArea(id, {
|
|
4265
|
-
width: canvasW,
|
|
4266
|
-
height: canvasH,
|
|
4267
|
-
left: viewport.left + canvasW / 2,
|
|
4268
|
-
top: viewport.top + canvasH / 2
|
|
4269
|
-
});
|
|
4270
|
-
}
|
|
4271
4383
|
getImageObjects() {
|
|
4272
4384
|
if (!this.canvasService) return [];
|
|
4273
4385
|
return this.canvasService.canvas.getObjects().filter((obj) => {
|
|
@@ -4598,11 +4710,38 @@ var ImageTool = class {
|
|
|
4598
4710
|
isImageSelectionActive: this.isImageSelectionActive,
|
|
4599
4711
|
focusedImageId: this.focusedImageId
|
|
4600
4712
|
});
|
|
4713
|
+
this.emitImageStateChange();
|
|
4601
4714
|
this.canvasService.requestRenderAll();
|
|
4602
4715
|
}
|
|
4603
4716
|
clampNormalized(value) {
|
|
4604
4717
|
return Math.max(-1, Math.min(2, value));
|
|
4605
4718
|
}
|
|
4719
|
+
async setImageTransform(id, updates, options = {}) {
|
|
4720
|
+
const next = {};
|
|
4721
|
+
if (Number.isFinite(updates.scale)) {
|
|
4722
|
+
next.scale = Math.max(0.05, Number(updates.scale));
|
|
4723
|
+
}
|
|
4724
|
+
if (Number.isFinite(updates.angle)) {
|
|
4725
|
+
next.angle = Number(updates.angle);
|
|
4726
|
+
}
|
|
4727
|
+
if (Number.isFinite(updates.left)) {
|
|
4728
|
+
next.left = this.clampNormalized(Number(updates.left));
|
|
4729
|
+
}
|
|
4730
|
+
if (Number.isFinite(updates.top)) {
|
|
4731
|
+
next.top = this.clampNormalized(Number(updates.top));
|
|
4732
|
+
}
|
|
4733
|
+
if (Number.isFinite(updates.opacity)) {
|
|
4734
|
+
next.opacity = Math.max(0, Math.min(1, Number(updates.opacity)));
|
|
4735
|
+
}
|
|
4736
|
+
if (!Object.keys(next).length) return;
|
|
4737
|
+
await this.updateImage(id, next, options);
|
|
4738
|
+
}
|
|
4739
|
+
resetImageSession() {
|
|
4740
|
+
this.workingItems = this.cloneItems(this.items);
|
|
4741
|
+
this.hasWorkingChanges = false;
|
|
4742
|
+
this.updateImages();
|
|
4743
|
+
this.emitWorkingChange();
|
|
4744
|
+
}
|
|
4606
4745
|
updateImageInWorking(id, updates) {
|
|
4607
4746
|
const index = this.workingItems.findIndex((item) => item.id === id);
|
|
4608
4747
|
if (index < 0) return;
|
|
@@ -4620,7 +4759,6 @@ var ImageTool = class {
|
|
|
4620
4759
|
this.emitWorkingChange(id);
|
|
4621
4760
|
}
|
|
4622
4761
|
async updateImageInConfig(id, updates) {
|
|
4623
|
-
var _a, _b, _c, _d;
|
|
4624
4762
|
const index = this.items.findIndex((item) => item.id === id);
|
|
4625
4763
|
if (index < 0) return;
|
|
4626
4764
|
const replacingSource = typeof updates.url === "string" && updates.url.length > 0;
|
|
@@ -4633,23 +4771,12 @@ var ImageTool = class {
|
|
|
4633
4771
|
...replacingSource ? {
|
|
4634
4772
|
url: replacingUrl,
|
|
4635
4773
|
sourceUrl: replacingUrl,
|
|
4636
|
-
committedUrl: void 0
|
|
4637
|
-
scale: (_a = updates.scale) != null ? _a : 1,
|
|
4638
|
-
angle: (_b = updates.angle) != null ? _b : 0,
|
|
4639
|
-
left: (_c = updates.left) != null ? _c : 0.5,
|
|
4640
|
-
top: (_d = updates.top) != null ? _d : 0.5
|
|
4774
|
+
committedUrl: void 0
|
|
4641
4775
|
} : {}
|
|
4642
4776
|
});
|
|
4643
4777
|
this.updateConfig(next);
|
|
4644
4778
|
if (replacingSource) {
|
|
4645
|
-
this.debug("replace:image:begin", { id, replacingUrl });
|
|
4646
4779
|
this.purgeSourceSizeCacheForItem(base);
|
|
4647
|
-
const loaded = await this.waitImageLoaded(id, true);
|
|
4648
|
-
this.debug("replace:image:loaded", { id, loaded });
|
|
4649
|
-
if (loaded) {
|
|
4650
|
-
await this.refitImageToFrame(id);
|
|
4651
|
-
this.setImageFocus(id);
|
|
4652
|
-
}
|
|
4653
4780
|
}
|
|
4654
4781
|
}
|
|
4655
4782
|
waitImageLoaded(id, forceWait = false) {
|
|
@@ -4667,70 +4794,43 @@ var ImageTool = class {
|
|
|
4667
4794
|
});
|
|
4668
4795
|
});
|
|
4669
4796
|
}
|
|
4670
|
-
async
|
|
4797
|
+
async resolveImageSourceSize(id, src) {
|
|
4671
4798
|
const obj = this.getImageObject(id);
|
|
4672
|
-
if (
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
const
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
const
|
|
4679
|
-
const
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
const updated = {
|
|
4683
|
-
scale: Number.isFinite(zoom) ? zoom : 1,
|
|
4684
|
-
angle: 0,
|
|
4685
|
-
left: 0.5,
|
|
4686
|
-
top: 0.5
|
|
4687
|
-
};
|
|
4688
|
-
const index = this.items.findIndex((item) => item.id === id);
|
|
4689
|
-
if (index < 0) return;
|
|
4690
|
-
const next = [...this.items];
|
|
4691
|
-
next[index] = this.normalizeItem({ ...next[index], ...updated });
|
|
4692
|
-
this.updateConfig(next);
|
|
4693
|
-
this.workingItems = this.cloneItems(next);
|
|
4694
|
-
this.hasWorkingChanges = false;
|
|
4695
|
-
this.updateImages();
|
|
4696
|
-
this.emitWorkingChange(id);
|
|
4799
|
+
if (obj) {
|
|
4800
|
+
this.rememberSourceSize(src, obj);
|
|
4801
|
+
}
|
|
4802
|
+
const ensured = await this.ensureSourceSize(src);
|
|
4803
|
+
if (ensured) return ensured;
|
|
4804
|
+
if (!obj) return null;
|
|
4805
|
+
const width = Number((obj == null ? void 0 : obj.width) || 0);
|
|
4806
|
+
const height = Number((obj == null ? void 0 : obj.height) || 0);
|
|
4807
|
+
if (width <= 0 || height <= 0) return null;
|
|
4808
|
+
return { width, height };
|
|
4697
4809
|
}
|
|
4698
|
-
async
|
|
4699
|
-
var _a, _b;
|
|
4810
|
+
async applyImageOperation(id, operation, options = {}) {
|
|
4700
4811
|
if (!this.canvasService) return;
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
const
|
|
4704
|
-
if (!obj) return;
|
|
4705
|
-
const renderItems = this.isToolActive ? this.workingItems : this.items;
|
|
4812
|
+
this.syncToolActiveFromWorkbench();
|
|
4813
|
+
const target = options.target || "auto";
|
|
4814
|
+
const renderItems = target === "working" || target === "auto" && this.isToolActive ? this.workingItems : this.items;
|
|
4706
4815
|
const current = renderItems.find((item) => item.id === id);
|
|
4707
4816
|
if (!current) return;
|
|
4708
4817
|
const render = this.resolveRenderImageState(current);
|
|
4709
|
-
this.
|
|
4710
|
-
|
|
4818
|
+
const source = await this.resolveImageSourceSize(id, render.src);
|
|
4819
|
+
if (!source) return;
|
|
4711
4820
|
const frame = this.getFrameRect();
|
|
4712
|
-
const baseCover = this.getCoverScale(frame, source);
|
|
4713
|
-
const desiredScale = Math.max(
|
|
4714
|
-
Math.max(1, area.width) / Math.max(1, source.width),
|
|
4715
|
-
Math.max(1, area.height) / Math.max(1, source.height)
|
|
4716
|
-
);
|
|
4717
4821
|
const viewport = this.canvasService.getSceneViewportRect();
|
|
4718
|
-
const
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
const
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
(areaTopPx - frame.top) / Math.max(1, frame.height)
|
|
4731
|
-
)
|
|
4732
|
-
};
|
|
4733
|
-
if (this.isToolActive) {
|
|
4822
|
+
const area = operation.type === "resetTransform" ? resolveImageOperationArea({ frame, viewport }) : resolveImageOperationArea({
|
|
4823
|
+
frame,
|
|
4824
|
+
viewport,
|
|
4825
|
+
area: operation.area
|
|
4826
|
+
});
|
|
4827
|
+
const updates = computeImageOperationUpdates({
|
|
4828
|
+
frame,
|
|
4829
|
+
source,
|
|
4830
|
+
operation,
|
|
4831
|
+
area
|
|
4832
|
+
});
|
|
4833
|
+
if (target === "working" || target === "auto" && this.isToolActive) {
|
|
4734
4834
|
this.updateImageInWorking(id, updates);
|
|
4735
4835
|
return;
|
|
4736
4836
|
}
|
|
@@ -4861,6 +4961,11 @@ var ImageTool = class {
|
|
|
4861
4961
|
}
|
|
4862
4962
|
};
|
|
4863
4963
|
|
|
4964
|
+
// src/extensions/image/model.ts
|
|
4965
|
+
function hasAnyImageInViewState(state) {
|
|
4966
|
+
return Boolean(state == null ? void 0 : state.hasAnyImage);
|
|
4967
|
+
}
|
|
4968
|
+
|
|
4864
4969
|
// src/extensions/size/SizeTool.ts
|
|
4865
4970
|
var import_core3 = require("@pooder/core");
|
|
4866
4971
|
var SizeTool = class {
|
|
@@ -10787,6 +10892,7 @@ var CanvasService = class {
|
|
|
10787
10892
|
ViewportSystem,
|
|
10788
10893
|
WhiteInkTool,
|
|
10789
10894
|
computeImageCoverScale,
|
|
10895
|
+
computeImageOperationUpdates,
|
|
10790
10896
|
computeWhiteInkCoverScale,
|
|
10791
10897
|
createDefaultDielineState,
|
|
10792
10898
|
createDielineCommands,
|
|
@@ -10796,5 +10902,7 @@ var CanvasService = class {
|
|
|
10796
10902
|
createWhiteInkCommands,
|
|
10797
10903
|
createWhiteInkConfigurations,
|
|
10798
10904
|
evaluateVisibilityExpr,
|
|
10799
|
-
|
|
10905
|
+
hasAnyImageInViewState,
|
|
10906
|
+
readDielineState,
|
|
10907
|
+
resolveImageOperationArea
|
|
10800
10908
|
});
|