@pooder/kit 5.0.3 → 5.1.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 +17 -0
- package/dist/index.d.mts +239 -269
- package/dist/index.d.ts +239 -269
- package/dist/index.js +6485 -5833
- package/dist/index.mjs +6587 -5923
- package/package.json +2 -2
- package/src/{background.ts → extensions/background.ts} +1 -1
- package/src/{dieline.ts → extensions/dieline.ts} +39 -17
- package/src/{feature.ts → extensions/feature.ts} +80 -67
- package/src/{film.ts → extensions/film.ts} +1 -1
- package/src/{geometry.ts → extensions/geometry.ts} +151 -105
- package/src/{image.ts → extensions/image.ts} +190 -192
- package/src/extensions/index.ts +11 -0
- package/src/{maskOps.ts → extensions/maskOps.ts} +28 -10
- package/src/{mirror.ts → extensions/mirror.ts} +1 -1
- package/src/{ruler.ts → extensions/ruler.ts} +5 -3
- package/src/extensions/sceneLayout.ts +140 -0
- package/src/{sceneLayoutModel.ts → extensions/sceneLayoutModel.ts} +17 -10
- package/src/extensions/sceneVisibility.ts +71 -0
- package/src/{size.ts → extensions/size.ts} +23 -13
- package/src/{tracer.ts → extensions/tracer.ts} +374 -45
- package/src/{white-ink.ts → extensions/white-ink.ts} +620 -236
- package/src/index.ts +2 -14
- package/src/{ViewportSystem.ts → services/ViewportSystem.ts} +5 -2
- package/src/services/index.ts +3 -0
- package/src/sceneLayout.ts +0 -121
- package/src/sceneVisibility.ts +0 -49
- /package/src/{bridgeSelection.ts → extensions/bridgeSelection.ts} +0 -0
- /package/src/{constraints.ts → extensions/constraints.ts} +0 -0
- /package/src/{edgeScale.ts → extensions/edgeScale.ts} +0 -0
- /package/src/{featureComplete.ts → extensions/featureComplete.ts} +0 -0
- /package/src/{wrappedOffsets.ts → extensions/wrappedOffsets.ts} +0 -0
- /package/src/{CanvasService.ts → services/CanvasService.ts} +0 -0
- /package/src/{renderSpec.ts → services/renderSpec.ts} +0 -0
|
@@ -212,8 +212,14 @@ function createBaseShape(options: GeometryOptions): paper.PathItem {
|
|
|
212
212
|
radius: [Math.max(0, width / 2), Math.max(0, height / 2)],
|
|
213
213
|
});
|
|
214
214
|
} else if (shape === "custom" && pathData) {
|
|
215
|
-
const
|
|
216
|
-
path.
|
|
215
|
+
const hasMultipleSubPaths = ((pathData.match(/[Mm]/g) || []).length ?? 0) > 1;
|
|
216
|
+
const path: paper.PathItem = hasMultipleSubPaths
|
|
217
|
+
? new paper.CompoundPath(pathData)
|
|
218
|
+
: (() => {
|
|
219
|
+
const single = new paper.Path();
|
|
220
|
+
single.pathData = pathData;
|
|
221
|
+
return single;
|
|
222
|
+
})();
|
|
217
223
|
// Align center
|
|
218
224
|
path.position = center;
|
|
219
225
|
if (
|
|
@@ -233,6 +239,37 @@ function createBaseShape(options: GeometryOptions): paper.PathItem {
|
|
|
233
239
|
}
|
|
234
240
|
}
|
|
235
241
|
|
|
242
|
+
function resolveBridgeBasePath(
|
|
243
|
+
shape: paper.PathItem,
|
|
244
|
+
anchor: paper.Point,
|
|
245
|
+
): paper.Path | null {
|
|
246
|
+
if (shape instanceof paper.Path) {
|
|
247
|
+
return shape;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (shape instanceof paper.CompoundPath) {
|
|
251
|
+
const children = (shape.children || []).filter(
|
|
252
|
+
(child): child is paper.Path => child instanceof paper.Path,
|
|
253
|
+
);
|
|
254
|
+
if (!children.length) return null;
|
|
255
|
+
let best = children[0];
|
|
256
|
+
let bestDistance = Infinity;
|
|
257
|
+
for (const child of children) {
|
|
258
|
+
const location = child.getNearestLocation(anchor);
|
|
259
|
+
const point = location?.point;
|
|
260
|
+
if (!point) continue;
|
|
261
|
+
const distance = point.getDistance(anchor);
|
|
262
|
+
if (distance < bestDistance) {
|
|
263
|
+
bestDistance = distance;
|
|
264
|
+
best = child;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return best;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
|
|
236
273
|
/**
|
|
237
274
|
* Creates a Paper.js Item for a single feature.
|
|
238
275
|
*/
|
|
@@ -307,113 +344,122 @@ function getPerimeterShape(options: GeometryOptions): paper.PathItem {
|
|
|
307
344
|
const inset = Math.min(1, Math.max(0, itemBounds.width * 0.01));
|
|
308
345
|
const xLeft = itemBounds.left + inset;
|
|
309
346
|
const xRight = itemBounds.right - inset;
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
347
|
+
const bridgeBasePath = resolveBridgeBasePath(mainShape, center);
|
|
348
|
+
const canBridge = !!bridgeBasePath && xRight - xLeft > eps;
|
|
349
|
+
|
|
350
|
+
if (canBridge && bridgeBasePath) {
|
|
351
|
+
const leftHit = getExitHit({
|
|
352
|
+
mainShape: bridgeBasePath,
|
|
353
|
+
x: xLeft,
|
|
354
|
+
bridgeBottom,
|
|
355
|
+
toY,
|
|
356
|
+
eps,
|
|
357
|
+
delta,
|
|
358
|
+
overlap,
|
|
359
|
+
op: f.operation,
|
|
360
|
+
});
|
|
361
|
+
const rightHit = getExitHit({
|
|
362
|
+
mainShape: bridgeBasePath,
|
|
363
|
+
x: xRight,
|
|
364
|
+
bridgeBottom,
|
|
365
|
+
toY,
|
|
366
|
+
eps,
|
|
367
|
+
delta,
|
|
368
|
+
overlap,
|
|
369
|
+
op: f.operation,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
if (leftHit && rightHit) {
|
|
373
|
+
const pathLength = bridgeBasePath.length;
|
|
374
|
+
const leftOffset = leftHit.location.offset;
|
|
375
|
+
const rightOffset = rightHit.location.offset;
|
|
376
|
+
|
|
377
|
+
const distanceA = wrappedDistance(pathLength, leftOffset, rightOffset);
|
|
378
|
+
const distanceB = wrappedDistance(pathLength, rightOffset, leftOffset);
|
|
379
|
+
const countFor = (d: number) =>
|
|
380
|
+
Math.max(8, Math.min(80, Math.ceil(d / 6)));
|
|
381
|
+
|
|
382
|
+
const offsetsA = sampleWrappedOffsets(
|
|
383
|
+
pathLength,
|
|
384
|
+
leftOffset,
|
|
385
|
+
rightOffset,
|
|
386
|
+
countFor(distanceA),
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
const offsetsB = sampleWrappedOffsets(
|
|
390
|
+
pathLength,
|
|
391
|
+
rightOffset,
|
|
392
|
+
leftOffset,
|
|
393
|
+
countFor(distanceB),
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
const pointsA = offsetsA
|
|
397
|
+
.map((o) => bridgeBasePath.getPointAt(o))
|
|
398
|
+
.filter((p): p is paper.Point => Boolean(p));
|
|
399
|
+
const pointsB = offsetsB
|
|
400
|
+
.map((o) => bridgeBasePath.getPointAt(o))
|
|
401
|
+
.filter((p): p is paper.Point => Boolean(p));
|
|
402
|
+
|
|
403
|
+
if (pointsA.length >= 2 && pointsB.length >= 2) {
|
|
404
|
+
let topBase = selectOuterChain({
|
|
405
|
+
mainShape: bridgeBasePath,
|
|
406
|
+
pointsA,
|
|
407
|
+
pointsB,
|
|
408
|
+
delta,
|
|
409
|
+
overlap,
|
|
410
|
+
op: f.operation,
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const dist2 = (a: paper.Point, b: paper.Point) => {
|
|
414
|
+
const dx = a.x - b.x;
|
|
415
|
+
const dy = a.y - b.y;
|
|
416
|
+
return dx * dx + dy * dy;
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
if (
|
|
420
|
+
dist2(topBase[0], leftHit.point) >
|
|
421
|
+
dist2(topBase[0], rightHit.point)
|
|
422
|
+
) {
|
|
423
|
+
topBase = topBase.slice().reverse();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
topBase = topBase.slice();
|
|
427
|
+
topBase[0] = leftHit.point;
|
|
428
|
+
topBase[topBase.length - 1] = rightHit.point;
|
|
429
|
+
|
|
430
|
+
const capShiftY =
|
|
431
|
+
f.operation === "subtract"
|
|
432
|
+
? -Math.max(overlap * 2, delta)
|
|
433
|
+
: overlap;
|
|
434
|
+
const topPoints = topBase.map((p) =>
|
|
435
|
+
p.add(new paper.Point(0, capShiftY)),
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
const bridgeBottomY = bridgeBottom + overlap * 2;
|
|
439
|
+
const bridgePoly = new paper.Path({ insert: false });
|
|
440
|
+
for (const p of topPoints) bridgePoly.add(p);
|
|
441
|
+
bridgePoly.add(new paper.Point(xRight, bridgeBottomY));
|
|
442
|
+
bridgePoly.add(new paper.Point(xLeft, bridgeBottomY));
|
|
443
|
+
bridgePoly.closed = true;
|
|
444
|
+
|
|
445
|
+
const unitedItem = item.unite(bridgePoly);
|
|
446
|
+
item.remove();
|
|
447
|
+
bridgePoly.remove();
|
|
448
|
+
|
|
449
|
+
if (f.operation === "add") {
|
|
450
|
+
adds.push(unitedItem);
|
|
451
|
+
} else {
|
|
452
|
+
subtracts.push(unitedItem);
|
|
453
|
+
}
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
372
457
|
}
|
|
373
458
|
|
|
374
|
-
let topBase = selectOuterChain({
|
|
375
|
-
mainShape,
|
|
376
|
-
pointsA,
|
|
377
|
-
pointsB,
|
|
378
|
-
delta,
|
|
379
|
-
overlap,
|
|
380
|
-
op: f.operation,
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
const dist2 = (a: paper.Point, b: paper.Point) => {
|
|
384
|
-
const dx = a.x - b.x;
|
|
385
|
-
const dy = a.y - b.y;
|
|
386
|
-
return dx * dx + dy * dy;
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
if (dist2(topBase[0], leftHit.point) > dist2(topBase[0], rightHit.point)) {
|
|
390
|
-
topBase = topBase.slice().reverse();
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
topBase = topBase.slice();
|
|
394
|
-
topBase[0] = leftHit.point;
|
|
395
|
-
topBase[topBase.length - 1] = rightHit.point;
|
|
396
|
-
|
|
397
|
-
const capShiftY = f.operation === "subtract" ? -Math.max(overlap * 2, delta) : overlap;
|
|
398
|
-
const topPoints = topBase.map(
|
|
399
|
-
(p) => p.add(new paper.Point(0, capShiftY)),
|
|
400
|
-
);
|
|
401
|
-
|
|
402
|
-
const bridgeBottomY = bridgeBottom + overlap * 2;
|
|
403
|
-
const bridgePoly = new paper.Path({ insert: false });
|
|
404
|
-
for (const p of topPoints) bridgePoly.add(p);
|
|
405
|
-
bridgePoly.add(new paper.Point(xRight, bridgeBottomY));
|
|
406
|
-
bridgePoly.add(new paper.Point(xLeft, bridgeBottomY));
|
|
407
|
-
bridgePoly.closed = true;
|
|
408
|
-
|
|
409
|
-
const unitedItem = item.unite(bridgePoly);
|
|
410
|
-
item.remove();
|
|
411
|
-
bridgePoly.remove();
|
|
412
|
-
|
|
413
459
|
if (f.operation === "add") {
|
|
414
|
-
adds.push(
|
|
460
|
+
adds.push(item);
|
|
415
461
|
} else {
|
|
416
|
-
subtracts.push(
|
|
462
|
+
subtracts.push(item);
|
|
417
463
|
}
|
|
418
464
|
} else {
|
|
419
465
|
if (f.operation === "add") {
|