LibWeb: Store property transitions in Animatable

Co-authored-by: Sam Atkins <sam@ladybird.org>
This commit is contained in:
Matthew Olsson 2024-07-03 14:21:19 +00:00 committed by Andreas Kling
commit 392510c631
Notes: github-actions[bot] 2024-09-22 04:42:58 +00:00
2 changed files with 86 additions and 2 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>.
* Copyright (c) 2024, Matthew Olsson <mattco@serenityos.org>
* Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -8,6 +9,9 @@
#include <LibWeb/Animations/Animatable.h>
#include <LibWeb/Animations/Animation.h>
#include <LibWeb/Animations/DocumentTimeline.h>
#include <LibWeb/CSS/CSSTransition.h>
#include <LibWeb/CSS/StyleValues/EasingStyleValue.h>
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Element.h>
@ -99,6 +103,57 @@ void Animatable::disassociate_with_animation(JS::NonnullGCPtr<Animation> animati
m_associated_animations.remove_first_matching([&](auto element) { return animation == element; });
}
void Animatable::add_transitioned_properties(Vector<Vector<CSS::PropertyID>> properties, CSS::StyleValueVector delays, CSS::StyleValueVector durations, CSS::StyleValueVector timing_functions)
{
VERIFY(properties.size() == delays.size());
VERIFY(properties.size() == durations.size());
VERIFY(properties.size() == timing_functions.size());
for (size_t i = 0; i < properties.size(); i++) {
size_t index_of_this_transition = m_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;
auto timing_function = timing_functions[i]->is_easing() ? timing_functions[i]->as_easing().function() : CSS::EasingStyleValue::CubicBezier::ease();
VERIFY(timing_functions[i]->is_easing());
m_transition_attributes.empend(delay, duration, timing_function);
for (auto const& property : properties[i])
m_transition_attribute_indices.set(property, index_of_this_transition);
}
}
Optional<Animatable::TransitionAttributes const&> Animatable::property_transition_attributes(CSS::PropertyID property) const
{
if (auto maybe_index = m_transition_attribute_indices.get(property); maybe_index.has_value())
return m_transition_attributes[maybe_index.value()];
return {};
}
JS::GCPtr<CSS::CSSTransition> Animatable::property_transition(CSS::PropertyID property) const
{
if (auto maybe_animation = m_associated_transitions.get(property); maybe_animation.has_value())
return maybe_animation.value();
return {};
}
void Animatable::set_transition(CSS::PropertyID property, JS::NonnullGCPtr<CSS::CSSTransition> animation)
{
VERIFY(!m_associated_transitions.contains(property));
m_associated_transitions.set(property, animation);
}
void Animatable::remove_transition(CSS::PropertyID property_id)
{
VERIFY(m_associated_transitions.contains(property_id));
m_associated_transitions.remove(property_id);
}
void Animatable::clear_transitions()
{
m_transition_attribute_indices.clear();
m_transition_attributes.clear();
}
void Animatable::visit_edges(JS::Cell::Visitor& visitor)
{
visitor.visit(m_associated_animations);
@ -106,6 +161,8 @@ void Animatable::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(cached_animation_source);
for (auto const& cached_animation_name : m_cached_animation_name_animation)
visitor.visit(cached_animation_name);
visitor.visit(m_cached_transition_property_source);
visitor.visit(m_associated_transitions);
}
JS::GCPtr<CSS::CSSStyleDeclaration const> Animatable::cached_animation_name_source(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const