@pooder/kit 5.2.0 → 5.3.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.
Files changed (39) hide show
  1. package/.test-dist/src/extensions/background.js +203 -0
  2. package/.test-dist/src/extensions/bridgeSelection.js +20 -0
  3. package/.test-dist/src/extensions/constraints.js +237 -0
  4. package/.test-dist/src/extensions/dieline.js +828 -0
  5. package/.test-dist/src/extensions/edgeScale.js +12 -0
  6. package/.test-dist/src/extensions/feature.js +825 -0
  7. package/.test-dist/src/extensions/featureComplete.js +32 -0
  8. package/.test-dist/src/extensions/film.js +167 -0
  9. package/.test-dist/src/extensions/geometry.js +545 -0
  10. package/.test-dist/src/extensions/image.js +1529 -0
  11. package/.test-dist/src/extensions/index.js +30 -0
  12. package/.test-dist/src/extensions/maskOps.js +279 -0
  13. package/.test-dist/src/extensions/mirror.js +104 -0
  14. package/.test-dist/src/extensions/ruler.js +345 -0
  15. package/.test-dist/src/extensions/sceneLayout.js +96 -0
  16. package/.test-dist/src/extensions/sceneLayoutModel.js +196 -0
  17. package/.test-dist/src/extensions/sceneVisibility.js +62 -0
  18. package/.test-dist/src/extensions/size.js +331 -0
  19. package/.test-dist/src/extensions/tracer.js +538 -0
  20. package/.test-dist/src/extensions/white-ink.js +1190 -0
  21. package/.test-dist/src/extensions/wrappedOffsets.js +33 -0
  22. package/.test-dist/src/index.js +2 -19
  23. package/.test-dist/src/services/CanvasService.js +249 -0
  24. package/.test-dist/src/services/ViewportSystem.js +76 -0
  25. package/.test-dist/src/services/index.js +24 -0
  26. package/.test-dist/src/services/renderSpec.js +2 -0
  27. package/CHANGELOG.md +12 -0
  28. package/dist/index.d.mts +11 -0
  29. package/dist/index.d.ts +11 -0
  30. package/dist/index.js +519 -395
  31. package/dist/index.mjs +519 -395
  32. package/package.json +1 -1
  33. package/src/extensions/dieline.ts +66 -17
  34. package/src/extensions/geometry.ts +36 -3
  35. package/src/extensions/image.ts +2 -0
  36. package/src/extensions/maskOps.ts +84 -18
  37. package/src/extensions/sceneLayoutModel.ts +10 -0
  38. package/src/extensions/tracer.ts +360 -389
  39. package/src/extensions/white-ink.ts +125 -2
@@ -56,6 +56,16 @@ interface ImageSnapshot {
56
56
  height: number;
57
57
  }
58
58
 
59
+ interface ImagePlacementState {
60
+ id: string;
61
+ sourceUrl: string;
62
+ committedUrl: string;
63
+ left: number;
64
+ top: number;
65
+ scale: number;
66
+ angle: number;
67
+ }
68
+
59
69
  interface RenderSources {
60
70
  whiteSrc: string;
61
71
  coverSrc: string;
@@ -797,6 +807,116 @@ export class WhiteInkTool implements Extension {
797
807
  };
798
808
  }
799
809
 
810
+ private getImagePlacementState(id?: string): ImagePlacementState | null {
811
+ const rawItems = this.getConfig<any[]>("image.items", []);
812
+ if (!Array.isArray(rawItems) || rawItems.length === 0) return null;
813
+
814
+ const matched =
815
+ (id
816
+ ? rawItems.find(
817
+ (item: any) =>
818
+ item &&
819
+ typeof item === "object" &&
820
+ typeof item.id === "string" &&
821
+ item.id === id,
822
+ )
823
+ : undefined) || rawItems[0];
824
+
825
+ if (!matched || typeof matched !== "object") return null;
826
+
827
+ const sourceUrl =
828
+ typeof matched.sourceUrl === "string" && matched.sourceUrl.length > 0
829
+ ? matched.sourceUrl
830
+ : typeof matched.url === "string"
831
+ ? matched.url
832
+ : "";
833
+ const committedUrl =
834
+ typeof matched.committedUrl === "string" ? matched.committedUrl : "";
835
+
836
+ return {
837
+ id:
838
+ typeof matched.id === "string" && matched.id.length > 0
839
+ ? matched.id
840
+ : id || "image",
841
+ sourceUrl,
842
+ committedUrl,
843
+ left: Number.isFinite(matched.left) ? Number(matched.left) : 0.5,
844
+ top: Number.isFinite(matched.top) ? Number(matched.top) : 0.5,
845
+ scale: Number.isFinite(matched.scale) ? Math.max(0.05, matched.scale) : 1,
846
+ angle: Number.isFinite(matched.angle) ? matched.angle : 0,
847
+ };
848
+ }
849
+
850
+ private shouldRestoreSnapshotToSource(
851
+ snapshot: ImageSnapshot,
852
+ placement: ImagePlacementState,
853
+ ): boolean {
854
+ if (!placement.sourceUrl || !placement.committedUrl) return false;
855
+ if (placement.sourceUrl === placement.committedUrl) return false;
856
+ return snapshot.src === placement.committedUrl;
857
+ }
858
+
859
+ private getCoverScale(frame: FrameRect, source: SourceSize): number {
860
+ const frameW = Math.max(1, frame.width);
861
+ const frameH = Math.max(1, frame.height);
862
+ const sourceW = Math.max(1, source.width);
863
+ const sourceH = Math.max(1, source.height);
864
+ return Math.max(frameW / sourceW, frameH / sourceH);
865
+ }
866
+
867
+ private async ensureSourceSize(sourceUrl: string): Promise<SourceSize | null> {
868
+ if (!sourceUrl) return null;
869
+ const cached = this.getSourceSize(sourceUrl);
870
+ if (cached) return cached;
871
+
872
+ try {
873
+ const image = await this.loadImageElement(sourceUrl);
874
+ const size = this.getElementSize(image);
875
+ if (!size) return null;
876
+ this.rememberSourceSize(sourceUrl, size);
877
+ return {
878
+ width: size.width,
879
+ height: size.height,
880
+ };
881
+ } catch {
882
+ return null;
883
+ }
884
+ }
885
+
886
+ private async resolveAlignedImageSnapshot(
887
+ snapshot: ImageSnapshot,
888
+ ): Promise<ImageSnapshot> {
889
+ const placement = this.getImagePlacementState(snapshot.id);
890
+ if (!placement) return snapshot;
891
+ if (!this.shouldRestoreSnapshotToSource(snapshot, placement)) {
892
+ return snapshot;
893
+ }
894
+
895
+ const frame = this.getFrameRect();
896
+ if (frame.width <= 0 || frame.height <= 0) {
897
+ return snapshot;
898
+ }
899
+
900
+ const sourceSize = await this.ensureSourceSize(placement.sourceUrl);
901
+ if (!sourceSize) return snapshot;
902
+
903
+ const coverScale = this.getCoverScale(frame, sourceSize);
904
+
905
+ return {
906
+ ...snapshot,
907
+ src: placement.sourceUrl,
908
+ element: undefined,
909
+ left: frame.left + placement.left * frame.width,
910
+ top: frame.top + placement.top * frame.height,
911
+ scaleX: coverScale * placement.scale,
912
+ scaleY: coverScale * placement.scale,
913
+ angle: placement.angle,
914
+ originX: "center",
915
+ originY: "center",
916
+ width: sourceSize.width,
917
+ height: sourceSize.height,
918
+ };
919
+ }
800
920
  private getImageElementFromObject(obj: any): any {
801
921
  if (!obj) return null;
802
922
  if (typeof obj.getElement === "function") {
@@ -1238,10 +1358,12 @@ export class WhiteInkTool implements Extension {
1238
1358
  let coverSpecs: RenderObjectSpec[] = [];
1239
1359
 
1240
1360
  if (previewActive) {
1241
- const snapshot = this.getImageSnapshot(this.getPrimaryImageObject());
1361
+ const baseSnapshot = this.getImageSnapshot(this.getPrimaryImageObject());
1242
1362
  const item = this.getEffectiveWhiteInkItem(this.resolveRenderItems());
1243
1363
 
1244
- if (snapshot && item) {
1364
+ if (baseSnapshot && item) {
1365
+ const snapshot = await this.resolveAlignedImageSnapshot(baseSnapshot);
1366
+ if (seq !== this.renderSeq) return;
1245
1367
  const sources = await this.resolveRenderSources(snapshot, item);
1246
1368
  if (seq !== this.renderSeq) return;
1247
1369
 
@@ -1400,3 +1522,4 @@ export class WhiteInkTool implements Extension {
1400
1522
  });
1401
1523
  }
1402
1524
  }
1525
+