mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibWeb: Add DOMMatrix rotate, rotateFromVector and rotateAxisAngle
This commit is contained in:
parent
42c2a67c83
commit
6265c544f9
Notes:
sideshowbarker
2024-07-17 11:06:06 +09:00
Author: https://github.com/bplaat Commit: https://github.com/SerenityOS/serenity/commit/6265c544f9 Pull-request: https://github.com/SerenityOS/serenity/pull/20981 Reviewed-by: https://github.com/ADKaster ✅
8 changed files with 144 additions and 6 deletions
8
Tests/LibWeb/Text/expected/geometry/dommatrix-rotate.txt
Normal file
8
Tests/LibWeb/Text/expected/geometry/dommatrix-rotate.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
1. 22.233366125282362
|
||||
2. 35.06980604270564
|
||||
3. 22.06722747248274
|
||||
4. 26.483172559777778
|
||||
5. {"a":30,"b":40,"c":-9.999999999999998,"d":-19.999999999999996,"e":50,"f":60,"m11":30,"m12":40,"m13":0,"m14":0,"m21":-9.999999999999998,"m22":-19.999999999999996,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
|
||||
6. {"a":30,"b":40,"c":-9.999999999999998,"d":-19.999999999999996,"e":50,"f":60,"m11":30,"m12":40,"m13":0,"m14":0,"m21":-9.999999999999998,"m22":-19.999999999999996,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":true,"isIdentity":false}
|
||||
7. {"a":9.84807753012208,"b":19.69615506024416,"c":30,"d":40,"e":50,"f":60,"m11":9.84807753012208,"m12":19.69615506024416,"m13":-0.17364817766693033,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":1.7364817766693033,"m32":3.4729635533386065,"m33":0.984807753012208,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":false,"isIdentity":false}
|
||||
8. {"a":9.84807753012208,"b":19.69615506024416,"c":30,"d":40,"e":50,"f":60,"m11":9.84807753012208,"m12":19.69615506024416,"m13":-0.17364817766693033,"m14":0,"m21":30,"m22":40,"m23":0,"m24":0,"m31":1.7364817766693033,"m32":3.4729635533386065,"m33":0.984807753012208,"m34":0,"m41":50,"m42":60,"m43":0,"m44":1,"is2D":false,"isIdentity":false}
|
33
Tests/LibWeb/Text/input/geometry/dommatrix-rotate.html
Normal file
33
Tests/LibWeb/Text/input/geometry/dommatrix-rotate.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
let testCounter = 1;
|
||||
function testPart(part) {
|
||||
println(`${testCounter++}. ${JSON.stringify(part())}`);
|
||||
}
|
||||
|
||||
// 1. Rotate DOMMatrix
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).rotate(10, 20, 30).a);
|
||||
|
||||
// 2. Rotate DOMMatrix with multiply
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().rotate(10, 20, 30)).b);
|
||||
|
||||
// 4. Rotate DOMMatrix
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).rotate(10, 20, 30).c);
|
||||
|
||||
// 5. Rotate DOMMatrix with multiply
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().rotate(10, 20, 30)).d);
|
||||
|
||||
// 6. Rotate from Vector DOMMatrix
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).rotateFromVector(0, 45));
|
||||
|
||||
// 7. Rotate from Vector DOMMatrix with multiply
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().rotateFromVector(0, 45)));
|
||||
|
||||
// 8. Rotate from Axis Angle DOMMatrix
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).rotateAxisAngle(0, 1, 0, 10));
|
||||
|
||||
// 9. Rotate from Axis Angle DOMMatrix with multiply
|
||||
testPart(() => new DOMMatrix([10, 20, 30, 40, 50, 60]).multiply(new DOMMatrix().rotateAxisAngle(0, 1, 0, 10)));
|
||||
});
|
||||
</script>
|
|
@ -371,6 +371,67 @@ JS::NonnullGCPtr<DOMMatrix> DOMMatrix::scale3d_self(Optional<double> scale, Opti
|
|||
return *this;
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrix-rotateself
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrix::rotate_self(Optional<double> rot_x, Optional<double> rot_y, Optional<double> rot_z)
|
||||
{
|
||||
// 1. If rotY and rotZ are both missing, set rotZ to the value of rotX and set rotX and rotY to 0.
|
||||
if (!rot_y.has_value() && !rot_z.has_value()) {
|
||||
rot_z = rot_x;
|
||||
rot_x = 0;
|
||||
rot_y = 0;
|
||||
}
|
||||
|
||||
// 2. If rotY is still missing, set rotY to 0.
|
||||
if (!rot_y.has_value())
|
||||
rot_y = 0;
|
||||
|
||||
// 3. If rotZ is still missing, set rotZ to 0.
|
||||
if (!rot_z.has_value())
|
||||
rot_z = 0;
|
||||
|
||||
// 4. If rotX or rotY are not 0 or -0, set is 2D of the current matrix to false.
|
||||
if (rot_x != 0 || rot_x != -0 || rot_y != 0 || rot_y != -0)
|
||||
m_is_2d = false;
|
||||
|
||||
// 5. Post-multiply a rotation transformation on the current matrix around the vector 0, 0, 1 by the specified rotation rotZ in degrees. The 3D rotation matrix is described in CSS Transforms with alpha = rotZ in degrees. [CSS3-TRANSFORMS]
|
||||
m_matrix = m_matrix * Gfx::rotation_matrix<double>(Vector3<double> { 0.0, 0.0, 1.0 }, AK::to_radians(rot_z.value()));
|
||||
|
||||
// 6. Post-multiply a rotation transformation on the current matrix around the vector 0, 1, 0 by the specified rotation rotY in degrees. The 3D rotation matrix is described in CSS Transforms with alpha = rotY in degrees. [CSS3-TRANSFORMS]
|
||||
m_matrix = m_matrix * Gfx::rotation_matrix<double>(Vector3<double> { 0.0, 1.0, 0.0 }, AK::to_radians(rot_y.value()));
|
||||
|
||||
// 7. Post-multiply a rotation transformation on the current matrix around the vector 1, 0, 0 by the specified rotation rotX in degrees. The 3D rotation matrix is described in CSS Transforms with alpha = rotX in degrees. [CSS3-TRANSFORMS]
|
||||
m_matrix = m_matrix * Gfx::rotation_matrix<double>(Vector3<double> { 1.0, 0.0, 0.0 }, AK::to_radians(rot_x.value()));
|
||||
|
||||
// 8. Return the current matrix.
|
||||
return *this;
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrix::rotate_from_vector_self(Optional<double> x, Optional<double> y)
|
||||
{
|
||||
// 1. Post-multiply a rotation transformation on the current matrix.
|
||||
// The rotation angle is determined by the angle between the vector (1,0)T and (x,y)T in the clockwise direction. If x and y should both be 0 or -0, the angle is specified as 0.
|
||||
double angle = (x == 0 || x == -0) && (y == 0 || y == -0) ? 0.0 : atan2(y.value_or(0), x.value_or(0));
|
||||
|
||||
// The 2D rotation matrix is described in CSS Transforms where alpha is the angle between the vector (1,0)T and (x,y)T in degrees. [CSS3-TRANSFORMS]
|
||||
m_matrix = m_matrix * Gfx::rotation_matrix<double>(Vector3<double> { 0.0, 0.0, 1.0 }, angle);
|
||||
|
||||
// 2. Return the current matrix.
|
||||
return *this;
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrix::rotate_axis_angle_self(Optional<double> x, Optional<double> y, Optional<double> z, Optional<double> angle)
|
||||
{
|
||||
// 1. Post-multiply a rotation transformation on the current matrix around the specified vector x, y, z by the specified rotation angle in degrees. The 3D rotation matrix is described in CSS Transforms with alpha = angle in degrees. [CSS3-TRANSFORMS]
|
||||
m_matrix = m_matrix * Gfx::rotation_matrix<double>(Vector3<double> { x.value_or(0), y.value_or(0), z.value_or(0) }.normalized(), AK::to_radians(angle.value()));
|
||||
|
||||
// 2. If x or y are not 0 or -0, set is 2D of the current matrix to false.
|
||||
if (x != 0 || x != -0 || y != 0 || y != -0)
|
||||
m_is_2d = false;
|
||||
|
||||
// 3. Return the current matrix.
|
||||
return *this;
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrix-skewxself
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrix::skew_x_self(double sx)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
JS::NonnullGCPtr<DOMMatrix> translate_self(Optional<double> tx, Optional<double> ty, Optional<double> tz);
|
||||
JS::NonnullGCPtr<DOMMatrix> scale_self(Optional<double> scale_x, Optional<double> scale_y, Optional<double> scale_z, Optional<double> origin_x, Optional<double> origin_y, Optional<double> origin_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> scale3d_self(Optional<double> scale, Optional<double> origin_x, Optional<double> origin_y, Optional<double> origin_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate_self(Optional<double> rot_x, Optional<double> rot_y, Optional<double> rot_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate_from_vector_self(Optional<double> x, Optional<double> y);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate_axis_angle_self(Optional<double> x, Optional<double> y, Optional<double> z, Optional<double> angle);
|
||||
JS::NonnullGCPtr<DOMMatrix> skew_x_self(double sx = 0);
|
||||
JS::NonnullGCPtr<DOMMatrix> skew_y_self(double sy = 0);
|
||||
JS::NonnullGCPtr<DOMMatrix> invert_self();
|
||||
|
|
|
@ -41,9 +41,9 @@ interface DOMMatrix : DOMMatrixReadOnly {
|
|||
DOMMatrix translateSelf(optional unrestricted double tx = 0, optional unrestricted double ty = 0, optional unrestricted double tz = 0);
|
||||
DOMMatrix scaleSelf(optional unrestricted double scaleX = 1, optional unrestricted double scaleY, optional unrestricted double scaleZ = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0);
|
||||
DOMMatrix scale3dSelf(optional unrestricted double scale = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0);
|
||||
// FIXME: DOMMatrix rotateSelf(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ);
|
||||
// FIXME: DOMMatrix rotateFromVectorSelf(optional unrestricted double x = 0, optional unrestricted double y = 0);
|
||||
// FIXME: DOMMatrix rotateAxisAngleSelf(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0);
|
||||
DOMMatrix rotateSelf(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ);
|
||||
DOMMatrix rotateFromVectorSelf(optional unrestricted double x = 0, optional unrestricted double y = 0);
|
||||
DOMMatrix rotateAxisAngleSelf(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0);
|
||||
DOMMatrix skewXSelf(optional unrestricted double sx = 0);
|
||||
DOMMatrix skewYSelf(optional unrestricted double sy = 0);
|
||||
DOMMatrix invertSelf();
|
||||
|
|
|
@ -307,6 +307,36 @@ JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::scale3d(Optional<double> scale, O
|
|||
return result->scale3d_self(scale, origin_x, origin_y, origin_z);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::rotate(Optional<double> rot_x, Optional<double> rot_y, Optional<double> rot_z)
|
||||
{
|
||||
// 1. Let result be the resulting matrix initialized to the values of the current matrix.
|
||||
auto result = DOMMatrix::create_from_dom_matrix_read_only(realm(), *this);
|
||||
|
||||
// 2. Perform a rotateSelf() transformation on result with the arguments rotX, rotY, rotZ.
|
||||
// 3. Return result.
|
||||
return result->rotate_self(rot_x, rot_y, rot_z);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::rotate_from_vector(Optional<double> x, Optional<double> y)
|
||||
{
|
||||
// 1. Let result be the resulting matrix initialized to the values of the current matrix.
|
||||
auto result = DOMMatrix::create_from_dom_matrix_read_only(realm(), *this);
|
||||
|
||||
// 2. Perform a rotateFromVectorSelf() transformation on result with the arguments x, y.
|
||||
// 3. Return result.
|
||||
return result->rotate_from_vector_self(x, y);
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::rotate_axis_angle(Optional<double> x, Optional<double> y, Optional<double> z, Optional<double> angle)
|
||||
{
|
||||
// 1. Let result be the resulting matrix initialized to the values of the current matrix.
|
||||
auto result = DOMMatrix::create_from_dom_matrix_read_only(realm(), *this);
|
||||
|
||||
// 2. Perform a rotateAxisAngleSelf() transformation on result with the arguments x, y, z, angle.
|
||||
// 3. Return result.
|
||||
return result->rotate_axis_angle_self(x, y, z, angle);
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-skewx
|
||||
JS::NonnullGCPtr<DOMMatrix> DOMMatrixReadOnly::skew_x(double sx) const
|
||||
{
|
||||
|
|
|
@ -89,6 +89,9 @@ public:
|
|||
JS::NonnullGCPtr<DOMMatrix> scale(Optional<double> scale_x, Optional<double> scale_y, Optional<double> scale_z, Optional<double> origin_x, Optional<double> origin_y, Optional<double> origin_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> scale_non_uniform(Optional<double> scale_x, Optional<double> scale_y);
|
||||
JS::NonnullGCPtr<DOMMatrix> scale3d(Optional<double> scale, Optional<double> origin_x, Optional<double> origin_y, Optional<double> origin_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate(Optional<double> rot_x, Optional<double> rot_y, Optional<double> rot_z);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate_from_vector(Optional<double> x, Optional<double> y);
|
||||
JS::NonnullGCPtr<DOMMatrix> rotate_axis_angle(Optional<double> x, Optional<double> y, Optional<double> z, Optional<double> angle);
|
||||
JS::NonnullGCPtr<DOMMatrix> skew_x(double sx = 0) const;
|
||||
JS::NonnullGCPtr<DOMMatrix> skew_y(double sy = 0) const;
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<DOMMatrix>> multiply(DOMMatrixInit other = {});
|
||||
|
|
|
@ -43,9 +43,9 @@ interface DOMMatrixReadOnly {
|
|||
[NewObject] DOMMatrix scale(optional unrestricted double scaleX = 1, optional unrestricted double scaleY, optional unrestricted double scaleZ = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0);
|
||||
[NewObject] DOMMatrix scaleNonUniform(optional unrestricted double scaleX = 1, optional unrestricted double scaleY = 1);
|
||||
[NewObject] DOMMatrix scale3d(optional unrestricted double scale = 1, optional unrestricted double originX = 0, optional unrestricted double originY = 0, optional unrestricted double originZ = 0);
|
||||
// FIXME: [NewObject] DOMMatrix rotate(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ);
|
||||
// FIXME: [NewObject] DOMMatrix rotateFromVector(optional unrestricted double x = 0, optional unrestricted double y = 0);
|
||||
// FIXME: [NewObject] DOMMatrix rotateAxisAngle(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0);
|
||||
[NewObject] DOMMatrix rotate(optional unrestricted double rotX = 0, optional unrestricted double rotY, optional unrestricted double rotZ);
|
||||
[NewObject] DOMMatrix rotateFromVector(optional unrestricted double x = 0, optional unrestricted double y = 0);
|
||||
[NewObject] DOMMatrix rotateAxisAngle(optional unrestricted double x = 0, optional unrestricted double y = 0, optional unrestricted double z = 0, optional unrestricted double angle = 0);
|
||||
[NewObject] DOMMatrix skewX(optional unrestricted double sx = 0);
|
||||
[NewObject] DOMMatrix skewY(optional unrestricted double sy = 0);
|
||||
[NewObject] DOMMatrix multiply(optional DOMMatrixInit other = {});
|
||||
|
|
Loading…
Reference in a new issue