-
Notifications
You must be signed in to change notification settings - Fork 5
/
Transition.cs
149 lines (128 loc) · 5.68 KB
/
Transition.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
namespace engenious.UI
{
/// <summary>
/// Base class for transition animations.
/// </summary>
public abstract class Transition
{
/// <summary>
/// Gets the currently elapsed time.
/// </summary>
public TimeSpan Current { get; private set; }
/// <summary>
/// Gets the delay to wait till starting the transition.
/// </summary>
public TimeSpan Delay { get; }
/// <summary>
/// Gets the duration of the transition.
/// </summary>
public TimeSpan Duration { get; }
/// <summary>
/// Gets the control that will be animated.
/// </summary>
public Control Control { get; }
/// <summary>
/// Gets the transition curve used for transitioning.
/// </summary>
/// <seealso cref="TransitionCurveDelegate"/>
public TransitionCurveDelegate Curve { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Transition"/> class.
/// </summary>
/// <param name="control">The control to apply the transition to.</param>
/// <param name="curve">The transition curve.</param>
/// <param name="duration">The time duration of the transition.</param>
public Transition(Control control, TransitionCurveDelegate curve, TimeSpan duration) :
this(control, curve, duration, TimeSpan.Zero)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Transition"/> class.
/// </summary>
/// <param name="control">The control to apply the transition to.</param>
/// <param name="curve">The transition curve.</param>
/// <param name="duration">The time duration of the transition.</param>
/// <param name="delay">The time delay to wait before starting the transition.</param>
public Transition(Control control, TransitionCurveDelegate curve, TimeSpan duration, TimeSpan delay)
{
Current = new TimeSpan();
Control = control;
Curve = curve;
Duration = duration;
Delay = delay;
}
/// <summary>
/// Update the transition and apply it.
/// </summary>
/// <param name="gameTime">Contains the elapsed time since the last update, as well as total elapsed time.</param>
/// <returns>Whether the transition is still ongoing.</returns>
public bool Update(GameTime gameTime)
{
// Calculate elapsed time of transition
Current += gameTime.ElapsedGameTime;
// Ignore if still below delay
if (Current < Delay) return true;
// Determine transition progress in percent
float position = Math.Max(0, Math.Min(1, (float)(
(Current.TotalMilliseconds - Delay.TotalMilliseconds) / Duration.TotalMilliseconds)));
float value = Math.Max(0, Math.Min(1, Curve(position)));
// Apply transition to control
ApplyValue(Control, value);
// At end of transition
if (position >= 1f)
{
Finished?.Invoke(this, Control);
return false;
}
return true;
}
/// <summary>
/// Applies the transition to a control.
/// </summary>
/// <param name="control">The <see cref="Control"/> to apply the transition to.</param>
/// <param name="value">Value depicting the progress of the transition in percent[0f-1f].</param>
protected abstract void ApplyValue(Control control, float value);
/// <summary>
/// Creates a cloned instance of this <see cref="Transition"/> but with a different control to apply the transition to.
/// </summary>
/// <param name="control">The control to apply the transition to.</param>
/// <returns>The cloned <see cref="Transition"/>.</returns>
public abstract Transition Clone(Control control);
/// <summary>
/// Occurs when the transition was finished.
/// </summary>
public event TransitionDelegate? Finished;
#region Transition Curves
/// <summary>
/// Depicts a linear transition curve.
/// </summary>
/// <param name="position">Value depicting the progress of the transition in percent[0f-1f].</param>
/// <returns>The linearly interpolated value(=<paramref name="position"/>).</returns>
public static float Linear(float position)
{
return position;
}
/// <summary>
/// Depicts a cubic transition curve.
/// </summary>
/// <param name="position">Value depicting the progress of the transition in percent[0f-1f].</param>
/// <returns>The cubic interpolated value(=pow(<paramref name="position"/>, 2)).</returns>
public static float Cubic(float position)
{
return MathF.Pow(position, 2);
}
#endregion
}
/// <summary>
/// Represents the method that will handle the <see cref="Transition.Finished"/> event of a <see cref="Transition"/>.
/// </summary>
/// <param name="sender">The transition that was finished.</param>
/// <param name="control">The control the transition was applied to.</param>
public delegate void TransitionDelegate(Transition sender, Control control);
/// <summary>
/// Represents the method that will curve transitions to be able to have different interpolation speeds across the transition time.
/// </summary>
/// <param name="t">The point to sample the curve at in percent[0f-1f].</param>
public delegate float TransitionCurveDelegate(float t);
}