mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:27:35 +00:00
LibWeb: Move easing parsing code out into a dedicated function
This will be used outside of StyleComputer
This commit is contained in:
parent
c8b9c137a1
commit
b33bb0997a
3 changed files with 85 additions and 81 deletions
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
#include <AK/BinarySearch.h>
|
#include <AK/BinarySearch.h>
|
||||||
#include <LibWeb/Animations/TimingFunction.h>
|
#include <LibWeb/Animations/TimingFunction.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace Web::Animations {
|
namespace Web::Animations {
|
||||||
|
@ -164,6 +167,80 @@ double StepsTimingFunction::operator()(double input_progress, bool before_flag)
|
||||||
return current_step / jumps;
|
return current_step / jumps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimingFunction TimingFunction::from_easing_style_value(CSS::EasingStyleValue const& easing_value)
|
||||||
|
{
|
||||||
|
switch (easing_value.easing_function()) {
|
||||||
|
case CSS::EasingFunction::Linear:
|
||||||
|
return Animations::linear_timing_function;
|
||||||
|
case CSS::EasingFunction::Ease:
|
||||||
|
return Animations::ease_timing_function;
|
||||||
|
case CSS::EasingFunction::EaseIn:
|
||||||
|
return Animations::ease_in_timing_function;
|
||||||
|
case CSS::EasingFunction::EaseOut:
|
||||||
|
return Animations::ease_out_timing_function;
|
||||||
|
case CSS::EasingFunction::EaseInOut:
|
||||||
|
return Animations::ease_in_out_timing_function;
|
||||||
|
case CSS::EasingFunction::CubicBezier: {
|
||||||
|
auto values = easing_value.values();
|
||||||
|
return {
|
||||||
|
Animations::CubicBezierTimingFunction {
|
||||||
|
values[0]->as_number().number(),
|
||||||
|
values[1]->as_number().number(),
|
||||||
|
values[2]->as_number().number(),
|
||||||
|
values[3]->as_number().number(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case CSS::EasingFunction::Steps: {
|
||||||
|
auto values = easing_value.values();
|
||||||
|
auto jump_at_start = false;
|
||||||
|
auto jump_at_end = true;
|
||||||
|
|
||||||
|
if (values.size() > 1) {
|
||||||
|
auto identifier = values[1]->to_identifier();
|
||||||
|
switch (identifier) {
|
||||||
|
case CSS::ValueID::JumpStart:
|
||||||
|
case CSS::ValueID::Start:
|
||||||
|
jump_at_start = true;
|
||||||
|
jump_at_end = false;
|
||||||
|
break;
|
||||||
|
case CSS::ValueID::JumpEnd:
|
||||||
|
case CSS::ValueID::End:
|
||||||
|
jump_at_start = false;
|
||||||
|
jump_at_end = true;
|
||||||
|
break;
|
||||||
|
case CSS::ValueID::JumpNone:
|
||||||
|
jump_at_start = false;
|
||||||
|
jump_at_end = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Animations::TimingFunction { Animations::StepsTimingFunction {
|
||||||
|
.number_of_steps = static_cast<size_t>(max(values[0]->as_integer().integer(), !(jump_at_end && jump_at_start) ? 1 : 0)),
|
||||||
|
.jump_at_start = jump_at_start,
|
||||||
|
.jump_at_end = jump_at_end,
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
case CSS::EasingFunction::StepEnd:
|
||||||
|
return Animations::TimingFunction { Animations::StepsTimingFunction {
|
||||||
|
.number_of_steps = 1,
|
||||||
|
.jump_at_start = false,
|
||||||
|
.jump_at_end = true,
|
||||||
|
} };
|
||||||
|
case CSS::EasingFunction::StepStart:
|
||||||
|
return Animations::TimingFunction { Animations::StepsTimingFunction {
|
||||||
|
.number_of_steps = 1,
|
||||||
|
.jump_at_start = true,
|
||||||
|
.jump_at_end = false,
|
||||||
|
} };
|
||||||
|
default:
|
||||||
|
return Animations::ease_timing_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double TimingFunction::operator()(double input_progress, bool before_flag) const
|
double TimingFunction::operator()(double input_progress, bool before_flag) const
|
||||||
{
|
{
|
||||||
return function.visit([&](auto const& f) { return f(input_progress, before_flag); });
|
return function.visit([&](auto const& f) { return f(input_progress, before_flag); });
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
class EasingStyleValue;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Web::Animations {
|
namespace Web::Animations {
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-easing-1/#the-linear-easing-function
|
// https://www.w3.org/TR/css-easing-1/#the-linear-easing-function
|
||||||
|
@ -45,6 +49,8 @@ struct StepsTimingFunction {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TimingFunction {
|
struct TimingFunction {
|
||||||
|
static TimingFunction from_easing_style_value(CSS::EasingStyleValue const&);
|
||||||
|
|
||||||
Variant<LinearTimingFunction, CubicBezierTimingFunction, StepsTimingFunction> function;
|
Variant<LinearTimingFunction, CubicBezierTimingFunction, StepsTimingFunction> function;
|
||||||
|
|
||||||
double operator()(double input_progress, bool before_flag) const;
|
double operator()(double input_progress, bool before_flag) const;
|
||||||
|
|
|
@ -1060,89 +1060,10 @@ ErrorOr<void> StyleComputer::compute_cascaded_values(StyleProperties& style, DOM
|
||||||
}
|
}
|
||||||
|
|
||||||
Animations::TimingFunction timing_function = Animations::ease_timing_function;
|
Animations::TimingFunction timing_function = Animations::ease_timing_function;
|
||||||
if (auto timing_property = style.maybe_null_property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing()) {
|
if (auto timing_property = style.maybe_null_property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing())
|
||||||
auto& easing_value = timing_property->as_easing();
|
timing_function = Animations::TimingFunction::from_easing_style_value(timing_property->as_easing());
|
||||||
switch (easing_value.easing_function()) {
|
|
||||||
case EasingFunction::Linear:
|
|
||||||
timing_function = Animations::linear_timing_function;
|
|
||||||
break;
|
|
||||||
case EasingFunction::Ease:
|
|
||||||
timing_function = Animations::ease_timing_function;
|
|
||||||
break;
|
|
||||||
case EasingFunction::EaseIn:
|
|
||||||
timing_function = Animations::ease_in_timing_function;
|
|
||||||
break;
|
|
||||||
case EasingFunction::EaseOut:
|
|
||||||
timing_function = Animations::ease_out_timing_function;
|
|
||||||
break;
|
|
||||||
case EasingFunction::EaseInOut:
|
|
||||||
timing_function = Animations::ease_in_out_timing_function;
|
|
||||||
break;
|
|
||||||
case EasingFunction::CubicBezier: {
|
|
||||||
auto values = easing_value.values();
|
|
||||||
timing_function = {
|
|
||||||
Animations::CubicBezierTimingFunction {
|
|
||||||
values[0]->as_number().number(),
|
|
||||||
values[1]->as_number().number(),
|
|
||||||
values[2]->as_number().number(),
|
|
||||||
values[3]->as_number().number(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EasingFunction::Steps: {
|
|
||||||
auto values = easing_value.values();
|
|
||||||
auto jump_at_start = false;
|
|
||||||
auto jump_at_end = true;
|
|
||||||
|
|
||||||
if (values.size() > 1) {
|
|
||||||
auto identifier = values[1]->to_identifier();
|
|
||||||
switch (identifier) {
|
|
||||||
case ValueID::JumpStart:
|
|
||||||
case ValueID::Start:
|
|
||||||
jump_at_start = true;
|
|
||||||
jump_at_end = false;
|
|
||||||
break;
|
|
||||||
case ValueID::JumpEnd:
|
|
||||||
case ValueID::End:
|
|
||||||
jump_at_start = false;
|
|
||||||
jump_at_end = true;
|
|
||||||
break;
|
|
||||||
case ValueID::JumpNone:
|
|
||||||
jump_at_start = false;
|
|
||||||
jump_at_end = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timing_function = Animations::TimingFunction { Animations::StepsTimingFunction {
|
|
||||||
.number_of_steps = static_cast<size_t>(max(values[0]->as_integer().integer(), !(jump_at_end && jump_at_start) ? 1 : 0)),
|
|
||||||
.jump_at_start = jump_at_start,
|
|
||||||
.jump_at_end = jump_at_end,
|
|
||||||
} };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EasingFunction::StepEnd:
|
|
||||||
timing_function = Animations::TimingFunction { Animations::StepsTimingFunction {
|
|
||||||
.number_of_steps = 1,
|
|
||||||
.jump_at_start = false,
|
|
||||||
.jump_at_end = true,
|
|
||||||
} };
|
|
||||||
break;
|
|
||||||
case EasingFunction::StepStart:
|
|
||||||
timing_function = Animations::TimingFunction { Animations::StepsTimingFunction {
|
|
||||||
.number_of_steps = 1,
|
|
||||||
.jump_at_start = true,
|
|
||||||
.jump_at_end = false,
|
|
||||||
} };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& realm = element.realm();
|
auto& realm = element.realm();
|
||||||
|
|
||||||
auto effect = Animations::KeyframeEffect::create(realm);
|
auto effect = Animations::KeyframeEffect::create(realm);
|
||||||
auto iteration_duration = duration.has_value()
|
auto iteration_duration = duration.has_value()
|
||||||
? Variant<double, String> { duration.release_value().to_milliseconds() }
|
? Variant<double, String> { duration.release_value().to_milliseconds() }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue