@pooder/kit 5.3.0 → 5.4.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/CHANGELOG.md +12 -0
- package/dist/index.d.mts +249 -36
- package/dist/index.d.ts +249 -36
- package/dist/index.js +2374 -1049
- package/dist/index.mjs +2375 -1050
- package/package.json +1 -1
- package/src/extensions/background.ts +178 -85
- package/src/extensions/dieline.ts +1149 -1030
- package/src/extensions/dielineShape.ts +109 -0
- package/src/extensions/feature.ts +482 -366
- package/src/extensions/film.ts +148 -76
- package/src/extensions/geometry.ts +210 -44
- package/src/extensions/image.ts +244 -114
- package/src/extensions/ruler.ts +471 -268
- package/src/extensions/sceneLayoutModel.ts +28 -6
- package/src/extensions/sceneVisibility.ts +3 -10
- package/src/extensions/tracer.ts +1019 -980
- package/src/extensions/white-ink.ts +284 -231
- package/src/services/CanvasService.ts +543 -11
- package/src/services/renderSpec.ts +37 -2
- package/.test-dist/src/CanvasService.js +0 -249
- package/.test-dist/src/ViewportSystem.js +0 -75
- package/.test-dist/src/background.js +0 -203
- package/.test-dist/src/bridgeSelection.js +0 -20
- package/.test-dist/src/constraints.js +0 -237
- package/.test-dist/src/coordinate.js +0 -74
- package/.test-dist/src/dieline.js +0 -818
- package/.test-dist/src/edgeScale.js +0 -12
- package/.test-dist/src/extensions/background.js +0 -203
- package/.test-dist/src/extensions/bridgeSelection.js +0 -20
- package/.test-dist/src/extensions/constraints.js +0 -237
- package/.test-dist/src/extensions/dieline.js +0 -828
- package/.test-dist/src/extensions/edgeScale.js +0 -12
- package/.test-dist/src/extensions/feature.js +0 -825
- package/.test-dist/src/extensions/featureComplete.js +0 -32
- package/.test-dist/src/extensions/film.js +0 -167
- package/.test-dist/src/extensions/geometry.js +0 -545
- package/.test-dist/src/extensions/image.js +0 -1529
- package/.test-dist/src/extensions/index.js +0 -30
- package/.test-dist/src/extensions/maskOps.js +0 -279
- package/.test-dist/src/extensions/mirror.js +0 -104
- package/.test-dist/src/extensions/ruler.js +0 -345
- package/.test-dist/src/extensions/sceneLayout.js +0 -96
- package/.test-dist/src/extensions/sceneLayoutModel.js +0 -196
- package/.test-dist/src/extensions/sceneVisibility.js +0 -62
- package/.test-dist/src/extensions/size.js +0 -331
- package/.test-dist/src/extensions/tracer.js +0 -538
- package/.test-dist/src/extensions/white-ink.js +0 -1190
- package/.test-dist/src/extensions/wrappedOffsets.js +0 -33
- package/.test-dist/src/feature.js +0 -826
- package/.test-dist/src/featureComplete.js +0 -32
- package/.test-dist/src/film.js +0 -167
- package/.test-dist/src/geometry.js +0 -506
- package/.test-dist/src/image.js +0 -1250
- package/.test-dist/src/index.js +0 -18
- package/.test-dist/src/maskOps.js +0 -270
- package/.test-dist/src/mirror.js +0 -104
- package/.test-dist/src/renderSpec.js +0 -2
- package/.test-dist/src/ruler.js +0 -343
- package/.test-dist/src/sceneLayout.js +0 -99
- package/.test-dist/src/sceneLayoutModel.js +0 -196
- package/.test-dist/src/sceneView.js +0 -40
- package/.test-dist/src/sceneVisibility.js +0 -42
- package/.test-dist/src/services/CanvasService.js +0 -249
- package/.test-dist/src/services/ViewportSystem.js +0 -76
- package/.test-dist/src/services/index.js +0 -24
- package/.test-dist/src/services/renderSpec.js +0 -2
- package/.test-dist/src/size.js +0 -332
- package/.test-dist/src/tracer.js +0 -544
- package/.test-dist/src/units.js +0 -30
- package/.test-dist/src/white-ink.js +0 -829
- package/.test-dist/src/wrappedOffsets.js +0 -33
- package/.test-dist/tests/run.js +0 -94
package/package.json
CHANGED
|
@@ -4,9 +4,21 @@ import {
|
|
|
4
4
|
ContributionPointIds,
|
|
5
5
|
CommandContribution,
|
|
6
6
|
ConfigurationContribution,
|
|
7
|
+
ConfigurationService,
|
|
7
8
|
} from "@pooder/core";
|
|
8
|
-
import {
|
|
9
|
-
import { CanvasService } from "../services";
|
|
9
|
+
import { FabricImage } from "fabric";
|
|
10
|
+
import { CanvasService, RenderObjectSpec } from "../services";
|
|
11
|
+
|
|
12
|
+
interface SourceSize {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const BACKGROUND_LAYER_ID = "background";
|
|
18
|
+
const BACKGROUND_RECT_ID = "background-color-rect";
|
|
19
|
+
const BACKGROUND_IMAGE_ID = "background-image";
|
|
20
|
+
const DEFAULT_WIDTH = 800;
|
|
21
|
+
const DEFAULT_HEIGHT = 600;
|
|
10
22
|
|
|
11
23
|
export class BackgroundTool implements Extension {
|
|
12
24
|
id = "pooder.kit.background";
|
|
@@ -18,6 +30,15 @@ export class BackgroundTool implements Extension {
|
|
|
18
30
|
private url: string = "";
|
|
19
31
|
|
|
20
32
|
private canvasService?: CanvasService;
|
|
33
|
+
private specs: RenderObjectSpec[] = [];
|
|
34
|
+
private renderProducerDisposable?: { dispose: () => void };
|
|
35
|
+
private renderSeq = 0;
|
|
36
|
+
private renderImageUrl = "";
|
|
37
|
+
private sourceSizeBySrc: Map<string, SourceSize> = new Map();
|
|
38
|
+
private pendingSizeBySrc: Map<string, Promise<SourceSize | null>> = new Map();
|
|
39
|
+
private onCanvasResized = () => {
|
|
40
|
+
this.updateBackground();
|
|
41
|
+
};
|
|
21
42
|
|
|
22
43
|
constructor(
|
|
23
44
|
options?: Partial<{
|
|
@@ -37,7 +58,20 @@ export class BackgroundTool implements Extension {
|
|
|
37
58
|
return;
|
|
38
59
|
}
|
|
39
60
|
|
|
40
|
-
|
|
61
|
+
this.renderProducerDisposable?.dispose();
|
|
62
|
+
this.renderProducerDisposable = this.canvasService.registerRenderProducer(
|
|
63
|
+
this.id,
|
|
64
|
+
() => ({
|
|
65
|
+
layerSpecs: {
|
|
66
|
+
[BACKGROUND_LAYER_ID]: this.specs,
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
{ priority: 0 },
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const configService = context.services.get<ConfigurationService>(
|
|
73
|
+
"ConfigurationService",
|
|
74
|
+
);
|
|
41
75
|
if (configService) {
|
|
42
76
|
// Load initial config
|
|
43
77
|
this.color = configService.get("background.color", this.color);
|
|
@@ -65,18 +99,25 @@ export class BackgroundTool implements Extension {
|
|
|
65
99
|
});
|
|
66
100
|
}
|
|
67
101
|
|
|
68
|
-
this.
|
|
102
|
+
context.eventBus.on("canvas:resized", this.onCanvasResized);
|
|
69
103
|
this.updateBackground();
|
|
70
104
|
}
|
|
71
105
|
|
|
72
106
|
deactivate(context: ExtensionContext) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
107
|
+
context.eventBus.off("canvas:resized", this.onCanvasResized);
|
|
108
|
+
this.renderSeq += 1;
|
|
109
|
+
this.specs = [];
|
|
110
|
+
this.renderImageUrl = "";
|
|
111
|
+
this.renderProducerDisposable?.dispose();
|
|
112
|
+
this.renderProducerDisposable = undefined;
|
|
113
|
+
if (!this.canvasService) return;
|
|
114
|
+
const layer = this.canvasService.getLayer(BACKGROUND_LAYER_ID);
|
|
115
|
+
if (layer) {
|
|
116
|
+
this.canvasService.canvas.remove(layer);
|
|
79
117
|
}
|
|
118
|
+
void this.canvasService.flushRenderFromProducers();
|
|
119
|
+
this.canvasService.requestRenderAll();
|
|
120
|
+
this.canvasService = undefined;
|
|
80
121
|
}
|
|
81
122
|
|
|
82
123
|
contribute() {
|
|
@@ -138,93 +179,145 @@ export class BackgroundTool implements Extension {
|
|
|
138
179
|
};
|
|
139
180
|
}
|
|
140
181
|
|
|
141
|
-
private
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
182
|
+
private getViewportSize(): { width: number; height: number } {
|
|
183
|
+
const width = Number(this.canvasService?.canvas.width || 0);
|
|
184
|
+
const height = Number(this.canvasService?.canvas.height || 0);
|
|
185
|
+
return {
|
|
186
|
+
width: width > 0 ? width : DEFAULT_WIDTH,
|
|
187
|
+
height: height > 0 ? height : DEFAULT_HEIGHT,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private buildBackgroundSpecs(
|
|
192
|
+
color: string,
|
|
193
|
+
imageUrl: string,
|
|
194
|
+
): RenderObjectSpec[] {
|
|
195
|
+
const { width, height } = this.getViewportSize();
|
|
196
|
+
const specs: RenderObjectSpec[] = [
|
|
197
|
+
{
|
|
198
|
+
id: BACKGROUND_RECT_ID,
|
|
199
|
+
type: "rect",
|
|
200
|
+
space: "screen",
|
|
201
|
+
data: {
|
|
202
|
+
id: BACKGROUND_RECT_ID,
|
|
203
|
+
layerId: BACKGROUND_LAYER_ID,
|
|
204
|
+
type: "background-color",
|
|
205
|
+
},
|
|
206
|
+
props: {
|
|
207
|
+
left: 0,
|
|
208
|
+
top: 0,
|
|
209
|
+
width,
|
|
210
|
+
height,
|
|
211
|
+
originX: "left",
|
|
212
|
+
originY: "top",
|
|
213
|
+
fill: color,
|
|
214
|
+
selectable: false,
|
|
215
|
+
evented: false,
|
|
216
|
+
excludeFromExport: true,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
];
|
|
220
|
+
|
|
221
|
+
if (!imageUrl) {
|
|
222
|
+
return specs;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const sourceSize = this.sourceSizeBySrc.get(imageUrl);
|
|
226
|
+
const sourceWidth = Math.max(1, Number(sourceSize?.width || width));
|
|
227
|
+
const sourceHeight = Math.max(1, Number(sourceSize?.height || height));
|
|
228
|
+
const coverScale = Math.max(width / sourceWidth, height / sourceHeight);
|
|
229
|
+
specs.push({
|
|
230
|
+
id: BACKGROUND_IMAGE_ID,
|
|
231
|
+
type: "image",
|
|
232
|
+
src: imageUrl,
|
|
233
|
+
space: "screen",
|
|
234
|
+
data: {
|
|
235
|
+
id: BACKGROUND_IMAGE_ID,
|
|
236
|
+
layerId: BACKGROUND_LAYER_ID,
|
|
237
|
+
type: "background-image",
|
|
238
|
+
},
|
|
239
|
+
props: {
|
|
240
|
+
left: 0,
|
|
241
|
+
top: 0,
|
|
242
|
+
originX: "left",
|
|
243
|
+
originY: "top",
|
|
244
|
+
scaleX: coverScale,
|
|
245
|
+
scaleY: coverScale,
|
|
148
246
|
selectable: false,
|
|
149
247
|
evented: false,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
248
|
+
excludeFromExport: true,
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return specs;
|
|
153
253
|
}
|
|
154
254
|
|
|
155
|
-
private async
|
|
156
|
-
if (!
|
|
157
|
-
const
|
|
158
|
-
if (
|
|
159
|
-
console.warn("[BackgroundTool] Background layer not found");
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
255
|
+
private async ensureImageSize(src: string): Promise<SourceSize | null> {
|
|
256
|
+
if (!src) return null;
|
|
257
|
+
const cached = this.sourceSizeBySrc.get(src);
|
|
258
|
+
if (cached) return cached;
|
|
162
259
|
|
|
163
|
-
const
|
|
260
|
+
const pending = this.pendingSizeBySrc.get(src);
|
|
261
|
+
if (pending) {
|
|
262
|
+
return pending;
|
|
263
|
+
}
|
|
164
264
|
|
|
165
|
-
const
|
|
166
|
-
|
|
265
|
+
const task = this.loadImageSize(src);
|
|
266
|
+
this.pendingSizeBySrc.set(src, task);
|
|
267
|
+
try {
|
|
268
|
+
return await task;
|
|
269
|
+
} finally {
|
|
270
|
+
if (this.pendingSizeBySrc.get(src) === task) {
|
|
271
|
+
this.pendingSizeBySrc.delete(src);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
167
275
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (rect) {
|
|
173
|
-
rect.set({
|
|
174
|
-
fill: color,
|
|
175
|
-
});
|
|
176
|
-
} else {
|
|
177
|
-
rect = new Rect({
|
|
178
|
-
width,
|
|
179
|
-
height,
|
|
180
|
-
fill: color,
|
|
181
|
-
selectable: false,
|
|
182
|
-
evented: false,
|
|
183
|
-
data: {
|
|
184
|
-
id: "background-color-rect",
|
|
185
|
-
},
|
|
276
|
+
private async loadImageSize(src: string): Promise<SourceSize | null> {
|
|
277
|
+
try {
|
|
278
|
+
const image = await FabricImage.fromURL(src, {
|
|
279
|
+
crossOrigin: "anonymous",
|
|
186
280
|
});
|
|
187
|
-
|
|
188
|
-
|
|
281
|
+
const width = Number(image?.width || 0);
|
|
282
|
+
const height = Number(image?.height || 0);
|
|
283
|
+
if (width > 0 && height > 0) {
|
|
284
|
+
const size = { width, height };
|
|
285
|
+
this.sourceSizeBySrc.set(src, size);
|
|
286
|
+
return size;
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
console.error("[BackgroundTool] Failed to load image", src, error);
|
|
189
290
|
}
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
190
293
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
originX: "left",
|
|
209
|
-
originY: "top",
|
|
210
|
-
left: 0,
|
|
211
|
-
top: 0,
|
|
212
|
-
selectable: false,
|
|
213
|
-
evented: false,
|
|
214
|
-
data: {
|
|
215
|
-
id: "background-image",
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
|
-
img.scaleToWidth(width);
|
|
219
|
-
if (img.getScaledHeight() < height) img.scaleToHeight(height);
|
|
220
|
-
layer.add(img);
|
|
221
|
-
}
|
|
294
|
+
private updateBackground() {
|
|
295
|
+
void this.updateBackgroundAsync();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private async updateBackgroundAsync() {
|
|
299
|
+
if (!this.canvasService) return;
|
|
300
|
+
const seq = ++this.renderSeq;
|
|
301
|
+
const color = this.color;
|
|
302
|
+
const nextUrl = String(this.url || "").trim();
|
|
303
|
+
|
|
304
|
+
if (!nextUrl) {
|
|
305
|
+
this.renderImageUrl = "";
|
|
306
|
+
} else if (nextUrl !== this.renderImageUrl) {
|
|
307
|
+
const loaded = await this.ensureImageSize(nextUrl);
|
|
308
|
+
if (seq !== this.renderSeq) return;
|
|
309
|
+
if (loaded) {
|
|
310
|
+
this.renderImageUrl = nextUrl;
|
|
222
311
|
}
|
|
223
|
-
this.canvasService.requestRenderAll();
|
|
224
|
-
} catch (e) {
|
|
225
|
-
console.error("[BackgroundTool] Failed to load image", e);
|
|
226
312
|
}
|
|
227
|
-
|
|
313
|
+
|
|
314
|
+
this.specs = this.buildBackgroundSpecs(color, this.renderImageUrl);
|
|
315
|
+
await this.canvasService.flushRenderFromProducers();
|
|
316
|
+
if (seq !== this.renderSeq) return;
|
|
317
|
+
const layer = this.canvasService.getLayer(BACKGROUND_LAYER_ID);
|
|
318
|
+
if (layer) {
|
|
319
|
+
this.canvasService.canvas.sendObjectToBack(layer);
|
|
320
|
+
}
|
|
228
321
|
this.canvasService.requestRenderAll();
|
|
229
322
|
}
|
|
230
323
|
}
|