Skip to content

Commit 22cf59a

Browse files
committed
refactor: enhance createElementBounds utility with transform accumulation
- Refactored the createElementBounds utility to utilize the new getAccumulatedTransform function, improving the handling of element transformations. - Updated the import statements to include additional transformation utilities for better modularity and clarity.
1 parent dddccd4 commit 22cf59a

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

packages/react-grab/src/utils/create-element-bounds.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,50 @@
11
import type { OverlayBounds } from "../types.js";
2-
import { stripTranslateFromTransformString } from "./strip-translate-from-transform.js";
2+
import {
3+
stripTranslateFromMatrix,
4+
stripTranslateFromTransformString,
5+
} from "./strip-translate-from-transform.js";
6+
7+
const MAX_ANCESTOR_DEPTH = 6;
8+
const EARLY_BAIL_DEPTH = 3;
9+
10+
const getAccumulatedTransform = (
11+
element: Element,
12+
selfTransform: string,
13+
): string => {
14+
const hasSelfTransform = selfTransform && selfTransform !== "none";
15+
16+
let accumulated: DOMMatrix | null = null;
17+
let current = element.parentElement;
18+
let depth = 0;
19+
20+
while (current && current !== document.documentElement && depth < MAX_ANCESTOR_DEPTH) {
21+
const t = window.getComputedStyle(current).transform;
22+
if (t && t !== "none") {
23+
accumulated = accumulated
24+
? new DOMMatrix(t).multiply(accumulated)
25+
: new DOMMatrix(t);
26+
} else if (!hasSelfTransform && !accumulated && depth >= EARLY_BAIL_DEPTH) {
27+
return "none";
28+
}
29+
current = current.parentElement;
30+
depth++;
31+
}
32+
33+
if (!accumulated) {
34+
return hasSelfTransform ? stripTranslateFromTransformString(selfTransform) : "none";
35+
}
36+
37+
if (hasSelfTransform) {
38+
accumulated = accumulated.multiply(new DOMMatrix(selfTransform));
39+
}
40+
41+
return stripTranslateFromMatrix(accumulated);
42+
};
343

444
export const createElementBounds = (element: Element): OverlayBounds => {
545
const rect = element.getBoundingClientRect();
646
const style = window.getComputedStyle(element);
7-
const transform = stripTranslateFromTransformString(style.transform);
47+
const transform = getAccumulatedTransform(element, style.transform);
848

949
if (transform !== "none" && element instanceof HTMLElement) {
1050
const ow = element.offsetWidth;

packages/react-grab/src/utils/strip-translate-from-transform.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,30 @@ export const stripTranslateFromTransformString = (transform: string): string =>
9393
return "none";
9494
};
9595

96+
/**
97+
* Strips translation from a DOMMatrix, returning a CSS matrix string.
98+
*/
99+
export const stripTranslateFromMatrix = (matrix: DOMMatrix): string => {
100+
if (matrix.isIdentity) return "none";
101+
102+
if (matrix.is2D) {
103+
if (isIdentityMatrix2d(matrix.a, matrix.b, matrix.c, matrix.d)) return "none";
104+
return `matrix(${matrix.a}, ${matrix.b}, ${matrix.c}, ${matrix.d}, 0, 0)`;
105+
}
106+
107+
const m = matrix;
108+
if (
109+
m.m11 === 1 && m.m12 === 0 && m.m13 === 0 && m.m14 === 0 &&
110+
m.m21 === 0 && m.m22 === 1 && m.m23 === 0 && m.m24 === 0 &&
111+
m.m31 === 0 && m.m32 === 0 && m.m33 === 1 && m.m34 === 0 &&
112+
m.m44 === 1
113+
) {
114+
return "none";
115+
}
116+
117+
return `matrix3d(${m.m11}, ${m.m12}, ${m.m13}, ${m.m14}, ${m.m21}, ${m.m22}, ${m.m23}, ${m.m24}, ${m.m31}, ${m.m32}, ${m.m33}, ${m.m34}, 0, 0, 0, ${m.m44})`;
118+
};
119+
96120
/**
97121
* Strips translation components from a CSS transform while preserving other transformations.
98122
*

0 commit comments

Comments
 (0)