@pixldocs/canvas-renderer 0.5.387 → 0.5.389

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.
@@ -13512,6 +13512,55 @@ const PageCanvas = forwardRef(
13512
13512
  if (!found) return null;
13513
13513
  return { left: minX, top: minY, right: maxX, bottom: maxY };
13514
13514
  };
13515
+ const groupFabricOrientedBBox = (g) => {
13516
+ var _a2;
13517
+ const memberIds = new Set(getAllElementIds(g.children ?? []));
13518
+ if (memberIds.size === 0) return null;
13519
+ const members = [];
13520
+ for (const o of fabricCanvas.getObjects()) {
13521
+ const oid = getObjectId(o);
13522
+ if (oid && memberIds.has(oid)) members.push(o);
13523
+ }
13524
+ if (members.length === 0) return null;
13525
+ const a0 = ((members[0].angle ?? 0) % 360 + 360) % 360;
13526
+ const TOL = 0.5;
13527
+ for (const m of members) {
13528
+ const a = ((m.angle ?? 0) % 360 + 360) % 360;
13529
+ const diff = Math.min(Math.abs(a - a0), 360 - Math.abs(a - a0));
13530
+ if (diff > TOL) return null;
13531
+ }
13532
+ const rad = -a0 * Math.PI / 180;
13533
+ const cos = Math.cos(rad), sin = Math.sin(rad);
13534
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
13535
+ let found = false;
13536
+ for (const m of members) {
13537
+ (_a2 = m.setCoords) == null ? void 0 : _a2.call(m);
13538
+ const aC = m.aCoords;
13539
+ if (!aC) continue;
13540
+ for (const k of ["tl", "tr", "br", "bl"]) {
13541
+ const p = aC[k];
13542
+ if (!p) continue;
13543
+ const xr = p.x * cos - p.y * sin;
13544
+ const yr = p.x * sin + p.y * cos;
13545
+ if (xr < minX) minX = xr;
13546
+ if (yr < minY) minY = yr;
13547
+ if (xr > maxX) maxX = xr;
13548
+ if (yr > maxY) maxY = yr;
13549
+ found = true;
13550
+ }
13551
+ }
13552
+ if (!found) return null;
13553
+ const radBack = a0 * Math.PI / 180;
13554
+ const cb = Math.cos(radBack), sb = Math.sin(radBack);
13555
+ const toCanvas = (x, y) => ({ x: x * cb - y * sb, y: x * sb + y * cb });
13556
+ const corners = [
13557
+ toCanvas(minX, minY),
13558
+ toCanvas(maxX, minY),
13559
+ toCanvas(maxX, maxY),
13560
+ toCanvas(minX, maxY)
13561
+ ];
13562
+ return { corners, angle: a0 };
13563
+ };
13515
13564
  const pickGroupAtPointer = (px, py, children, activeEditingGroupId) => {
13516
13565
  let pick = null;
13517
13566
  for (const node of children) {
@@ -13758,6 +13807,21 @@ const PageCanvas = forwardRef(
13758
13807
  const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
13759
13808
  const groupPick = pickGroupAtPointer(pointer.x, pointer.y, childrenNow, activeEditingGroupId);
13760
13809
  if (groupPick && !activeIds.has(groupPick.group.id)) {
13810
+ const oriented = groupFabricOrientedBBox(groupPick.group);
13811
+ if (oriented) {
13812
+ const pts = oriented.corners.map((p) => `${p.x},${p.y}`).join(" ");
13813
+ const xs = oriented.corners.map((p) => p.x);
13814
+ const ys = oriented.corners.map((p) => p.y);
13815
+ setHoverBounds({
13816
+ left: Math.min(...xs),
13817
+ top: Math.min(...ys),
13818
+ width: Math.max(...xs) - Math.min(...xs),
13819
+ height: Math.max(...ys) - Math.min(...ys),
13820
+ angle: oriented.angle,
13821
+ points: pts
13822
+ });
13823
+ return;
13824
+ }
13761
13825
  const b = groupFabricUnionBBox(groupPick.group);
13762
13826
  if (b) {
13763
13827
  setHoverBounds({
@@ -13773,14 +13837,31 @@ const PageCanvas = forwardRef(
13773
13837
  const isHoveringSelected = !!(tid && activeIds.has(tid));
13774
13838
  if (t && tid && tid !== "__background__" && !isHoveringSelected) {
13775
13839
  t.setCoords();
13776
- const br = t.getBoundingRect();
13777
- setHoverBounds({
13778
- left: br.left,
13779
- top: br.top,
13780
- width: br.width,
13781
- height: br.height,
13782
- angle: 0
13783
- });
13840
+ const ang = ((t.angle ?? 0) % 360 + 360) % 360;
13841
+ const aC = t.aCoords;
13842
+ if (ang > 0.5 && (aC == null ? void 0 : aC.tl) && (aC == null ? void 0 : aC.tr) && (aC == null ? void 0 : aC.br) && (aC == null ? void 0 : aC.bl)) {
13843
+ const corners = [aC.tl, aC.tr, aC.br, aC.bl];
13844
+ const pts = corners.map((p) => `${p.x},${p.y}`).join(" ");
13845
+ const xs = corners.map((p) => p.x);
13846
+ const ys = corners.map((p) => p.y);
13847
+ setHoverBounds({
13848
+ left: Math.min(...xs),
13849
+ top: Math.min(...ys),
13850
+ width: Math.max(...xs) - Math.min(...xs),
13851
+ height: Math.max(...ys) - Math.min(...ys),
13852
+ angle: ang,
13853
+ points: pts
13854
+ });
13855
+ } else {
13856
+ const br = t.getBoundingRect();
13857
+ setHoverBounds({
13858
+ left: br.left,
13859
+ top: br.top,
13860
+ width: br.width,
13861
+ height: br.height,
13862
+ angle: 0
13863
+ });
13864
+ }
13784
13865
  } else {
13785
13866
  setHoverBounds(null);
13786
13867
  }
@@ -14231,23 +14312,26 @@ const PageCanvas = forwardRef(
14231
14312
  if (child instanceof fabric.Group && (child.__cropGroup || ((_f = child._ct) == null ? void 0 : _f.isCropGroup))) {
14232
14313
  const ct = child.__cropData;
14233
14314
  if (!ct) continue;
14315
+ if (child.__asLiveOrigAngle == null) {
14316
+ child.__asLiveOrigAngle = child.angle ?? 0;
14317
+ }
14318
+ const childAngleDegC = child.__asLiveOrigAngle;
14319
+ const asSxC = isXSide ? sAxis : 1;
14320
+ const asSyC = isXSide ? 1 : sAxis;
14321
+ const thetaC = fabric.util.degreesToRadians(childAngleDegC);
14322
+ const cosTC = Math.cos(thetaC);
14323
+ const sinTC = Math.sin(thetaC);
14324
+ const sLocalC = isXSide ? asSxC * cosTC * cosTC + sinTC * sinTC : asSyC * cosTC * cosTC + sinTC * sinTC;
14234
14325
  if (isXSide) {
14235
14326
  if (child.__asLiveOrigW == null) {
14236
14327
  const baseW = child.width ?? ct.frameW ?? 0;
14237
14328
  child.__asLiveOrigW = baseW * (child.scaleX ?? 1);
14238
14329
  }
14239
14330
  const origW = child.__asLiveOrigW;
14240
- const newW = Math.max(20, origW * sAxis);
14331
+ const newW = Math.max(20, origW * sLocalC);
14241
14332
  if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14242
14333
  ct.frameW = newW;
14243
14334
  child._set("width", newW);
14244
- child._set("scaleX", 1 / sAxis);
14245
- try {
14246
- updateCoverLayout(child);
14247
- } catch {
14248
- }
14249
- child.setCoords();
14250
- child.dirty = true;
14251
14335
  }
14252
14336
  } else {
14253
14337
  if (child.__asLiveOrigH == null) {
@@ -14255,47 +14339,88 @@ const PageCanvas = forwardRef(
14255
14339
  child.__asLiveOrigH = baseH * (child.scaleY ?? 1);
14256
14340
  }
14257
14341
  const origH = child.__asLiveOrigH;
14258
- const newH = Math.max(20, origH * sAxis);
14342
+ const newH = Math.max(20, origH * sLocalC);
14259
14343
  if (Math.abs((child.height ?? 0) - newH) > 0.5) {
14260
14344
  ct.frameH = newH;
14261
14345
  child._set("height", newH);
14262
- child._set("scaleY", 1 / sAxis);
14263
- try {
14264
- updateCoverLayout(child);
14265
- } catch {
14266
- }
14267
- child.setCoords();
14268
- child.dirty = true;
14269
14346
  }
14270
14347
  }
14348
+ try {
14349
+ const invC = [1 / asSxC, 0, 0, 1 / asSyC, 0, 0];
14350
+ const RthetaC = fabric.util.composeMatrix({
14351
+ angle: childAngleDegC,
14352
+ scaleX: 1,
14353
+ scaleY: 1,
14354
+ translateX: 0,
14355
+ translateY: 0
14356
+ });
14357
+ const MC = fabric.util.multiplyTransformMatrices(invC, RthetaC);
14358
+ const decC = fabric.util.qrDecompose(MC);
14359
+ child._set("angle", decC.angle);
14360
+ child._set("scaleX", decC.scaleX);
14361
+ child._set("scaleY", decC.scaleY);
14362
+ child._set("skewX", decC.skewX);
14363
+ child._set("skewY", decC.skewY);
14364
+ } catch {
14365
+ }
14366
+ try {
14367
+ updateCoverLayout(child);
14368
+ } catch {
14369
+ }
14370
+ child.setCoords();
14371
+ child.dirty = true;
14271
14372
  continue;
14272
14373
  }
14273
14374
  if (child instanceof fabric.FabricImage && !child.__cropGroup && !child.smartElementType) {
14375
+ if (child.__asLiveOrigAngle == null) {
14376
+ child.__asLiveOrigAngle = child.angle ?? 0;
14377
+ }
14378
+ const childAngleDegI = child.__asLiveOrigAngle;
14379
+ const asSxI = isXSide ? sAxis : 1;
14380
+ const asSyI = isXSide ? 1 : sAxis;
14381
+ const thetaI = fabric.util.degreesToRadians(childAngleDegI);
14382
+ const cosTI = Math.cos(thetaI);
14383
+ const sinTI = Math.sin(thetaI);
14384
+ const sLocalI = isXSide ? asSxI * cosTI * cosTI + sinTI * sinTI : asSyI * cosTI * cosTI + sinTI * sinTI;
14274
14385
  if (isXSide) {
14275
14386
  if (child.__asLiveOrigW == null) {
14276
14387
  child.__asLiveOrigW = (child.width ?? 0) * (child.scaleX ?? 1);
14277
14388
  }
14278
14389
  const origW = child.__asLiveOrigW;
14279
- const newW = Math.max(1, origW * sAxis);
14390
+ const newW = Math.max(1, origW * sLocalI);
14280
14391
  if (Math.abs((child.width ?? 0) - newW) > 0.5) {
14281
14392
  child._set("width", newW);
14282
- child._set("scaleX", 1 / sAxis);
14283
- child.setCoords();
14284
- child.dirty = true;
14285
14393
  }
14286
14394
  } else {
14287
14395
  if (child.__asLiveOrigH == null) {
14288
14396
  child.__asLiveOrigH = (child.height ?? 0) * (child.scaleY ?? 1);
14289
14397
  }
14290
14398
  const origH = child.__asLiveOrigH;
14291
- const newH = Math.max(1, origH * sAxis);
14399
+ const newH = Math.max(1, origH * sLocalI);
14292
14400
  if (Math.abs((child.height ?? 0) - newH) > 0.5) {
14293
14401
  child._set("height", newH);
14294
- child._set("scaleY", 1 / sAxis);
14295
- child.setCoords();
14296
- child.dirty = true;
14297
14402
  }
14298
14403
  }
14404
+ try {
14405
+ const invI = [1 / asSxI, 0, 0, 1 / asSyI, 0, 0];
14406
+ const RthetaI = fabric.util.composeMatrix({
14407
+ angle: childAngleDegI,
14408
+ scaleX: 1,
14409
+ scaleY: 1,
14410
+ translateX: 0,
14411
+ translateY: 0
14412
+ });
14413
+ const MI = fabric.util.multiplyTransformMatrices(invI, RthetaI);
14414
+ const decI = fabric.util.qrDecompose(MI);
14415
+ child._set("angle", decI.angle);
14416
+ child._set("scaleX", decI.scaleX);
14417
+ child._set("scaleY", decI.scaleY);
14418
+ child._set("skewX", decI.skewX);
14419
+ child._set("skewY", decI.skewY);
14420
+ } catch {
14421
+ }
14422
+ child.setCoords();
14423
+ child.dirty = true;
14299
14424
  continue;
14300
14425
  }
14301
14426
  if (!(child instanceof fabric.Textbox)) continue;
@@ -18732,7 +18857,18 @@ const PageCanvas = forwardRef(
18732
18857
  className: "absolute inset-0 pointer-events-none",
18733
18858
  style: { width: scaledWidth, height: scaledHeight },
18734
18859
  viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
18735
- children: /* @__PURE__ */ jsx(
18860
+ children: hoverBounds.points ? /* @__PURE__ */ jsx(
18861
+ "polygon",
18862
+ {
18863
+ points: hoverBounds.points,
18864
+ fill: "none",
18865
+ stroke: SELECTION_PRIMARY,
18866
+ strokeWidth: 2,
18867
+ vectorEffect: "non-scaling-stroke",
18868
+ strokeDasharray: "0",
18869
+ opacity: 1
18870
+ }
18871
+ ) : /* @__PURE__ */ jsx(
18736
18872
  "rect",
18737
18873
  {
18738
18874
  x: hoverBounds.left,
@@ -24882,9 +25018,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
24882
25018
  }
24883
25019
  return svgString;
24884
25020
  }
24885
- const resolvedPackageVersion = "0.5.387";
25021
+ const resolvedPackageVersion = "0.5.389";
24886
25022
  const PACKAGE_VERSION = resolvedPackageVersion;
24887
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.387";
25023
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.389";
24888
25024
  const roundParityValue = (value) => {
24889
25025
  if (typeof value !== "number") return value;
24890
25026
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -25698,7 +25834,7 @@ class PixldocsRenderer {
25698
25834
  await this.waitForCanvasScene(container, cloned, i);
25699
25835
  }
25700
25836
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
25701
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-DNhNOmXo.js");
25837
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-aeROfqEB.js");
25702
25838
  const prepared = preparePagesForExport(
25703
25839
  cloned.pages,
25704
25840
  canvasWidth,
@@ -28018,7 +28154,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
28018
28154
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
28019
28155
  sanitizeSvgTreeForPdf(svgToDraw);
28020
28156
  try {
28021
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-DNhNOmXo.js");
28157
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-aeROfqEB.js");
28022
28158
  try {
28023
28159
  await logTextMeasurementDiagnostic(svgToDraw);
28024
28160
  } catch {
@@ -28418,4 +28554,4 @@ export {
28418
28554
  buildTeaserBlurFlatKeys as y,
28419
28555
  collectFontDescriptorsFromConfig as z
28420
28556
  };
28421
- //# sourceMappingURL=index-Dojo9KpB.js.map
28557
+ //# sourceMappingURL=index-CxeXN5KG.js.map