mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-10-04 00:59:34 +03:00
LibWeb: Store property transitions in Animatable
Co-authored-by: Sam Atkins <sam@ladybird.org>
This commit is contained in:
parent
815a87100e
commit
392510c631
Notes:
github-actions[bot]
2024-09-22 04:42:58 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/392510c631a Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1442
@ -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
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
@ -8,6 +9,9 @@
|
|||||||
#include <LibWeb/Animations/Animatable.h>
|
#include <LibWeb/Animations/Animatable.h>
|
||||||
#include <LibWeb/Animations/Animation.h>
|
#include <LibWeb/Animations/Animation.h>
|
||||||
#include <LibWeb/Animations/DocumentTimeline.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/Document.h>
|
||||||
#include <LibWeb/DOM/Element.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; });
|
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)
|
void Animatable::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
visitor.visit(m_associated_animations);
|
visitor.visit(m_associated_animations);
|
||||||
@ -106,6 +161,8 @@ void Animatable::visit_edges(JS::Cell::Visitor& visitor)
|
|||||||
visitor.visit(cached_animation_source);
|
visitor.visit(cached_animation_source);
|
||||||
for (auto const& cached_animation_name : m_cached_animation_name_animation)
|
for (auto const& cached_animation_name : m_cached_animation_name_animation)
|
||||||
visitor.visit(cached_animation_name);
|
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
|
JS::GCPtr<CSS::CSSStyleDeclaration const> Animatable::cached_animation_name_source(Optional<CSS::Selector::PseudoElement::Type> pseudo_element) const
|
||||||
|
@ -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
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
@ -7,8 +8,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/FlyString.h>
|
#include <AK/FlyString.h>
|
||||||
|
#include <AK/HashMap.h>
|
||||||
#include <LibWeb/Animations/KeyframeEffect.h>
|
#include <LibWeb/Animations/KeyframeEffect.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
class CSSTransition;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Web::Animations {
|
namespace Web::Animations {
|
||||||
|
|
||||||
// https://www.w3.org/TR/web-animations-1/#dictdef-keyframeanimationoptions
|
// https://www.w3.org/TR/web-animations-1/#dictdef-keyframeanimationoptions
|
||||||
@ -25,6 +31,12 @@ struct GetAnimationsOptions {
|
|||||||
// https://www.w3.org/TR/web-animations-1/#animatable
|
// https://www.w3.org/TR/web-animations-1/#animatable
|
||||||
class Animatable {
|
class Animatable {
|
||||||
public:
|
public:
|
||||||
|
struct TransitionAttributes {
|
||||||
|
double delay;
|
||||||
|
double duration;
|
||||||
|
CSS::EasingStyleValue::Function timing_function;
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~Animatable() = default;
|
virtual ~Animatable() = default;
|
||||||
|
|
||||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> animate(Optional<JS::Handle<JS::Object>> keyframes, Variant<Empty, double, KeyframeAnimationOptions> options = {});
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<Animation>> animate(Optional<JS::Handle<JS::Object>> keyframes, Variant<Empty, double, KeyframeAnimationOptions> options = {});
|
||||||
@ -39,6 +51,16 @@ public:
|
|||||||
JS::GCPtr<Animations::Animation> cached_animation_name_animation(Optional<CSS::Selector::PseudoElement::Type>) const;
|
JS::GCPtr<Animations::Animation> cached_animation_name_animation(Optional<CSS::Selector::PseudoElement::Type>) const;
|
||||||
void set_cached_animation_name_animation(JS::GCPtr<Animations::Animation> value, Optional<CSS::Selector::PseudoElement::Type>);
|
void set_cached_animation_name_animation(JS::GCPtr<Animations::Animation> value, Optional<CSS::Selector::PseudoElement::Type>);
|
||||||
|
|
||||||
|
JS::GCPtr<CSS::CSSStyleDeclaration const> cached_transition_property_source() const { return m_cached_transition_property_source; }
|
||||||
|
void set_cached_transition_property_source(JS::GCPtr<CSS::CSSStyleDeclaration const> value) { m_cached_transition_property_source = value; }
|
||||||
|
|
||||||
|
void add_transitioned_properties(Vector<Vector<CSS::PropertyID>> properties, CSS::StyleValueVector delays, CSS::StyleValueVector durations, CSS::StyleValueVector timing_functions);
|
||||||
|
Optional<TransitionAttributes const&> property_transition_attributes(CSS::PropertyID) const;
|
||||||
|
void set_transition(CSS::PropertyID, JS::NonnullGCPtr<CSS::CSSTransition>);
|
||||||
|
void remove_transition(CSS::PropertyID);
|
||||||
|
JS::GCPtr<CSS::CSSTransition> property_transition(CSS::PropertyID) const;
|
||||||
|
void clear_transitions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void visit_edges(JS::Cell::Visitor&);
|
void visit_edges(JS::Cell::Visitor&);
|
||||||
|
|
||||||
@ -48,6 +70,11 @@ private:
|
|||||||
|
|
||||||
Array<JS::GCPtr<CSS::CSSStyleDeclaration const>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_source;
|
Array<JS::GCPtr<CSS::CSSStyleDeclaration const>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_source;
|
||||||
Array<JS::GCPtr<Animations::Animation>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_animation;
|
Array<JS::GCPtr<Animations::Animation>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + 1> m_cached_animation_name_animation;
|
||||||
|
|
||||||
|
HashMap<CSS::PropertyID, size_t> m_transition_attribute_indices;
|
||||||
|
Vector<TransitionAttributes> m_transition_attributes;
|
||||||
|
JS::GCPtr<CSS::CSSStyleDeclaration const> m_cached_transition_property_source;
|
||||||
|
HashMap<CSS::PropertyID, JS::NonnullGCPtr<CSS::CSSTransition>> m_associated_transitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user