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 <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> | ||||
| 
 | ||||
| namespace Web::Animations { | ||||
|  | @ -164,6 +167,80 @@ double StepsTimingFunction::operator()(double input_progress, bool before_flag) | |||
|     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 | ||||
| { | ||||
|     return function.visit([&](auto const& f) { return f(input_progress, before_flag); }); | ||||
|  |  | |||
|  | @ -10,6 +10,10 @@ | |||
| #include <AK/Function.h> | ||||
| #include <AK/Vector.h> | ||||
| 
 | ||||
| namespace Web::CSS { | ||||
| class EasingStyleValue; | ||||
| } | ||||
| 
 | ||||
| namespace Web::Animations { | ||||
| 
 | ||||
| // https://www.w3.org/TR/css-easing-1/#the-linear-easing-function
 | ||||
|  | @ -45,6 +49,8 @@ struct StepsTimingFunction { | |||
| }; | ||||
| 
 | ||||
| struct TimingFunction { | ||||
|     static TimingFunction from_easing_style_value(CSS::EasingStyleValue const&); | ||||
| 
 | ||||
|     Variant<LinearTimingFunction, CubicBezierTimingFunction, StepsTimingFunction> function; | ||||
| 
 | ||||
|     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; | ||||
|             if (auto timing_property = style.maybe_null_property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing()) { | ||||
|                 auto& easing_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; | ||||
|                 } | ||||
|             } | ||||
|             if (auto timing_property = style.maybe_null_property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing()) | ||||
|                 timing_function = Animations::TimingFunction::from_easing_style_value(timing_property->as_easing()); | ||||
| 
 | ||||
|             auto& realm = element.realm(); | ||||
| 
 | ||||
|             auto effect = Animations::KeyframeEffect::create(realm); | ||||
|             auto iteration_duration = duration.has_value() | ||||
|                 ? Variant<double, String> { duration.release_value().to_milliseconds() } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Matthew Olsson
						Matthew Olsson