| 
									
										
										
										
											2023-08-19 13:56:36 +02:00
										 |  |  | // Copyright 2022 Arthur Sonzogni. All rights reserved.
 | 
					
						
							|  |  |  | // Use of this source code is governed by the MIT license that can be found in
 | 
					
						
							|  |  |  | // the LICENSE file.
 | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | #ifndef FTXUI_ANIMATION_HPP
 | 
					
						
							|  |  |  | #define FTXUI_ANIMATION_HPP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <chrono>      // for milliseconds, duration, steady_clock, time_point
 | 
					
						
							|  |  |  | #include <functional>  // for function
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-01 11:40:49 +02:00
										 |  |  | namespace ftxui::animation { | 
					
						
							| 
									
										
										
										
											2025-06-05 11:35:14 +02:00
										 |  |  | /// @brief RequestAnimationFrame is a function that requests a new frame to be
 | 
					
						
							|  |  |  | /// drawn in the next animation cycle.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// @note This function is typically called by components that need to
 | 
					
						
							|  |  |  | /// update their state or appearance over time, such as animations or
 | 
					
						
							|  |  |  | /// transitions. This is useful when the change doesn't depend depend on the
 | 
					
						
							|  |  |  | /// events seen by the terminal, but rather on the passage of time.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// Components who haven't completed their animation can call this function to
 | 
					
						
							|  |  |  | /// request a new frame to be drawn later.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// When there is no new events and no animations to complete, no new frame is
 | 
					
						
							|  |  |  | /// drawn.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// @ingroup component
 | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | void RequestAnimationFrame(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using Clock = std::chrono::steady_clock; | 
					
						
							|  |  |  | using TimePoint = std::chrono::time_point<Clock>; | 
					
						
							| 
									
										
										
										
											2023-03-26 16:42:08 +02:00
										 |  |  | using Duration = std::chrono::duration<float>; | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Parameter of Component::OnAnimation(param).
 | 
					
						
							|  |  |  | class Params { | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2024-05-01 11:40:49 +02:00
										 |  |  |   explicit Params(Duration duration) : duration_(duration) {} | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /// The duration this animation step represents.
 | 
					
						
							|  |  |  |   Duration duration() const { return duration_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   Duration duration_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace easing { | 
					
						
							|  |  |  | using Function = std::function<float(float)>; | 
					
						
							|  |  |  | // Linear interpolation (no easing)
 | 
					
						
							|  |  |  | float Linear(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Quadratic easing; p^2
 | 
					
						
							|  |  |  | float QuadraticIn(float p); | 
					
						
							|  |  |  | float QuadraticOut(float p); | 
					
						
							|  |  |  | float QuadraticInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Cubic easing; p^3
 | 
					
						
							|  |  |  | float CubicIn(float p); | 
					
						
							|  |  |  | float CubicOut(float p); | 
					
						
							|  |  |  | float CubicInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Quartic easing; p^4
 | 
					
						
							|  |  |  | float QuarticIn(float p); | 
					
						
							|  |  |  | float QuarticOut(float p); | 
					
						
							|  |  |  | float QuarticInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Quintic easing; p^5
 | 
					
						
							|  |  |  | float QuinticIn(float p); | 
					
						
							|  |  |  | float QuinticOut(float p); | 
					
						
							|  |  |  | float QuinticInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Sine wave easing; sin(p * PI/2)
 | 
					
						
							|  |  |  | float SineIn(float p); | 
					
						
							|  |  |  | float SineOut(float p); | 
					
						
							|  |  |  | float SineInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Circular easing; sqrt(1 - p^2)
 | 
					
						
							|  |  |  | float CircularIn(float p); | 
					
						
							|  |  |  | float CircularOut(float p); | 
					
						
							|  |  |  | float CircularInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Exponential easing, base 2
 | 
					
						
							|  |  |  | float ExponentialIn(float p); | 
					
						
							|  |  |  | float ExponentialOut(float p); | 
					
						
							|  |  |  | float ExponentialInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Exponentially-damped sine wave easing
 | 
					
						
							|  |  |  | float ElasticIn(float p); | 
					
						
							|  |  |  | float ElasticOut(float p); | 
					
						
							|  |  |  | float ElasticInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Overshooting cubic easing;
 | 
					
						
							|  |  |  | float BackIn(float p); | 
					
						
							|  |  |  | float BackOut(float p); | 
					
						
							|  |  |  | float BackInOut(float p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Exponentially-decaying bounce easing
 | 
					
						
							|  |  |  | float BounceIn(float p); | 
					
						
							|  |  |  | float BounceOut(float p); | 
					
						
							|  |  |  | float BounceInOut(float p); | 
					
						
							|  |  |  | }  // namespace easing
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Animator { | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2024-05-01 11:40:49 +02:00
										 |  |  |   explicit Animator(float* from, | 
					
						
							|  |  |  |                     float to = 0.f, | 
					
						
							|  |  |  |                     Duration duration = std::chrono::milliseconds(250), | 
					
						
							|  |  |  |                     easing::Function easing_function = easing::Linear, | 
					
						
							|  |  |  |                     Duration delay = std::chrono::milliseconds(0)); | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void OnAnimation(Params&); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   float to() const { return to_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   float* value_; | 
					
						
							|  |  |  |   float from_; | 
					
						
							|  |  |  |   float to_; | 
					
						
							|  |  |  |   Duration duration_; | 
					
						
							|  |  |  |   easing::Function easing_function_; | 
					
						
							|  |  |  |   Duration current_; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-01 11:40:49 +02:00
										 |  |  | }  // namespace ftxui::animation
 | 
					
						
							| 
									
										
										
										
											2022-03-13 18:51:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif /* end of include guard: FTXUI_ANIMATION_HPP */
 |