@hyperframes/studio 0.7.105 → 0.7.106

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/dist/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <title>HyperFrames Studio</title>
8
- <script type="module" crossorigin src="/assets/index-DuxKGsHZ.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-DerI0ikN.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-tBPidglp.css">
10
10
  </head>
11
11
  <body>
package/dist/index.js CHANGED
@@ -23596,6 +23596,39 @@ function buildAgentContextPreview(selection, activeCompPath) {
23596
23596
  ].filter(Boolean).join("\n");
23597
23597
  }
23598
23598
 
23599
+ // src/components/editor/domEditOverlayTransform.ts
23600
+ var COMPOSITION_ROOT_ATTR = "data-composition-id";
23601
+ function individualRotateDegrees(value) {
23602
+ if (!value || value === "none") return 0;
23603
+ const parts = value.trim().split(/\s+/);
23604
+ const angle = parts.at(-1);
23605
+ if (!angle?.endsWith("deg")) return 0;
23606
+ if (parts.length === 4) {
23607
+ const [x, y, z] = parts;
23608
+ if (Number(x) !== 0 || Number(y) !== 0 || Math.abs(Number(z)) !== 1) return 0;
23609
+ const deg2 = Number.parseFloat(angle);
23610
+ return Number.isFinite(deg2) ? deg2 * Math.sign(Number(z)) : 0;
23611
+ }
23612
+ if (parts.length !== 1) return 0;
23613
+ const deg = Number.parseFloat(angle);
23614
+ return Number.isFinite(deg) ? deg : 0;
23615
+ }
23616
+ function composeElementTransform(element, ops, getStyle) {
23617
+ let acc = ops.identity();
23618
+ for (let node = element; node; node = node.parentElement) {
23619
+ const style = getStyle(node);
23620
+ if (!style) return null;
23621
+ const transform = style.transform;
23622
+ let own = transform && transform !== "none" ? ops.fromTransform(transform) : ops.identity();
23623
+ if (!own) return null;
23624
+ const spin = individualRotateDegrees(style.rotate);
23625
+ if (spin !== 0) own = ops.compose(ops.fromRotate(spin), own);
23626
+ acc = ops.compose(own, acc);
23627
+ if (node.hasAttribute(COMPOSITION_ROOT_ATTR)) break;
23628
+ }
23629
+ return acc;
23630
+ }
23631
+
23599
23632
  // src/components/editor/clipPathHelpers.ts
23600
23633
  function formatClipNumber(value) {
23601
23634
  const rounded2 = roundToCenti(value);
@@ -23737,6 +23770,49 @@ function hugRectForElement(rect, element) {
23737
23770
  return rect;
23738
23771
  return cropRectFromInsets(rect, insets, rect.editScaleX, rect.editScaleY);
23739
23772
  }
23773
+ var IDENTITY = { a: 1, b: 0, c: 0, d: 1 };
23774
+ var PERSPECTIVE_EPSILON = 1e-6;
23775
+ function parseMatrixComponents(transform) {
23776
+ const flat = /^matrix\(([^)]+)\)$/.exec(transform);
23777
+ if (flat) {
23778
+ const [a, b, c, d] = flat[1].split(",").map((v) => Number.parseFloat(v));
23779
+ return [a, b, c, d].every(Number.isFinite) ? { a, b, c, d } : null;
23780
+ }
23781
+ const spatial = /^matrix3d\(([^)]+)\)$/.exec(transform);
23782
+ if (!spatial) return null;
23783
+ const m = spatial[1].split(",").map((v) => Number.parseFloat(v));
23784
+ if (m.length !== 16 || !m.every(Number.isFinite)) return null;
23785
+ const affine = [m[3], m[7], m[11]].every((v) => Math.abs(v) < PERSPECTIVE_EPSILON);
23786
+ if (!affine) return null;
23787
+ return { a: m[0], b: m[1], c: m[4], d: m[5] };
23788
+ }
23789
+ var PLANAR_2D_OPS = {
23790
+ identity: () => IDENTITY,
23791
+ fromTransform: parseMatrixComponents,
23792
+ fromRotate: (degrees2) => {
23793
+ const rad = degrees2 * Math.PI / 180;
23794
+ return { a: Math.cos(rad), b: Math.sin(rad), c: -Math.sin(rad), d: Math.cos(rad) };
23795
+ },
23796
+ compose: (outer, inner) => ({
23797
+ a: outer.a * inner.a + outer.c * inner.b,
23798
+ b: outer.b * inner.a + outer.d * inner.b,
23799
+ c: outer.a * inner.c + outer.c * inner.d,
23800
+ d: outer.b * inner.c + outer.d * inner.d
23801
+ })
23802
+ };
23803
+ function isIdentity(m) {
23804
+ return Math.abs(m.a - 1) < PERSPECTIVE_EPSILON && Math.abs(m.b) < PERSPECTIVE_EPSILON && Math.abs(m.c) < PERSPECTIVE_EPSILON && Math.abs(m.d - 1) < PERSPECTIVE_EPSILON;
23805
+ }
23806
+ function readPlanarTransform(element) {
23807
+ const acc = composeElementTransform(element, PLANAR_2D_OPS, (node) => {
23808
+ try {
23809
+ return node.ownerDocument.defaultView?.getComputedStyle(node) ?? null;
23810
+ } catch {
23811
+ return null;
23812
+ }
23813
+ });
23814
+ return acc && !isIdentity(acc) ? acc : null;
23815
+ }
23740
23816
  function readElementCropFrame(element, overlayRect) {
23741
23817
  const editX = overlayRect.editScaleX > 0 ? overlayRect.editScaleX : 1;
23742
23818
  const editY = overlayRect.editScaleY > 0 ? overlayRect.editScaleY : 1;
@@ -23749,20 +23825,12 @@ function readElementCropFrame(element, overlayRect) {
23749
23825
  scaleX: editX,
23750
23826
  scaleY: editY
23751
23827
  };
23752
- let transform = "";
23753
- try {
23754
- transform = element.ownerDocument.defaultView?.getComputedStyle(element).transform ?? "";
23755
- } catch {
23756
- return aabb;
23757
- }
23758
- if (!transform || transform === "none") return aabb;
23759
- const m = /^matrix\(([^)]+)\)$/.exec(transform);
23760
- if (!m) return aabb;
23761
- const [a, b, c, d] = m[1].split(",").map((v) => Number.parseFloat(v));
23762
- if (![a, b, c, d].every(Number.isFinite)) return aabb;
23828
+ const planar = readPlanarTransform(element);
23829
+ if (!planar) return aabb;
23830
+ const { a, b, c, d } = planar;
23763
23831
  const elScaleX = Math.hypot(a, b);
23764
23832
  const det = a * d - b * c;
23765
- const elScaleY = elScaleX !== 0 ? det / elScaleX : 1;
23833
+ const elScaleY = elScaleX !== 0 ? Math.abs(det) / elScaleX : 1;
23766
23834
  if (elScaleX <= 0 || elScaleY <= 0) return aabb;
23767
23835
  const angleDeg = Math.atan2(b, a) * 180 / Math.PI;
23768
23836
  const scaleX = elScaleX * editX;
@@ -23827,16 +23895,19 @@ function readElementTransformSnapshot(win, element) {
23827
23895
  const DOMMatrixCtor = win.DOMMatrix;
23828
23896
  if (!DOMMatrixCtor) return null;
23829
23897
  const cs = win.getComputedStyle(element);
23898
+ const ops = {
23899
+ identity: () => new DOMMatrixCtor(),
23900
+ fromTransform: (value) => new DOMMatrixCtor(value),
23901
+ fromRotate: (degrees2) => new DOMMatrixCtor().rotateSelf(degrees2),
23902
+ compose: (outer, inner) => outer.multiply(inner)
23903
+ };
23830
23904
  try {
23831
- let matrix = new DOMMatrixCtor();
23832
- for (let node = element; node; node = node.parentElement) {
23833
- const transform = node === element ? cs.transform : win.getComputedStyle(node).transform;
23834
- if (transform && transform !== "none") {
23835
- matrix = new DOMMatrixCtor(transform).multiply(matrix);
23836
- }
23837
- if (node.hasAttribute("data-composition-id")) break;
23838
- }
23839
- return { matrix, cs };
23905
+ const matrix = composeElementTransform(
23906
+ element,
23907
+ ops,
23908
+ (node) => node === element ? cs : win.getComputedStyle(node)
23909
+ );
23910
+ return matrix ? { matrix, cs } : null;
23840
23911
  } catch {
23841
23912
  return null;
23842
23913
  }