@pooder/kit 6.2.0 → 6.2.2

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.
@@ -11,6 +11,7 @@ const commands_1 = require("./commands");
11
11
  const config_1 = require("./config");
12
12
  const model_1 = require("./model");
13
13
  const renderBuilder_1 = require("./renderBuilder");
14
+ const featurePlacement_1 = require("../featurePlacement");
14
15
  class DielineTool {
15
16
  constructor(options) {
16
17
  this.id = "pooder.kit.dieline";
@@ -250,15 +251,27 @@ class DielineTool {
250
251
  const visualRadius = radius * scale;
251
252
  const visualOffset = (cutW - sceneLayout.trimRect.width) / 2;
252
253
  const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
253
- const absoluteFeatures = (features || []).map((f) => ({
254
- ...f,
255
- x: f.x,
256
- y: f.y,
257
- width: (f.width || 0) * scale,
258
- height: (f.height || 0) * scale,
259
- radius: (f.radius || 0) * scale,
260
- }));
261
- const cutFeatures = absoluteFeatures.filter((f) => !f.skipCut);
254
+ const placements = (0, featurePlacement_1.resolveFeaturePlacements)(features || [], {
255
+ shape,
256
+ shapeStyle,
257
+ pathData,
258
+ customSourceWidthPx: this.state.customSourceWidthPx,
259
+ customSourceHeightPx: this.state.customSourceHeightPx,
260
+ canvasWidth: canvasW,
261
+ canvasHeight: canvasH,
262
+ x: cx,
263
+ y: cy,
264
+ width: sceneLayout.trimRect.width,
265
+ height: sceneLayout.trimRect.height,
266
+ radius: visualRadius,
267
+ scale,
268
+ });
269
+ const cutFeatures = (0, featurePlacement_1.projectPlacedFeatures)(placements.filter((placement) => !placement.feature.skipCut), {
270
+ x: cx,
271
+ y: cy,
272
+ width: cutW,
273
+ height: cutH,
274
+ }, scale);
262
275
  const generatedPathData = (0, geometry_1.generateDielinePath)({
263
276
  shape,
264
277
  width: cutW,
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildDielineRenderBundle = buildDielineRenderBundle;
4
4
  const geometry_1 = require("../geometry");
5
+ const featurePlacement_1 = require("../featurePlacement");
5
6
  const layers_1 = require("../../shared/constants/layers");
6
7
  const DEFAULT_IDS = {
7
8
  inside: "dieline.inside",
@@ -11,16 +12,6 @@ const DEFAULT_IDS = {
11
12
  clip: "dieline.clip.image",
12
13
  clipSource: "dieline.effect.clip-path",
13
14
  };
14
- function scaleFeatures(state, scale) {
15
- return (state.features || []).map((feature) => ({
16
- ...feature,
17
- x: feature.x,
18
- y: feature.y,
19
- width: (feature.width || 0) * scale,
20
- height: (feature.height || 0) * scale,
21
- radius: (feature.radius || 0) * scale,
22
- }));
23
- }
24
15
  function buildDielineRenderBundle(options) {
25
16
  const ids = { ...DEFAULT_IDS, ...(options.ids || {}) };
26
17
  const { state, sceneLayout, canvasWidth, canvasHeight, hasImages, createHatchPattern, includeImageClipEffect = true, clipTargetPassIds = [layers_1.IMAGE_OBJECT_LAYER_ID], clipVisibility, } = options;
@@ -35,8 +26,33 @@ function buildDielineRenderBundle(options) {
35
26
  const cutH = sceneLayout.cutRect.height;
36
27
  const visualOffset = (cutW - visualWidth) / 2;
37
28
  const cutR = visualRadius === 0 ? 0 : Math.max(0, visualRadius + visualOffset);
38
- const absoluteFeatures = scaleFeatures(state, scale);
39
- const cutFeatures = absoluteFeatures.filter((feature) => !feature.skipCut);
29
+ const placements = (0, featurePlacement_1.resolveFeaturePlacements)(state.features || [], {
30
+ shape,
31
+ shapeStyle,
32
+ pathData: state.pathData,
33
+ customSourceWidthPx: state.customSourceWidthPx,
34
+ customSourceHeightPx: state.customSourceHeightPx,
35
+ canvasWidth,
36
+ canvasHeight,
37
+ x: cx,
38
+ y: cy,
39
+ width: visualWidth,
40
+ height: visualHeight,
41
+ radius: visualRadius,
42
+ scale,
43
+ });
44
+ const absoluteFeatures = (0, featurePlacement_1.projectPlacedFeatures)(placements, {
45
+ x: cx,
46
+ y: cy,
47
+ width: visualWidth,
48
+ height: visualHeight,
49
+ }, scale);
50
+ const cutFeatures = (0, featurePlacement_1.projectPlacedFeatures)(placements.filter((placement) => !placement.feature.skipCut), {
51
+ x: cx,
52
+ y: cy,
53
+ width: cutW,
54
+ height: cutH,
55
+ }, scale);
40
56
  const common = {
41
57
  shape,
42
58
  shapeStyle,
@@ -46,6 +62,13 @@ function buildDielineRenderBundle(options) {
46
62
  canvasWidth,
47
63
  canvasHeight,
48
64
  };
65
+ const cutFrameRect = {
66
+ left: cx - cutW / 2,
67
+ top: cy - cutH / 2,
68
+ width: cutW,
69
+ height: cutH,
70
+ space: "screen",
71
+ };
49
72
  const specs = [];
50
73
  if (insideColor &&
51
74
  insideColor !== "transparent" &&
@@ -170,9 +193,13 @@ function buildDielineRenderBundle(options) {
170
193
  width: cutW,
171
194
  height: cutH,
172
195
  radius: cutR,
173
- x: cx,
174
- y: cy,
196
+ // Build the clip path in the cut frame's local coordinates so Fabric
197
+ // does not have to infer placement from the standalone path bounds.
198
+ x: cutW / 2,
199
+ y: cutH / 2,
175
200
  features: cutFeatures,
201
+ canvasWidth: cutW,
202
+ canvasHeight: cutH,
176
203
  });
177
204
  if (!clipPathData) {
178
205
  return { specs, effects: [] };
@@ -189,6 +216,12 @@ function buildDielineRenderBundle(options) {
189
216
  id: ids.clipSource,
190
217
  type: "path",
191
218
  space: "screen",
219
+ layout: {
220
+ reference: "custom",
221
+ referenceRect: cutFrameRect,
222
+ alignX: "start",
223
+ alignY: "start",
224
+ },
192
225
  data: {
193
226
  id: ids.clipSource,
194
227
  type: "dieline-effect",
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FeatureTool = void 0;
4
4
  const core_1 = require("@pooder/core");
5
5
  const fabric_1 = require("fabric");
6
- const geometry_1 = require("../geometry");
7
6
  const constraints_1 = require("../constraints");
8
7
  const featureComplete_1 = require("../featureComplete");
8
+ const featurePlacement_1 = require("../featurePlacement");
9
9
  const sceneLayoutModel_1 = require("../../shared/scene/sceneLayoutModel");
10
10
  const layers_1 = require("../../shared/constants/layers");
11
11
  const subscriptions_1 = require("../../shared/runtime/subscriptions");
@@ -726,9 +726,26 @@ class FeatureTool {
726
726
  }
727
727
  const groups = new Map();
728
728
  const singles = [];
729
- this.workingFeatures.forEach((feature, index) => {
729
+ const placements = (0, featurePlacement_1.resolveFeaturePlacements)(this.workingFeatures, {
730
+ shape: this.currentGeometry.shape,
731
+ shapeStyle: this.currentGeometry.shapeStyle,
732
+ pathData: this.currentGeometry.pathData,
733
+ customSourceWidthPx: this.currentGeometry.customSourceWidthPx,
734
+ customSourceHeightPx: this.currentGeometry.customSourceHeightPx,
735
+ x: this.currentGeometry.x,
736
+ y: this.currentGeometry.y,
737
+ width: this.currentGeometry.width,
738
+ height: this.currentGeometry.height,
739
+ radius: this.currentGeometry.radius,
740
+ scale: this.currentGeometry.scale || 1,
741
+ });
742
+ placements.forEach((placement, index) => {
743
+ const feature = placement.feature;
730
744
  const geometry = this.getGeometryForFeature(this.currentGeometry, feature);
731
- const position = (0, geometry_1.resolveFeaturePosition)(feature, geometry);
745
+ const position = {
746
+ x: placement.centerX,
747
+ y: placement.centerY,
748
+ };
732
749
  const scale = geometry.scale || 1;
733
750
  const marker = {
734
751
  feature,
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveFeaturePosition = resolveFeaturePosition;
4
+ exports.normalizePointInGeometry = normalizePointInGeometry;
5
+ function resolveFeaturePosition(feature, geometry) {
6
+ const { x, y, width, height } = geometry;
7
+ const left = x - width / 2;
8
+ const top = y - height / 2;
9
+ return {
10
+ x: left + feature.x * width,
11
+ y: top + feature.y * height,
12
+ };
13
+ }
14
+ function normalizePointInGeometry(point, geometry) {
15
+ const left = geometry.x - geometry.width / 2;
16
+ const top = geometry.y - geometry.height / 2;
17
+ return {
18
+ x: geometry.width > 0 ? (point.x - left) / geometry.width : 0.5,
19
+ y: geometry.height > 0 ? (point.y - top) / geometry.height : 0.5,
20
+ };
21
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveFeaturePlacements = resolveFeaturePlacements;
4
+ exports.projectPlacedFeatures = projectPlacedFeatures;
5
+ const constraints_1 = require("./constraints");
6
+ const featureCoordinates_1 = require("./featureCoordinates");
7
+ function scaleFeatureForRender(feature, scale, x, y) {
8
+ return {
9
+ ...feature,
10
+ x,
11
+ y,
12
+ width: feature.width !== undefined ? feature.width * scale : undefined,
13
+ height: feature.height !== undefined ? feature.height * scale : undefined,
14
+ radius: feature.radius !== undefined ? feature.radius * scale : undefined,
15
+ };
16
+ }
17
+ function resolveFeaturePlacements(features, geometry) {
18
+ const dielineWidth = geometry.scale > 0 ? geometry.width / geometry.scale : geometry.width;
19
+ const dielineHeight = geometry.scale > 0 ? geometry.height / geometry.scale : geometry.height;
20
+ return (features || []).map((feature) => {
21
+ const activeConstraints = feature.constraints?.filter((constraint) => !constraint.validateOnly);
22
+ const constrained = constraints_1.ConstraintRegistry.apply(feature.x, feature.y, feature, {
23
+ dielineWidth,
24
+ dielineHeight,
25
+ geometry,
26
+ }, activeConstraints);
27
+ const center = (0, featureCoordinates_1.resolveFeaturePosition)({
28
+ ...feature,
29
+ x: constrained.x,
30
+ y: constrained.y,
31
+ }, geometry);
32
+ return {
33
+ feature,
34
+ normalizedX: constrained.x,
35
+ normalizedY: constrained.y,
36
+ centerX: center.x,
37
+ centerY: center.y,
38
+ };
39
+ });
40
+ }
41
+ function projectPlacedFeatures(placements, geometry, scale) {
42
+ return placements.map((placement) => {
43
+ const normalized = (0, featureCoordinates_1.normalizePointInGeometry)({ x: placement.centerX, y: placement.centerY }, geometry);
44
+ return scaleFeatureForRender(placement.feature, scale, normalized.x, normalized.y);
45
+ });
46
+ }