forked from microsoft/WPF-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathElasticDoubleAnimation.cs
155 lines (137 loc) · 6.15 KB
/
ElasticDoubleAnimation.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
150
151
152
153
154
155
// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Windows;
using System.Windows.Media.Animation;
namespace AnimationExamples
{
/// <summary>
/// ElasticDoubleAnimation - like something attached to a rubber band
/// </summary>
public class ElasticDoubleAnimation : DoubleAnimationBase
{
public enum EdgeBehaviorEnum
{
EaseIn,
EaseOut,
EaseInOut
}
public static readonly DependencyProperty EdgeBehaviorProperty =
DependencyProperty.Register("EdgeBehavior", typeof (EdgeBehaviorEnum), typeof (ElasticDoubleAnimation),
new PropertyMetadata(EdgeBehaviorEnum.EaseIn));
public static readonly DependencyProperty SpringinessProperty =
DependencyProperty.Register("Springiness", typeof (double), typeof (ElasticDoubleAnimation),
new PropertyMetadata(3.0));
public static readonly DependencyProperty OscillationsProperty =
DependencyProperty.Register("Oscillations", typeof (double), typeof (ElasticDoubleAnimation),
new PropertyMetadata(10.0));
public static readonly DependencyProperty FromProperty =
DependencyProperty.Register("From",
typeof (double?),
typeof (ElasticDoubleAnimation),
new PropertyMetadata(null));
public static readonly DependencyProperty ToProperty =
DependencyProperty.Register("To",
typeof (double?),
typeof (ElasticDoubleAnimation),
new PropertyMetadata(null));
/// <summary>
/// which side gets the effect
/// </summary>
public EdgeBehaviorEnum EdgeBehavior
{
get { return (EdgeBehaviorEnum) GetValue(EdgeBehaviorProperty); }
set { SetValue(EdgeBehaviorProperty, value); }
}
/// <summary>
/// how much springiness is there in the effect
/// </summary>
public double Springiness
{
get { return (double) GetValue(SpringinessProperty); }
set { SetValue(SpringinessProperty, value); }
}
/// <summary>
/// number of oscillations in the effect
/// </summary>
public double Oscillations
{
get { return (double) GetValue(OscillationsProperty); }
set { SetValue(OscillationsProperty, value); }
}
/// <summary>
/// Specifies the starting value of the animation.
/// </summary>
public double? From
{
get { return (double?) GetValue(FromProperty); }
set { SetValue(FromProperty, value); }
}
/// <summary>
/// Specifies the ending value of the animation.
/// </summary>
public double? To
{
get { return (double?) GetValue(ToProperty); }
set { SetValue(ToProperty, value); }
}
protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue,
AnimationClock clock)
{
double returnValue;
var start = From ?? defaultOriginValue;
var delta = To - start ?? defaultOriginValue - start;
switch (EdgeBehavior)
{
case EdgeBehaviorEnum.EaseIn:
returnValue = EaseIn(clock.CurrentProgress.Value, start, delta, Springiness, Oscillations);
break;
case EdgeBehaviorEnum.EaseOut:
returnValue = EaseOut(clock.CurrentProgress.Value, start, delta, Springiness, Oscillations);
break;
default:
returnValue = EaseInOut(clock.CurrentProgress.Value, start, delta, Springiness, Oscillations);
break;
}
return returnValue;
}
protected override Freezable CreateInstanceCore() => new ElasticDoubleAnimation();
private static double EaseOut(double timeFraction, double start, double delta, double springiness,
double oscillations)
{
// math magic: The cosine gives us the right wave, the timeFraction * the # of oscillations is the
// frequency of the wave, and the amplitude (the exponent) makes the wave get smaller at the end
// by the "springiness" factor. This is extremely similar to the bounce equation.
var returnValue = Math.Pow((1 - timeFraction), springiness)
*Math.Cos(2*Math.PI*timeFraction*oscillations);
returnValue = delta - (returnValue*delta);
returnValue += start;
return returnValue;
}
private static double EaseIn(double timeFraction, double start, double delta, double springiness,
double oscillations)
{
// math magic: The cosine gives us the right wave, the timeFraction * the # of oscillations is the
// frequency of the wave, and the amplitude (the exponent) makes the wave get smaller at the beginning
// by the "springiness" factor. This is extremely similar to the bounce equation.
var returnValue = Math.Pow((timeFraction), springiness)
*Math.Cos(2*Math.PI*timeFraction*oscillations);
returnValue = returnValue*delta;
returnValue += start;
return returnValue;
}
private static double EaseInOut(double timeFraction, double start, double delta, double springiness,
double oscillations)
{
double returnValue;
// we cut each effect in half by multiplying the time fraction by two and halving the distance.
if (timeFraction <= 0.5)
{
return EaseIn(timeFraction*2, start, delta/2, springiness, oscillations);
}
returnValue = EaseOut((timeFraction - 0.5)*2, start, delta/2, springiness, oscillations);
returnValue += (delta/2);
return returnValue;
}
}
}