fix(geometry): apply DOMMatrix rotations in spec order

This commit is contained in:
ldm0
2026-09-02 05:23:36 +08:00
committed by Donough Liu
parent 0a90591d7c
commit ce91c551ba
3 changed files with 32 additions and 9 deletions
+23
View File
@@ -73,6 +73,29 @@ mod tests {
assert_close(product.m43, 0.0);
}
#[test]
fn combined_rotation_applies_z_then_y_then_x() {
let combined = DomMatrixComponents::identity().rotated(90.0, 90.0, 90.0);
let sequential = DomMatrixComponents::identity()
.rotated(0.0, 0.0, 90.0)
.rotated(0.0, 90.0, 0.0)
.rotated(90.0, 0.0, 0.0);
for (actual, expected) in [
(combined.m11, sequential.m11),
(combined.m12, sequential.m12),
(combined.m13, sequential.m13),
(combined.m21, sequential.m21),
(combined.m22, sequential.m22),
(combined.m23, sequential.m23),
(combined.m31, sequential.m31),
(combined.m32, sequential.m32),
(combined.m33, sequential.m33),
] {
assert_close(actual, expected);
}
}
#[test]
fn css_text_rejects_non_finite_components() {
assert_eq!(
+4 -4
View File
@@ -267,14 +267,14 @@ impl DomMatrixComponents {
}
pub fn rotated(mut self, rot_x: f64, rot_y: f64, rot_z: f64) -> Self {
if rot_x != 0.0 {
self = self.rotated_axis_angle(1.0, 0.0, 0.0, rot_x);
if rot_z != 0.0 {
self = self.rotated_z(rot_z);
}
if rot_y != 0.0 {
self = self.rotated_axis_angle(0.0, 1.0, 0.0, rot_y);
}
if rot_z != 0.0 {
self = self.rotated_z(rot_z);
if rot_x != 0.0 {
self = self.rotated_axis_angle(1.0, 0.0, 0.0, rot_x);
}
self
}
@@ -373,16 +373,16 @@ test(function () {
assert_approx_equals(zAxis.b, 1, 0.000001);
const multiAxis = new DOMMatrix().rotate(45, 45, 0).transformPoint({ x: 0, y: 0, z: 1 });
assert_approx_equals(multiAxis.x, Math.SQRT1_2, 0.000001);
assert_approx_equals(multiAxis.y, -0.5, 0.000001);
assert_approx_equals(multiAxis.x, 0.5, 0.000001);
assert_approx_equals(multiAxis.y, -Math.SQRT1_2, 0.000001);
assert_approx_equals(multiAxis.z, 0.5, 0.000001);
const ordered = new DOMMatrix().rotate(30, 40, 50);
const explicit = new DOMMatrix()
.rotateAxisAngleSelf(1, 0, 0, 30)
.rotateAxisAngleSelf(0, 0, 1, 50)
.rotateAxisAngleSelf(0, 1, 0, 40)
.rotateAxisAngleSelf(0, 0, 1, 50);
assert_matrix_approx_equals(ordered, explicit, "rotate(x, y, z) composes in X then Y then Z order");
.rotateAxisAngleSelf(1, 0, 0, 30);
assert_matrix_approx_equals(ordered, explicit, "rotate(x, y, z) composes in Z then Y then X order");
}, "DOMMatrix rotate methods honor rotX, rotY, and rotZ");
test(function () {