mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:32:46 +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
	
	 Matthew Olsson
						Matthew Olsson