#region Imports using DPumpHydr.WinFrmUI.RLT.Enum.Metro; using System; using System.Windows.Forms; #endregion namespace DPumpHydr.WinFrmUI.RLT.Animate.Metro { #region AnimateAnimate public abstract class Animate : IDisposable { public Action Update { get; set; } public MethodInvoker Complete { get; set; } #region Internal Vars private DateTime _lastUpdateTime; private readonly Timer _animateTimer; private bool _reverse; #endregion #region Constructors public Animate(int updateInterval = 16) { _animateTimer = new Timer() { Interval = updateInterval, Enabled = false, }; _animateTimer.Tick += OnFrameUpdate; _reverse = false; Alpha = 0.0; } #endregion #region Functions public void Setting(int duration, T initial, T end, EasingType easing = EasingType.Linear) { InitialValue = initial; EndValue = end; EasingType = easing; Duration = duration; } public void Start() { _reverse = false; Alpha = 0.0; Play(); } public void Back() { _reverse = true; Alpha = 1.0; Play(); } public void Start(int duration) { _reverse = false; Alpha = 0.0; Duration = duration; Play(); } public void Back(int duration) { _reverse = true; Alpha = 1.0; Duration = duration; Play(); } public void Reverse() { Reverse(!_reverse); } public void Reverse(bool val) { _reverse = val; if (!Active) { Play(); } } public void Play() { _lastUpdateTime = DateTime.Now; Active = true; _animateTimer.Enabled = true; _animateTimer.Start(); } public void Pause() { _animateTimer.Stop(); _animateTimer.Enabled = false; Active = false; } public void Stop() { Pause(); Alpha = _reverse ? 1.0 : 0.0; } public void Start(int duration, T initial, T end, EasingType easing = EasingType.Linear) { Setting(duration, initial, end, easing); Start(); } public void Back(int duration, T initial, T end, EasingType easing = EasingType.Linear) { Setting(duration, initial, end, easing); Back(); } #endregion #region Events private void OnFrameUpdate(object sender, EventArgs e) { DateTime updateTime = DateTime.Now; double elapsed; if (Duration == 0) { elapsed = 1.0; } else { elapsed = (updateTime - _lastUpdateTime).TotalMilliseconds / Duration; } _lastUpdateTime = updateTime; Alpha = Math.Max(0.0, Math.Min(Alpha + (_reverse ? -elapsed : elapsed), 1.0)); Update?.Invoke(Value); if (Alpha is not 0.0 and not 1.0) { return; } Pause(); Complete?.Invoke(); } #endregion #region Properties public double Alpha { get; set; } public int Duration { get; set; } public T InitialValue { get; private set; } public abstract T Value { get; } public T EndValue { get; private set; } public EasingType EasingType { get; private set; } public bool Active { get; private set; } public object Tag { get; set; } #endregion #region Dispose void IDisposable.Dispose() { GC.SuppressFinalize(this); _animateTimer.Dispose(); } #endregion } #endregion }