@pixldocs/canvas-renderer 0.5.467 → 0.5.469

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.
@@ -5237,22 +5237,6 @@ function updateCoverLayout(g) {
5237
5237
  if (g.clipPath) {
5238
5238
  g.clipPath.dirty = true;
5239
5239
  }
5240
- if (fitContain && g.clipPath) {
5241
- const clip = g.clipPath;
5242
- const isSpecialMask = isSvgMaskClipPath(clip) || isLuminanceMaskClipPath(clip) || clip.__svgMask || clip.__edgeFadeMask;
5243
- if (!isSpecialMask) {
5244
- const clipW = Math.max(frameW, dispW);
5245
- const clipH = Math.max(frameH, dispH);
5246
- if (clip instanceof fabric.Rect) {
5247
- const rxRatioCt = Number(ct.rx) || 0;
5248
- const rxPx = rxRatioCt > 0.5 ? Math.min(rxRatioCt, clipW / 2, clipH / 2) : Math.max(0, Math.min(rxRatioCt * Math.min(clipW, clipH), clipW / 2, clipH / 2));
5249
- clip.set({ width: clipW, height: clipH, rx: rxPx, ry: rxPx, left: offsetX, top: offsetY });
5250
- } else if (clip instanceof fabric.Ellipse) {
5251
- clip.set({ rx: clipW / 2, ry: clipH / 2, left: offsetX, top: offsetY });
5252
- }
5253
- clip.dirty = true;
5254
- }
5255
- }
5256
5240
  finalizeCropGroupCoords(g);
5257
5241
  if (g.canvas) {
5258
5242
  g.setCoords();
@@ -12297,18 +12281,21 @@ const PageCanvas = forwardRef(
12297
12281
  if (id && id !== "__background__") {
12298
12282
  const width = (obj.width ?? 0) * (obj.scaleX ?? 1);
12299
12283
  const height = (obj.height ?? 0) * (obj.scaleY ?? 1);
12300
- let left = obj.left ?? 0;
12301
- let top = obj.top ?? 0;
12302
- if (obj instanceof fabric.Group && obj.__cropGroup) {
12303
- left = left - width / 2;
12304
- top = top - height / 2;
12305
- } else if (obj.originX === "center" || obj.originY === "center") {
12306
- const offsetX = obj.originX === "center" ? width / 2 : 0;
12307
- const offsetY = obj.originY === "center" ? height / 2 : 0;
12308
- left = left - offsetX;
12309
- top = top - offsetY;
12284
+ const angle = obj.angle ?? 0;
12285
+ let left;
12286
+ let top;
12287
+ const centerFn = obj.getCenterPoint;
12288
+ if (typeof centerFn === "function") {
12289
+ const c = centerFn.call(obj);
12290
+ left = c.x - width / 2;
12291
+ top = c.y - height / 2;
12292
+ } else {
12293
+ left = obj.left ?? 0;
12294
+ top = obj.top ?? 0;
12295
+ if (obj.originX === "center") left -= width / 2;
12296
+ if (obj.originY === "center") top -= height / 2;
12310
12297
  }
12311
- result.set(id, { left, top, width, height });
12298
+ result.set(id, { left, top, width, height, angle });
12312
12299
  }
12313
12300
  });
12314
12301
  return result;
@@ -17483,6 +17470,17 @@ const PageCanvas = forwardRef(
17483
17470
  const fadeKeyChanged = newFadeKey !== oldFadeKey || newFadeKey !== innerOldKey || cropFadeRendererMissing;
17484
17471
  const needsReload = sourceUrlChanged || colorMapChanged || fadeKeyChanged && !isCropGroup2;
17485
17472
  const needsCropGroupFadeUpdate = isCropGroup2 && fadeKeyChanged;
17473
+ let cropFrameSizeChanged = false;
17474
+ if (isCropGroup2) {
17475
+ const liveCt = existingObj.__cropData;
17476
+ const liveW = Number(liveCt == null ? void 0 : liveCt.frameW) || 0;
17477
+ const liveH = Number(liveCt == null ? void 0 : liveCt.frameH) || 0;
17478
+ const schemaW = (Number(element.width) || 0) * (Number(element.scaleX) || 1);
17479
+ const schemaH = (Number(element.height) || 0) * (Number(element.scaleY) || 1);
17480
+ if (schemaW > 0 && schemaH > 0 && (Math.abs(schemaW - liveW) > 0.5 || Math.abs(schemaH - liveH) > 0.5)) {
17481
+ cropFrameSizeChanged = true;
17482
+ }
17483
+ }
17486
17484
  const hadUrlBefore = storedImageUrl && String(storedImageUrl).trim() !== "";
17487
17485
  if (!hasUrl && hadUrlBefore) {
17488
17486
  const resolvedSizeImg = (pageChildren == null ? void 0 : pageChildren.length) ? getNodeBounds(element, pageChildren) : { width: typeof element.width === "number" ? element.width : 200, height: typeof element.height === "number" ? element.height : 50 };
@@ -17519,7 +17517,7 @@ const PageCanvas = forwardRef(
17519
17517
  const clipShapeForReplace = element.clipShape ?? ((_g = element.style) == null ? void 0 : _g.imageFrameShape) ?? (isPreviewMode ? "rectangle" : "none");
17520
17518
  const needCropGroupForElement = imageFitForReplace !== "fill" || clipShapeForReplace && clipShapeForReplace !== "none";
17521
17519
  const plainImageNeedsCropGroup = hasUrl && !isCropGroup2 && existingObj instanceof fabric.FabricImage && needCropGroupForElement;
17522
- if (hasUrl && (needsReload || isPlaceholder || plainImageNeedsCropGroup || needsCropGroupFadeUpdate)) {
17520
+ if (hasUrl && (needsReload || isPlaceholder || plainImageNeedsCropGroup || needsCropGroupFadeUpdate || cropFrameSizeChanged)) {
17523
17521
  if (needsReload && !isBeingTransformed && (!wasJustModified || sourceUrlChanged)) {
17524
17522
  loadImageAsync2(element, existingObj, fc);
17525
17523
  } else if (plainImageNeedsCropGroup) {
@@ -20233,27 +20231,32 @@ PageCanvas.displayName = "PageCanvas";
20233
20231
  function buildElementToFieldMap(dynamicFields) {
20234
20232
  const map = /* @__PURE__ */ new Map();
20235
20233
  if (!dynamicFields) return map;
20236
- for (const field of dynamicFields) {
20234
+ const ordered = dynamicFields.map((f, idx) => ({ f, idx })).sort((a, b) => {
20235
+ const ao = a.f.order ?? Number.POSITIVE_INFINITY;
20236
+ const bo = b.f.order ?? Number.POSITIVE_INFINITY;
20237
+ if (ao !== bo) return ao - bo;
20238
+ return a.idx - b.idx;
20239
+ });
20240
+ const push = (elementId, info) => {
20241
+ const list = map.get(elementId);
20242
+ if (list) list.push(info);
20243
+ else map.set(elementId, [info]);
20244
+ };
20245
+ ordered.forEach(({ f: field }, formIndex) => {
20237
20246
  if (field.mappings && Array.isArray(field.mappings)) {
20238
20247
  for (const mapping of field.mappings) {
20239
20248
  if (mapping.elementId) {
20240
- map.set(mapping.elementId, {
20241
- fieldId: field.id,
20242
- label: field.label
20243
- });
20249
+ push(mapping.elementId, { fieldId: field.id, label: field.label, formIndex });
20244
20250
  }
20245
20251
  }
20246
20252
  } else if (field.elementIds && Array.isArray(field.elementIds)) {
20247
20253
  for (const elementId of field.elementIds) {
20248
20254
  if (elementId) {
20249
- map.set(elementId, {
20250
- fieldId: field.id,
20251
- label: field.label
20252
- });
20255
+ push(elementId, { fieldId: field.id, label: field.label, formIndex });
20253
20256
  }
20254
20257
  }
20255
20258
  }
20256
- }
20259
+ });
20257
20260
  return map;
20258
20261
  }
20259
20262
  function PreviewCanvas({
@@ -20344,9 +20347,9 @@ function PreviewCanvas({
20344
20347
  };
20345
20348
  }, [config.themeConfig]);
20346
20349
  const handleDynamicFieldClick = useCallback((elementId) => {
20347
- const fieldInfo = elementToFieldMap.get(elementId);
20348
- if (fieldInfo && onDynamicFieldClick) {
20349
- onDynamicFieldClick(elementId, fieldInfo.fieldId);
20350
+ const infos = elementToFieldMap.get(elementId);
20351
+ if (infos && infos.length && onDynamicFieldClick) {
20352
+ onDynamicFieldClick(elementId, infos.map((i) => i.fieldId));
20350
20353
  }
20351
20354
  }, [elementToFieldMap, onDynamicFieldClick]);
20352
20355
  const dynamicFieldElements = useMemo(() => {
@@ -20354,10 +20357,14 @@ function PreviewCanvas({
20354
20357
  const seenIds = /* @__PURE__ */ new Set();
20355
20358
  for (const element of elements) {
20356
20359
  if (seenIds.has(element.id)) continue;
20357
- const fieldInfo = elementToFieldMap.get(element.id);
20358
- if (fieldInfo) {
20360
+ const infos = elementToFieldMap.get(element.id);
20361
+ if (infos && infos.length) {
20359
20362
  seenIds.add(element.id);
20360
- result.push({ element, label: fieldInfo.label });
20363
+ result.push({
20364
+ element,
20365
+ label: infos[0].label,
20366
+ extraCount: Math.max(0, infos.length - 1)
20367
+ });
20361
20368
  }
20362
20369
  }
20363
20370
  return result;
@@ -20431,7 +20438,7 @@ function PreviewCanvas({
20431
20438
  onReady
20432
20439
  }
20433
20440
  ),
20434
- onDynamicFieldClick && dynamicFieldElements.map(({ element, label }) => {
20441
+ onDynamicFieldClick && dynamicFieldElements.map(({ element, label, extraCount }) => {
20435
20442
  const bounds = actualBounds.get(element.id);
20436
20443
  const isHovered = hoveredFieldId === element.id;
20437
20444
  let left, top, width, height;
@@ -20458,22 +20465,27 @@ function PreviewCanvas({
20458
20465
  border: isHovered ? "2px solid rgb(59 130 246)" : "none",
20459
20466
  backgroundColor: isHovered ? "rgba(59, 130, 246, 0.1)" : "transparent",
20460
20467
  borderRadius: 4,
20461
- pointerEvents: "auto"
20468
+ pointerEvents: "auto",
20469
+ transform: (bounds == null ? void 0 : bounds.angle) ? `rotate(${bounds.angle}deg)` : void 0,
20470
+ transformOrigin: "center center"
20462
20471
  },
20463
20472
  onMouseEnter: () => setHoveredFieldId(element.id),
20464
20473
  onMouseLeave: () => setHoveredFieldId(null),
20465
20474
  onClick: () => {
20466
- const fieldInfo = elementToFieldMap.get(element.id);
20467
- if (fieldInfo && onDynamicFieldClick) {
20468
- onDynamicFieldClick(element.id, fieldInfo.fieldId);
20475
+ const infos = elementToFieldMap.get(element.id);
20476
+ if (infos && infos.length && onDynamicFieldClick) {
20477
+ onDynamicFieldClick(element.id, infos.map((i) => i.fieldId));
20469
20478
  }
20470
20479
  },
20471
- children: isHovered && /* @__PURE__ */ jsx(
20480
+ children: isHovered && /* @__PURE__ */ jsxs(
20472
20481
  "div",
20473
20482
  {
20474
20483
  className: "absolute -top-6 left-0 bg-primary text-primary-foreground text-xs px-2 py-0.5 rounded shadow-sm whitespace-nowrap",
20475
20484
  style: { fontSize: 10 },
20476
- children: label
20485
+ children: [
20486
+ label,
20487
+ extraCount > 0 ? ` +${extraCount} more` : ""
20488
+ ]
20477
20489
  }
20478
20490
  )
20479
20491
  },
@@ -26295,9 +26307,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
26295
26307
  }
26296
26308
  return svgString;
26297
26309
  }
26298
- const resolvedPackageVersion = "0.5.467";
26310
+ const resolvedPackageVersion = "0.5.469";
26299
26311
  const PACKAGE_VERSION = resolvedPackageVersion;
26300
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.467";
26312
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.469";
26301
26313
  const roundParityValue = (value) => {
26302
26314
  if (typeof value !== "number") return value;
26303
26315
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -27111,7 +27123,7 @@ class PixldocsRenderer {
27111
27123
  await this.waitForCanvasScene(container, cloned, i);
27112
27124
  }
27113
27125
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
27114
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-v-hlKrdw.js");
27126
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-CKIO3hJy.js");
27115
27127
  const prepared = preparePagesForExport(
27116
27128
  cloned.pages,
27117
27129
  canvasWidth,
@@ -29431,7 +29443,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
29431
29443
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
29432
29444
  sanitizeSvgTreeForPdf(svgToDraw);
29433
29445
  try {
29434
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-v-hlKrdw.js");
29446
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-CKIO3hJy.js");
29435
29447
  try {
29436
29448
  await logTextMeasurementDiagnostic(svgToDraw);
29437
29449
  } catch {
@@ -29748,4 +29760,4 @@ export {
29748
29760
  buildTeaserBlurFlatKeys as y,
29749
29761
  collectFontDescriptorsFromConfig as z
29750
29762
  };
29751
- //# sourceMappingURL=index-MX3VJ8nQ.js.map
29763
+ //# sourceMappingURL=index-P777JY1z.js.map