(parts: number[])
| 963 | const Z_EPSILON = 1e-6; |
| 964 | |
| 965 | function warnIfZSignificant(parts: number[]): void { |
| 966 | if (warnedZSignificant) return; |
| 967 | // CSS matrix3d() is column-major: |
| 968 | // matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4) |
| 969 | // laid out as: |
| 970 | // | a1 a2 a3 a4 | | parts[0] parts[4] parts[8] parts[12] | |
| 971 | // | b1 b2 b3 b4 | = | parts[1] parts[5] parts[9] parts[13] | |
| 972 | // | c1 c2 c3 c4 | | parts[2] parts[6] parts[10] parts[14] | |
| 973 | // | d1 d2 d3 d4 | | parts[3] parts[7] parts[11] parts[15] | |
| 974 | // |
| 975 | // For a flat 2D transform — the only thing this engine path can render |
| 976 | // faithfully — we expect: |
| 977 | // a3 = b3 = c1 = c2 = 0 (no XZ/YZ rotation coupling) |
| 978 | // c3 = 1 (no Z scaling) |
| 979 | // d1 = d2 = d3 = 0 (no perspective) |
| 980 | // d4 = 1 (no homogeneous scaling) |
| 981 | // Z translation (c4 = parts[14]) is explicitly dropped by the 2D affine |
| 982 | // extraction below — that's the whole point of supporting GSAP's |
| 983 | // `force3D: true` translate3d(x, y, 0) emission — so it is NOT flagged. |
| 984 | const a3 = parts[8] ?? 0; |
| 985 | const b3 = parts[9] ?? 0; |
| 986 | const c1 = parts[2] ?? 0; |
| 987 | const c2 = parts[6] ?? 0; |
| 988 | const c3 = parts[10] ?? 1; |
| 989 | const d1 = parts[3] ?? 0; |
| 990 | const d2 = parts[7] ?? 0; |
| 991 | const d3 = parts[11] ?? 0; |
| 992 | const d4 = parts[15] ?? 1; |
| 993 | if ( |
| 994 | Math.abs(a3) > Z_EPSILON || |
| 995 | Math.abs(b3) > Z_EPSILON || |
| 996 | Math.abs(c1) > Z_EPSILON || |
| 997 | Math.abs(c2) > Z_EPSILON || |
| 998 | Math.abs(c3 - 1) > Z_EPSILON || |
| 999 | Math.abs(d1) > Z_EPSILON || |
| 1000 | Math.abs(d2) > Z_EPSILON || |
| 1001 | Math.abs(d3) > Z_EPSILON || |
| 1002 | Math.abs(d4 - 1) > Z_EPSILON |
| 1003 | ) { |
| 1004 | warnedZSignificant = true; |
| 1005 | console.warn( |
| 1006 | `[alphaBlit] parseTransformMatrix received a matrix3d with non-trivial 3D components ` + |
| 1007 | `(a3=${a3}, b3=${b3}, c1=${c1}, c2=${c2}, c3=${c3}, d1=${d1}, d2=${d2}, d3=${d3}, d4=${d4}). ` + |
| 1008 | `The engine projects 3D transforms to 2D (m11, m12, m21, m22, m41, m42) and silently ` + |
| 1009 | `discards perspective and out-of-plane rotation. If your composition uses real 3D ` + |
| 1010 | `(rotateX/Y, perspective), the rendered output will not match the studio preview. ` + |
| 1011 | `Z translation (translateZ) is dropped by design and does not trigger this warning. ` + |
| 1012 | `This warning is emitted once per process.`, |
| 1013 | ); |
| 1014 | } |
| 1015 | } |
no test coverage detected