using System.Diagnostics; using System.Numerics; using Dalamud.Utility; namespace Dalamud.Interface.Animation; /// /// Base class facilitating the implementation of easing functions. /// [Api11ToDo("Re-apply https://github.com/goatcorp/Dalamud/commit/1aada983931d9e45a250eebbc17c8b782d07701b")] public abstract class Easing { // TODO: Use game delta time here instead private readonly Stopwatch animationTimer = new(); private double valueInternal; /// /// Initializes a new instance of the class with the specified duration. /// /// The animation duration. protected Easing(TimeSpan duration) { this.Duration = duration; } /// /// Gets or sets the origin point of the animation. /// public Vector2? Point1 { get; set; } /// /// Gets or sets the destination point of the animation. /// public Vector2? Point2 { get; set; } /// /// Gets the resulting point at the current timestep. /// public Vector2 EasedPoint { get; private set; } /// /// Gets or sets a value indicating whether the result of the easing should be inversed. /// public bool IsInverse { get; set; } /// /// Gets or sets the current value of the animation, from 0 to 1. /// public double Value { get { if (this.IsInverse) return 1 - this.valueInternal; return this.valueInternal; } protected set { this.valueInternal = value; if (this.Point1.HasValue && this.Point2.HasValue) this.EasedPoint = AnimUtil.Lerp(this.Point1.Value, this.Point2.Value, (float)this.valueInternal); } } /// /// Gets or sets the duration of the animation. /// public TimeSpan Duration { get; set; } /// /// Gets a value indicating whether or not the animation is running. /// public bool IsRunning => this.animationTimer.IsRunning; /// /// Gets a value indicating whether or not the animation is done. /// public bool IsDone => this.animationTimer.ElapsedMilliseconds > this.Duration.TotalMilliseconds; /// /// Gets the progress of the animation, from 0 to 1. /// protected double Progress => this.animationTimer.ElapsedMilliseconds / this.Duration.TotalMilliseconds; /// /// Starts the animation from where it was last stopped, or from the start if it was never started before. /// public void Start() { this.animationTimer.Start(); } /// /// Stops the animation at the current point. /// public void Stop() { this.animationTimer.Stop(); } /// /// Restarts the animation. /// public void Restart() { this.animationTimer.Restart(); } /// /// Resets the animation. /// public void Reset() { this.animationTimer.Reset(); } /// /// Updates the animation. /// public abstract void Update(); }