diff --git a/Libraries/LibWeb/Animations/Animatable.cpp b/Libraries/LibWeb/Animations/Animatable.cpp index 189529c0fcd..8ed2c17d1ca 100644 --- a/Libraries/LibWeb/Animations/Animatable.cpp +++ b/Libraries/LibWeb/Animations/Animatable.cpp @@ -152,8 +152,25 @@ void Animatable::add_transitioned_properties(Optional pseudo auto& transition = *maybe_transition; for (size_t i = 0; i < properties.size(); i++) { size_t index_of_this_transition = transition.transition_attributes.size(); - auto delay = delays[i]->is_time() ? delays[i]->as_time().time().to_milliseconds() : 0; - auto duration = durations[i]->is_time() ? durations[i]->as_time().time().to_milliseconds() : 0; + double delay = 0.0; + if (delays[i]->is_time()) { + delay = delays[i]->as_time().time().to_milliseconds(); + } else if (delays[i]->is_calculated() && delays[i]->as_calculated().resolves_to_time()) { + auto resolved_time = delays[i]->as_calculated().resolve_time({}); + if (resolved_time.has_value()) { + delay = resolved_time.value().to_milliseconds(); + } + } + + double duration = 0.0; + if (durations[i]->is_time()) { + duration = durations[i]->as_time().time().to_milliseconds(); + } else if (durations[i]->is_calculated() && durations[i]->as_calculated().resolves_to_time()) { + auto resolved_time = durations[i]->as_calculated().resolve_time({}); + if (resolved_time.has_value()) { + duration = resolved_time.value().to_milliseconds(); + } + } auto timing_function = timing_functions[i]->is_easing() ? timing_functions[i]->as_easing().function() : CSS::EasingStyleValue::CubicBezier::ease(); auto transition_behavior = CSS::keyword_to_transition_behavior(transition_behaviors[i]->to_keyword()).value_or(CSS::TransitionBehavior::Normal); VERIFY(timing_functions[i]->is_easing()); diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index dcfcf302721..cab9bd98aad 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -1193,12 +1193,25 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti } else if (duration_value->is_keyword() && duration_value->as_keyword().keyword() == Keyword::Auto) { // We use empty optional to represent "auto". duration = {}; + } else if (duration_value->is_calculated() && duration_value->as_calculated().resolves_to_time()) { + auto resolved_time = duration_value->as_calculated().resolve_time({}); + if (resolved_time.has_value()) { + duration = resolved_time.value(); + } } } CSS::Time delay { 0, CSS::Time::Type::S }; - if (auto delay_value = cascaded_properties.property(PropertyID::AnimationDelay); delay_value && delay_value->is_time()) - delay = delay_value->as_time().time(); + if (auto delay_value = cascaded_properties.property(PropertyID::AnimationDelay); delay_value) { + if (delay_value->is_time()) { + delay = delay_value->as_time().time(); + } else if (delay_value->is_calculated() && delay_value->as_calculated().resolves_to_time()) { + auto resolved_time = delay_value->as_calculated().resolve_time({}); + if (resolved_time.has_value()) { + delay = resolved_time.value(); + } + } + } double iteration_count = 1.0; if (auto iteration_count_value = cascaded_properties.property(PropertyID::AnimationIterationCount); iteration_count_value) { @@ -1206,6 +1219,12 @@ static void apply_animation_properties(DOM::Document& document, CascadedProperti iteration_count = HUGE_VAL; else if (iteration_count_value->is_number()) iteration_count = iteration_count_value->as_number().number(); + else if (iteration_count_value->is_calculated() && iteration_count_value->as_calculated().resolves_to_number()) { + auto resolved_number = iteration_count_value->as_calculated().resolve_number({}); + if (resolved_number.has_value()) { + iteration_count = resolved_number.value(); + } + } } CSS::AnimationFillMode fill_mode { CSS::AnimationFillMode::None };