LibWeb: Support interpolating rotate values

This commit is contained in:
Tim Ledbetter 2025-07-21 23:50:04 +01:00 committed by Sam Atkins
commit 484a09d6a2
Notes: github-actions[bot] 2025-07-22 10:11:19 +00:00
3 changed files with 705 additions and 0 deletions

View file

@ -177,6 +177,89 @@ static FloatVector4 slerp(FloatVector4 const& from, FloatVector4 const& to, floa
return from * (cosf(delta * theta) - (product * w)) + to * w;
}
static RefPtr<CSSStyleValue const> interpolate_rotate(DOM::Element& element, CalculationContext calculation_context, CSSStyleValue const& a_from, CSSStyleValue const& a_to, float delta, AllowDiscrete allow_discrete)
{
if (a_from.to_keyword() == Keyword::None && a_to.to_keyword() == Keyword::None)
return a_from;
static auto zero_degrees_value = AngleStyleValue::create(Angle::make_degrees(0));
static auto zero = TransformationStyleValue::create(PropertyID::Rotate, TransformFunction::Rotate, { zero_degrees_value });
auto const& from = a_from.to_keyword() == Keyword::None ? *zero : a_from;
auto const& to = a_to.to_keyword() == Keyword::None ? *zero : a_to;
auto const& from_transform = from.as_transformation();
auto const& to_transform = to.as_transformation();
auto from_transform_type = from_transform.transform_function();
auto to_transform_type = to_transform.transform_function();
if (from_transform_type == to_transform_type && from_transform.values().size() == 1) {
auto interpolated_angle = interpolate_value(element, calculation_context, from_transform.values()[0], to_transform.values()[0], delta, allow_discrete);
if (!interpolated_angle)
return {};
return TransformationStyleValue::create(PropertyID::Rotate, from_transform_type, { *interpolated_angle.release_nonnull() });
}
FloatVector3 from_axis { 0, 0, 1 };
auto from_angle_value = from_transform.values()[0];
if (from_transform.values().size() == 4) {
from_axis.set_x(from_transform.values()[0]->as_number().number());
from_axis.set_y(from_transform.values()[1]->as_number().number());
from_axis.set_z(from_transform.values()[2]->as_number().number());
from_angle_value = from_transform.values()[3];
}
float from_angle = from_angle_value->as_angle().angle().to_radians();
FloatVector3 to_axis { 0, 0, 1 };
auto to_angle_value = to_transform.values()[0];
if (to_transform.values().size() == 4) {
to_axis.set_x(to_transform.values()[0]->as_number().number());
to_axis.set_y(to_transform.values()[1]->as_number().number());
to_axis.set_z(to_transform.values()[2]->as_number().number());
to_angle_value = to_transform.values()[3];
}
float to_angle = to_angle_value->as_angle().angle().to_radians();
auto from_axis_angle = [](FloatVector3 const& axis, float angle) -> FloatVector4 {
auto normalized = axis.normalized();
auto half_angle = angle / 2.0f;
auto sin_half_angle = sin(half_angle);
FloatVector4 result { normalized.x() * sin_half_angle, normalized.y() * sin_half_angle, normalized.z() * sin_half_angle, cosf(half_angle) };
return result;
};
struct AxisAngle {
FloatVector3 axis;
float angle;
};
auto quaternion_to_axis_angle = [](FloatVector4 const& quaternion) {
FloatVector3 axis { quaternion[0], quaternion[1], quaternion[2] };
auto epsilon = 1e-5f;
auto sin_half_angle = sqrtf(max(0.0f, 1.0f - quaternion[3] * quaternion[3]));
if (sin_half_angle < epsilon)
return AxisAngle { axis, quaternion[3] };
auto angle = 2.0f * acosf(quaternion[3]);
axis = axis * (1.0f / sin_half_angle);
return AxisAngle { axis, angle };
};
auto from_quaternion = from_axis_angle(from_axis, from_angle);
auto to_quaternion = from_axis_angle(to_axis, to_angle);
auto interpolated_quaternion = slerp(from_quaternion, to_quaternion, delta);
auto interpolated_axis_angle = quaternion_to_axis_angle(interpolated_quaternion);
auto interpolated_x_axis = NumberStyleValue::create(interpolated_axis_angle.axis.x());
auto interpolated_y_axis = NumberStyleValue::create(interpolated_axis_angle.axis.y());
auto interpolated_z_axis = NumberStyleValue::create(interpolated_axis_angle.axis.z());
auto interpolated_angle = AngleStyleValue::create(Angle::make_degrees(AK::to_degrees(interpolated_axis_angle.angle)));
return TransformationStyleValue::create(
PropertyID::Rotate,
TransformFunction::Rotate3d,
{ interpolated_x_axis, interpolated_y_axis, interpolated_z_axis, interpolated_angle });
}
ValueComparingRefPtr<CSSStyleValue const> interpolate_property(DOM::Element& element, PropertyID property_id, CSSStyleValue const& a_from, CSSStyleValue const& a_to, float delta, AllowDiscrete allow_discrete)
{
auto from = with_keyword_values_resolved(element, property_id, a_from);
@ -273,6 +356,12 @@ ValueComparingRefPtr<CSSStyleValue const> interpolate_property(DOM::Element& ele
return interpolate_discrete(from, to, delta, allow_discrete);
}
if (property_id == PropertyID::Rotate) {
if (auto result = interpolate_rotate(element, calculation_context, from, to, delta, allow_discrete))
return result;
return interpolate_discrete(from, to, delta, allow_discrete);
}
// FIXME: Handle all custom animatable properties
[[fallthrough]];
}

View file

@ -0,0 +1,366 @@
Harness status: OK
Found 360 tests
238 Pass
122 Fail
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (-1) should be [20deg]
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (0) should be [100deg]
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (0.125) should be [110deg]
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (0.875) should be [170deg]
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (1) should be [180deg]
Pass CSS Transitions: property <rotate> from [100deg] to [180deg] at (2) should be [260deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (-1) should be [20deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (0) should be [100deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (0.125) should be [110deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (0.875) should be [170deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (1) should be [180deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [180deg] at (2) should be [260deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (-1) should be [20deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (0) should be [100deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (0.125) should be [110deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (0.875) should be [170deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (1) should be [180deg]
Pass CSS Animations: property <rotate> from [100deg] to [180deg] at (2) should be [260deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (-1) should be [20deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (0) should be [100deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (0.125) should be [110deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (0.875) should be [170deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (1) should be [180deg]
Pass Web Animations: property <rotate> from [100deg] to [180deg] at (2) should be [260deg]
Pass CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (-1) should be [0.447214 -0.447214 0.774597 104.478deg]
Pass CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (0) should be [45deg]
Pass CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.125) should be [-0.136456 0.136456 0.981203 40.6037deg]
Pass CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.875) should be [-0.70246 0.70246 0.114452 53.1994deg]
Pass CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (1) should be [-0.71 0.71 0 60deg]
Fail CSS Transitions: property <rotate> from [45deg] to [-1 1 0 60deg] at (2) should be [-0.637897 0.637897 -0.431479 124.975deg]
Pass CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (-1) should be [0.447214 -0.447214 0.774597 104.478deg]
Pass CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (0) should be [45deg]
Pass CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.125) should be [-0.136456 0.136456 0.981203 40.6037deg]
Pass CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.875) should be [-0.70246 0.70246 0.114452 53.1994deg]
Pass CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (1) should be [-0.71 0.71 0 60deg]
Fail CSS Transitions with transition: all: property <rotate> from [45deg] to [-1 1 0 60deg] at (2) should be [-0.637897 0.637897 -0.431479 124.975deg]
Pass CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (-1) should be [0.447214 -0.447214 0.774597 104.478deg]
Pass CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0) should be [45deg]
Pass CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.125) should be [-0.136456 0.136456 0.981203 40.6037deg]
Pass CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.875) should be [-0.70246 0.70246 0.114452 53.1994deg]
Pass CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (1) should be [-0.71 0.71 0 60deg]
Fail CSS Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (2) should be [-0.637897 0.637897 -0.431479 124.975deg]
Pass Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (-1) should be [0.447214 -0.447214 0.774597 104.478deg]
Pass Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0) should be [45deg]
Pass Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.125) should be [-0.136456 0.136456 0.981203 40.6037deg]
Pass Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (0.875) should be [-0.70246 0.70246 0.114452 53.1994deg]
Pass Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (1) should be [-0.71 0.71 0 60deg]
Fail Web Animations: property <rotate> from [45deg] to [-1 1 0 60deg] at (2) should be [-0.637897 0.637897 -0.431479 124.975deg]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (-1) should be [0.5 -0.57 0.65 -400grad]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (0) should be [0.5 -0.57 0.65 0deg]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (0.125) should be [0.5 -0.57 0.65 50grad]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (0.875) should be [0.5 -0.57 0.65 350grad]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (1) should be [0.5 -0.57 0.65 400grad]
Fail CSS Transitions: property <rotate> from [none] to [7 -8 9 400grad] at (2) should be [0.5 -0.57 0.65 800grad]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (-1) should be [0.5 -0.57 0.65 -400grad]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (0) should be [0.5 -0.57 0.65 0deg]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (0.125) should be [0.5 -0.57 0.65 50grad]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (0.875) should be [0.5 -0.57 0.65 350grad]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (1) should be [0.5 -0.57 0.65 400grad]
Fail CSS Transitions with transition: all: property <rotate> from [none] to [7 -8 9 400grad] at (2) should be [0.5 -0.57 0.65 800grad]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (-1) should be [0.5 -0.57 0.65 -400grad]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0) should be [0.5 -0.57 0.65 0deg]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0.125) should be [0.5 -0.57 0.65 50grad]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0.875) should be [0.5 -0.57 0.65 350grad]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (1) should be [0.5 -0.57 0.65 400grad]
Fail CSS Animations: property <rotate> from [none] to [7 -8 9 400grad] at (2) should be [0.5 -0.57 0.65 800grad]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (-1) should be [0.5 -0.57 0.65 -400grad]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0) should be [0.5 -0.57 0.65 0deg]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0.125) should be [0.5 -0.57 0.65 50grad]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (0.875) should be [0.5 -0.57 0.65 350grad]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (1) should be [0.5 -0.57 0.65 400grad]
Fail Web Animations: property <rotate> from [none] to [7 -8 9 400grad] at (2) should be [0.5 -0.57 0.65 800grad]
Pass CSS Transitions: property <rotate> from [none] to [none] at (-1) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [none] at (0) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [none] at (0.125) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [none] at (0.875) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [none] at (1) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [none] at (2) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (-1) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (0) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (0.125) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (0.875) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (1) should be [none]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [none] at (2) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (-1) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (0) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (0.125) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (0.875) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (1) should be [none]
Pass CSS Animations: property <rotate> from [none] to [none] at (2) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (-1) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (0) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (0.125) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (0.875) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (1) should be [none]
Pass Web Animations: property <rotate> from [none] to [none] at (2) should be [none]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (-1) should be [-30deg]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (0) should be [0deg]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (1) should be [30deg]
Pass CSS Transitions: property <rotate> from [none] to [30deg] at (2) should be [60deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (-1) should be [-30deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (0) should be [0deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (1) should be [30deg]
Pass CSS Transitions with transition: all: property <rotate> from [none] to [30deg] at (2) should be [60deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (-1) should be [-30deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (0) should be [0deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (1) should be [30deg]
Pass CSS Animations: property <rotate> from [none] to [30deg] at (2) should be [60deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (-1) should be [-30deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (0) should be [0deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (0.25) should be [7.5deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (0.75) should be [22.5deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (1) should be [30deg]
Pass Web Animations: property <rotate> from [none] to [30deg] at (2) should be [60deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (-1) should be [-10deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (0) should be [10deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (0.25) should be [15deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (0.75) should be [25deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (1) should be [30deg]
Pass CSS Transitions: property <rotate> from neutral to [30deg] at (2) should be [50deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (-1) should be [-10deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (0) should be [10deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (0.25) should be [15deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (0.75) should be [25deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (1) should be [30deg]
Pass CSS Transitions with transition: all: property <rotate> from neutral to [30deg] at (2) should be [50deg]
Fail CSS Animations: property <rotate> from neutral to [30deg] at (-1) should be [-10deg]
Fail CSS Animations: property <rotate> from neutral to [30deg] at (0) should be [10deg]
Fail CSS Animations: property <rotate> from neutral to [30deg] at (0.25) should be [15deg]
Fail CSS Animations: property <rotate> from neutral to [30deg] at (0.75) should be [25deg]
Pass CSS Animations: property <rotate> from neutral to [30deg] at (1) should be [30deg]
Fail CSS Animations: property <rotate> from neutral to [30deg] at (2) should be [50deg]
Fail Web Animations: property <rotate> from neutral to [30deg] at (-1) should be [-10deg]
Fail Web Animations: property <rotate> from neutral to [30deg] at (0) should be [10deg]
Fail Web Animations: property <rotate> from neutral to [30deg] at (0.25) should be [15deg]
Fail Web Animations: property <rotate> from neutral to [30deg] at (0.75) should be [25deg]
Pass Web Animations: property <rotate> from neutral to [30deg] at (1) should be [30deg]
Fail Web Animations: property <rotate> from neutral to [30deg] at (2) should be [50deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (-1) should be [-90deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (0) should be [90deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (0.25) should be [135deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (0.75) should be [225deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (1) should be [270deg]
Pass CSS Transitions: property <rotate> from [inherit] to [270deg] at (2) should be [450deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (-1) should be [-90deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (0) should be [90deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (0.25) should be [135deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (0.75) should be [225deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (1) should be [270deg]
Pass CSS Transitions with transition: all: property <rotate> from [inherit] to [270deg] at (2) should be [450deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (-1) should be [-90deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (0) should be [90deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (0.25) should be [135deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (0.75) should be [225deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (1) should be [270deg]
Pass CSS Animations: property <rotate> from [inherit] to [270deg] at (2) should be [450deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (-1) should be [-90deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (0) should be [90deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (0.25) should be [135deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (0.75) should be [225deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (1) should be [270deg]
Pass Web Animations: property <rotate> from [inherit] to [270deg] at (2) should be [450deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (-1) should be [-30deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (0) should be [0deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (1) should be [30deg]
Pass CSS Transitions: property <rotate> from [unset] to [30deg] at (2) should be [60deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (-1) should be [-30deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (0) should be [0deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (1) should be [30deg]
Pass CSS Transitions with transition: all: property <rotate> from [unset] to [30deg] at (2) should be [60deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (-1) should be [-30deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (0) should be [0deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (0.25) should be [7.5deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (0.75) should be [22.5deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (1) should be [30deg]
Pass CSS Animations: property <rotate> from [unset] to [30deg] at (2) should be [60deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (-1) should be [-30deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (0) should be [0deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (0.25) should be [7.5deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (0.75) should be [22.5deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (1) should be [30deg]
Pass Web Animations: property <rotate> from [unset] to [30deg] at (2) should be [60deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (-1) should be [300deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (0) should be [100deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (0.25) should be [50deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (0.75) should be [-50deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (1) should be [-100deg]
Pass CSS Transitions: property <rotate> from [100deg] to [-100deg] at (2) should be [-300deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (-1) should be [300deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (0) should be [100deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (0.25) should be [50deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (0.75) should be [-50deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (1) should be [-100deg]
Pass CSS Transitions with transition: all: property <rotate> from [100deg] to [-100deg] at (2) should be [-300deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (-1) should be [300deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (0) should be [100deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (0.25) should be [50deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (0.75) should be [-50deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (1) should be [-100deg]
Pass CSS Animations: property <rotate> from [100deg] to [-100deg] at (2) should be [-300deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (-1) should be [300deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (0) should be [100deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (0.25) should be [50deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (0.75) should be [-50deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (1) should be [-100deg]
Pass Web Animations: property <rotate> from [100deg] to [-100deg] at (2) should be [-300deg]
Pass CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (-1) should be [0 1 0 300deg]
Pass CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0) should be [0 1 0 100deg]
Pass CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.25) should be [0 1 0 50deg]
Fail CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.75) should be [0 1 0 -50deg]
Fail CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (1) should be [0 1 0 -100deg]
Fail CSS Transitions: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (2) should be [0 1 0 -300deg]
Pass CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (-1) should be [0 1 0 300deg]
Pass CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0) should be [0 1 0 100deg]
Pass CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.25) should be [0 1 0 50deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.75) should be [0 1 0 -50deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (1) should be [0 1 0 -100deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (2) should be [0 1 0 -300deg]
Pass CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (-1) should be [0 1 0 300deg]
Pass CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0) should be [0 1 0 100deg]
Pass CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.25) should be [0 1 0 50deg]
Fail CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.75) should be [0 1 0 -50deg]
Fail CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (1) should be [0 1 0 -100deg]
Fail CSS Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (2) should be [0 1 0 -300deg]
Pass Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (-1) should be [0 1 0 300deg]
Pass Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0) should be [0 1 0 100deg]
Pass Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.25) should be [0 1 0 50deg]
Fail Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (0.75) should be [0 1 0 -50deg]
Fail Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (1) should be [0 1 0 -100deg]
Fail Web Animations: property <rotate> from [0 1 0 100deg] to [0 1 0 -100deg] at (2) should be [0 1 0 -300deg]
Pass CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (-1) should be [0.22 -0.55 0.8 300deg]
Pass CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0) should be [0.22 -0.55 0.8 100deg]
Pass CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.25) should be [0.22 -0.55 0.8 50deg]
Fail CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.75) should be [0.22 -0.55 0.8 -50deg]
Fail CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (1) should be [0.22 -0.55 0.8 -100deg]
Fail CSS Transitions: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (2) should be [0.22 -0.55 0.8 -300deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (-1) should be [0.22 -0.55 0.8 300deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0) should be [0.22 -0.55 0.8 100deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.25) should be [0.22 -0.55 0.8 50deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.75) should be [0.22 -0.55 0.8 -50deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (1) should be [0.22 -0.55 0.8 -100deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (2) should be [0.22 -0.55 0.8 -300deg]
Pass CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (-1) should be [0.22 -0.55 0.8 300deg]
Pass CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0) should be [0.22 -0.55 0.8 100deg]
Pass CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.25) should be [0.22 -0.55 0.8 50deg]
Fail CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.75) should be [0.22 -0.55 0.8 -50deg]
Fail CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (1) should be [0.22 -0.55 0.8 -100deg]
Fail CSS Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (2) should be [0.22 -0.55 0.8 -300deg]
Pass Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (-1) should be [0.22 -0.55 0.8 300deg]
Pass Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0) should be [0.22 -0.55 0.8 100deg]
Pass Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.25) should be [0.22 -0.55 0.8 50deg]
Fail Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (0.75) should be [0.22 -0.55 0.8 -50deg]
Fail Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (1) should be [0.22 -0.55 0.8 -100deg]
Fail Web Animations: property <rotate> from [1 -2.5 3.64 100deg] to [1 -2.5 3.64 -100deg] at (2) should be [0.22 -0.55 0.8 -300deg]
Fail CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (-1) should be [0 1 0 -10deg]
Fail CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0) should be [0 1 0 0deg]
Pass CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.25) should be [0 1 0 2.5deg]
Pass CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.75) should be [0 1 0 7.5deg]
Pass CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (1) should be [0 1 0 10deg]
Pass CSS Transitions: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (2) should be [0 1 0 20deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (-1) should be [0 1 0 -10deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0) should be [0 1 0 0deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.25) should be [0 1 0 2.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.75) should be [0 1 0 7.5deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (1) should be [0 1 0 10deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (2) should be [0 1 0 20deg]
Fail CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (-1) should be [0 1 0 -10deg]
Fail CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0) should be [0 1 0 0deg]
Pass CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.25) should be [0 1 0 2.5deg]
Pass CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.75) should be [0 1 0 7.5deg]
Pass CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (1) should be [0 1 0 10deg]
Pass CSS Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (2) should be [0 1 0 20deg]
Fail Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (-1) should be [0 1 0 -10deg]
Fail Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0) should be [0 1 0 0deg]
Pass Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.25) should be [0 1 0 2.5deg]
Pass Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (0.75) should be [0 1 0 7.5deg]
Pass Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (1) should be [0 1 0 10deg]
Pass Web Animations: property <rotate> from [1 0 0 0deg] to [0 1 0 10deg] at (2) should be [0 1 0 20deg]
Fail CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (-1) should be [0.67 -0.06 -0.74 124.97deg]
Pass CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0) should be [0.71 0.71 0 90deg]
Pass CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.25) should be [0.54 0.8 0.26 94.83deg]
Pass CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.75) should be [0.17 0.78 0.61 118.68deg]
Pass CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (1) should be [0 0.71 0.71 135deg]
Pass CSS Transitions: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (2) should be [-0.52 0.29 0.81 208.96deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (-1) should be [0.67 -0.06 -0.74 124.97deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0) should be [0.71 0.71 0 90deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.25) should be [0.54 0.8 0.26 94.83deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.75) should be [0.17 0.78 0.61 118.68deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (1) should be [0 0.71 0.71 135deg]
Pass CSS Transitions with transition: all: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (2) should be [-0.52 0.29 0.81 208.96deg]
Fail CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (-1) should be [0.67 -0.06 -0.74 124.97deg]
Pass CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0) should be [0.71 0.71 0 90deg]
Pass CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.25) should be [0.54 0.8 0.26 94.83deg]
Pass CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.75) should be [0.17 0.78 0.61 118.68deg]
Pass CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (1) should be [0 0.71 0.71 135deg]
Pass CSS Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (2) should be [-0.52 0.29 0.81 208.96deg]
Fail Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (-1) should be [0.67 -0.06 -0.74 124.97deg]
Pass Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0) should be [0.71 0.71 0 90deg]
Pass Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.25) should be [0.54 0.8 0.26 94.83deg]
Pass Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (0.75) should be [0.17 0.78 0.61 118.68deg]
Pass Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (1) should be [0 0.71 0.71 135deg]
Pass Web Animations: property <rotate> from [1 1 0 90deg] to [0 1 1 135deg] at (2) should be [-0.52 0.29 0.81 208.96deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (-1) should be [1 0 0 -450deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0) should be [1 0 0 0deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.25) should be [1 0 0 112.5deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.75) should be [1 0 0 337.5deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (1) should be [1 0 0 450deg]
Fail CSS Transitions: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (2) should be [1 0 0 900deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (-1) should be [1 0 0 -450deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0) should be [1 0 0 0deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.25) should be [1 0 0 112.5deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.75) should be [1 0 0 337.5deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (1) should be [1 0 0 450deg]
Fail CSS Transitions with transition: all: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (2) should be [1 0 0 900deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (-1) should be [1 0 0 -450deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0) should be [1 0 0 0deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.25) should be [1 0 0 112.5deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.75) should be [1 0 0 337.5deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (1) should be [1 0 0 450deg]
Fail CSS Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (2) should be [1 0 0 900deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (-1) should be [1 0 0 -450deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0) should be [1 0 0 0deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.25) should be [1 0 0 112.5deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (0.75) should be [1 0 0 337.5deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (1) should be [1 0 0 450deg]
Fail Web Animations: property <rotate> from [0 1 0 0deg] to [1 0 0 450deg] at (2) should be [1 0 0 900deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (-1) should be [1 0 0 900deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0) should be [1 0 0 450deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.25) should be [1 0 0 337.5deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.75) should be [1 0 0 112.5deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (1) should be [1 0 0 0deg]
Fail CSS Transitions: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (2) should be [1 0 0 -450deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (-1) should be [1 0 0 900deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0) should be [1 0 0 450deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.25) should be [1 0 0 337.5deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.75) should be [1 0 0 112.5deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (1) should be [1 0 0 0deg]
Fail CSS Transitions with transition: all: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (2) should be [1 0 0 -450deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (-1) should be [1 0 0 900deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0) should be [1 0 0 450deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.25) should be [1 0 0 337.5deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.75) should be [1 0 0 112.5deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (1) should be [1 0 0 0deg]
Fail CSS Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (2) should be [1 0 0 -450deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (-1) should be [1 0 0 900deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0) should be [1 0 0 450deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.25) should be [1 0 0 337.5deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (0.75) should be [1 0 0 112.5deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (1) should be [1 0 0 0deg]
Fail Web Animations: property <rotate> from [1 0 0 450deg] to [0 1 0 0deg] at (2) should be [1 0 0 -450deg]

View file

@ -0,0 +1,250 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>rotate interpolation</title>
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-rotate">
<meta name="assert" content="rotate supports animation.">
<meta name="timeout" content="long">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/interpolation-testcommon.js"></script>
</head>
<style>
.parent {
rotate: 90deg;
}
.target {
width: 40px;
height: 20px;
background-color: grey;
rotate: 10deg;
}
.expected {
background-color: green;
}
</style>
<template id="target-template">
<div class="parent">
<div class="target">Text</div>
</div>
</template>
<body>
<script>
test_interpolation({
property: 'rotate',
from: '100deg',
to: '180deg',
}, [
{at: -1, expect: '20deg'},
{at: 0, expect: '100deg'},
{at: 0.125, expect: '110deg'},
{at: 0.875, expect: '170deg'},
{at: 1, expect: '180deg'},
{at: 2, expect: '260deg'}
]);
test_interpolation({
property: 'rotate',
from: '45deg',
to: '-1 1 0 60deg',
}, [
{at: -1, expect: '0.447214 -0.447214 0.774597 104.478deg'},
{at: 0, expect: '45deg'},
{at: 0.125, expect: '-0.136456 0.136456 0.981203 40.6037deg'},
{at: 0.875, expect: '-0.70246 0.70246 0.114452 53.1994deg'},
{at: 1, expect: '-0.71 0.71 0 60deg'},
{at: 2, expect: '-0.637897 0.637897 -0.431479 124.975deg'}
]);
test_interpolation({
property: 'rotate',
from: 'none',
to: '7 -8 9 400grad',
}, [
{at: -1, expect: '0.5 -0.57 0.65 -400grad'},
{at: 0, expect: '0.5 -0.57 0.65 0deg'},
{at: 0.125, expect: '0.5 -0.57 0.65 50grad'},
{at: 0.875, expect: '0.5 -0.57 0.65 350grad'},
{at: 1, expect: '0.5 -0.57 0.65 400grad'},
{at: 2, expect: '0.5 -0.57 0.65 800grad'}
]);
test_interpolation({
property: 'rotate',
from: 'none',
to: 'none',
}, [
{at: -1, expect: 'none'},
{at: 0, expect: 'none'},
{at: 0.125, expect: 'none'},
{at: 0.875, expect: 'none'},
{at: 1, expect: 'none'},
{at: 2, expect: 'none'}
]);
test_interpolation({
property: 'rotate',
from: 'none',
to: '30deg',
}, [
{at: -1, expect: '-30deg'},
{at: 0, expect: '0deg'},
{at: 0.25, expect: '7.5deg'},
{at: 0.75, expect: '22.5deg'},
{at: 1, expect: '30deg'},
{at: 2, expect: '60deg'},
]);
test_interpolation({
property: 'rotate',
from: neutralKeyframe,
to: '30deg',
}, [
{at: -1, expect: '-10deg'},
{at: 0, expect: '10deg'},
{at: 0.25, expect: '15deg'},
{at: 0.75, expect: '25deg'},
{at: 1, expect: '30deg'},
{at: 2, expect: '50deg'},
]);
test_interpolation({
property: 'rotate',
from: 'inherit',
to: '270deg',
}, [
{at: -1, expect: '-90deg'},
{at: 0, expect: '90deg'},
{at: 0.25, expect: '135deg'},
{at: 0.75, expect: '225deg'},
{at: 1, expect: '270deg'},
{at: 2, expect: '450deg'},
]);
test_interpolation({
property: 'rotate',
from: 'unset',
to: '30deg',
}, [
{at: -1, expect: '-30deg'},
{at: 0, expect: '0deg'},
{at: 0.25, expect: '7.5deg'},
{at: 0.75, expect: '22.5deg'},
{at: 1, expect: '30deg'},
{at: 2, expect: '60deg'},
]);
test_interpolation({
property: 'rotate',
from: '100deg',
to: '-100deg',
}, [
{at: -1, expect: '300deg'},
{at: 0, expect: '100deg'},
{at: 0.25, expect: '50deg'},
{at: 0.75, expect: '-50deg'},
{at: 1, expect: '-100deg'},
{at: 2, expect: '-300deg'},
]);
test_interpolation({
property: 'rotate',
from: '0 1 0 100deg',
to: '0 1 0 -100deg',
}, [
{at: -1, expect: '0 1 0 300deg'},
{at: 0, expect: '0 1 0 100deg'},
{at: 0.25, expect: '0 1 0 50deg'},
{at: 0.75, expect: '0 1 0 -50deg'},
{at: 1, expect: '0 1 0 -100deg'},
{at: 2, expect: '0 1 0 -300deg'},
]);
test_interpolation({
property: 'rotate',
from: '1 -2.5 3.64 100deg',
to: '1 -2.5 3.64 -100deg',
}, [
{at: -1, expect: '0.22 -0.55 0.8 300deg'},
{at: 0, expect: '0.22 -0.55 0.8 100deg'},
{at: 0.25, expect: '0.22 -0.55 0.8 50deg'},
{at: 0.75, expect: '0.22 -0.55 0.8 -50deg'},
{at: 1, expect: '0.22 -0.55 0.8 -100deg'},
{at: 2, expect: '0.22 -0.55 0.8 -300deg'},
]);
// The rotation angle gets interpolated numerically and the rotation vector
// of the non-zero angle is used or (0, 0, 1) if both angles are zero.
// So, we have to convert "1 0 0 0deg" into "0 1 0 0deg", and apply the same
// concept for other test cases.
// https://drafts.csswg.org/css-transforms-2/#interpolation-of-transform-functions
test_interpolation({
property: 'rotate',
from: '1 0 0 0deg',
to: '0 1 0 10deg',
}, [
{at: -1, expect: '0 1 0 -10deg'},
{at: 0, expect: '0 1 0 0deg'},
{at: 0.25, expect: '0 1 0 2.5deg'},
{at: 0.75, expect: '0 1 0 7.5deg'},
{at: 1, expect: '0 1 0 10deg'},
{at: 2, expect: '0 1 0 20deg'},
]);
test_interpolation({
property: 'rotate',
from: '1 1 0 90deg',
to: '0 1 1 135deg',
}, [
{at: -1, expect: '0.67 -0.06 -0.74 124.97deg'},
{at: 0, expect: '0.71 0.71 0 90deg'},
{at: 0.25, expect: '0.54 0.8 0.26 94.83deg'},
{at: 0.75, expect: '0.17 0.78 0.61 118.68deg'},
{at: 1, expect: '0 0.71 0.71 135deg'},
// The result in Blink is '0.52 -0.29 -0.81 151.04deg', and the result in
// Gecko is `-0.52 0.29 0.8 208.96deg`. Both of them can be represented as the
// same 3d rotation (but by an opposite direction vector and angle).
// The spec only mentions we should use Slerp to do interpolation for rotate
// property, but it seems the implementation detail for extrapolation are
// different (because this is not in the range of [0, 1]).
// For now, we make both results pass because their rendering results are the
// same.
{at: 2, expect: '0.52 -0.29 -0.81 151.04deg',
option: '-0.52 0.29 0.81 208.96deg'},
]);
test_interpolation({
property: 'rotate',
from: '0 1 0 0deg',
to: '1 0 0 450deg',
}, [
{at: -1, expect: '1 0 0 -450deg'},
{at: 0, expect: '1 0 0 0deg'},
{at: 0.25, expect: '1 0 0 112.5deg'},
{at: 0.75, expect: '1 0 0 337.5deg'},
{at: 1, expect: '1 0 0 450deg'},
{at: 2, expect: '1 0 0 900deg'},
]);
test_interpolation({
property: 'rotate',
from: '1 0 0 450deg',
to: '0 1 0 0deg',
}, [
{at: -1, expect: '1 0 0 900deg'},
{at: 0, expect: '1 0 0 450deg'},
{at: 0.25, expect: '1 0 0 337.5deg'},
{at: 0.75, expect: '1 0 0 112.5deg'},
{at: 1, expect: '1 0 0 0deg'},
{at: 2, expect: '1 0 0 -450deg'},
]);
</script>
</body>
</html>