@@ -5,6 +5,7 @@ use crate::{
5
5
ops:: { self , FloatPow } ,
6
6
VectorSpace ,
7
7
} ;
8
+ use interpolation:: Ease ;
8
9
9
10
use super :: { Curve , FunctionCurve , Interval } ;
10
11
84
85
}
85
86
86
87
impl EasingCurve < f32 , FunctionCurve < f32 , fn ( f32 ) -> f32 > > {
88
+ /// A [`Curve`] mapping the [unit interval] to itself.
89
+ ///
90
+ /// [unit interval]: `Interval::UNIT`
91
+ pub fn ease ( function : EaseFunction ) -> Self {
92
+ Self {
93
+ start : 0.0 ,
94
+ end : 1.0 ,
95
+ easing : FunctionCurve :: new (
96
+ Interval :: UNIT ,
97
+ match function {
98
+ EaseFunction :: QuadraticIn => Ease :: quadratic_in,
99
+ EaseFunction :: QuadraticOut => Ease :: quadratic_out,
100
+ EaseFunction :: QuadraticInOut => Ease :: quadratic_in_out,
101
+ EaseFunction :: CubicIn => Ease :: cubic_in,
102
+ EaseFunction :: CubicOut => Ease :: cubic_out,
103
+ EaseFunction :: CubicInOut => Ease :: cubic_in_out,
104
+ EaseFunction :: QuarticIn => Ease :: quartic_in,
105
+ EaseFunction :: QuarticOut => Ease :: quartic_out,
106
+ EaseFunction :: QuarticInOut => Ease :: quartic_in_out,
107
+ EaseFunction :: QuinticIn => Ease :: quintic_in,
108
+ EaseFunction :: QuinticOut => Ease :: quintic_out,
109
+ EaseFunction :: QuinticInOut => Ease :: quintic_in_out,
110
+ EaseFunction :: SineIn => Ease :: sine_in,
111
+ EaseFunction :: SineOut => Ease :: sine_out,
112
+ EaseFunction :: SineInOut => Ease :: sine_in_out,
113
+ EaseFunction :: CircularIn => Ease :: circular_in,
114
+ EaseFunction :: CircularOut => Ease :: circular_out,
115
+ EaseFunction :: CircularInOut => Ease :: circular_in_out,
116
+ EaseFunction :: ExponentialIn => Ease :: exponential_in,
117
+ EaseFunction :: ExponentialOut => Ease :: exponential_out,
118
+ EaseFunction :: ExponentialInOut => Ease :: exponential_in_out,
119
+ EaseFunction :: ElasticIn => Ease :: elastic_in,
120
+ EaseFunction :: ElasticOut => Ease :: elastic_out,
121
+ EaseFunction :: ElasticInOut => Ease :: elastic_in_out,
122
+ EaseFunction :: BackIn => Ease :: back_in,
123
+ EaseFunction :: BackOut => Ease :: back_out,
124
+ EaseFunction :: BackInOut => Ease :: back_in_out,
125
+ EaseFunction :: BounceIn => Ease :: bounce_in,
126
+ EaseFunction :: BounceOut => Ease :: bounce_out,
127
+ EaseFunction :: BounceInOut => Ease :: bounce_in_out,
128
+ } ,
129
+ ) ,
130
+ }
131
+ }
132
+
87
133
/// A [`Curve`] mapping the [unit interval] to itself.
88
134
///
89
135
/// Quadratic easing functions can have exactly one critical point. This is a point on the function
@@ -92,7 +138,7 @@ impl EasingCurve<f32, FunctionCurve<f32, fn(f32) -> f32>> {
92
138
///
93
139
/// It uses the function `f(t) = t²`
94
140
///
95
- /// [unit domain ]: `Interval::UNIT`
141
+ /// [unit interval ]: `Interval::UNIT`
96
142
/// [`t = 1`]: `Self::quadratic_ease_out`
97
143
pub fn quadratic_ease_in ( ) -> Self {
98
144
Self {
@@ -110,7 +156,7 @@ impl EasingCurve<f32, FunctionCurve<f32, fn(f32) -> f32>> {
110
156
///
111
157
/// It uses the function `f(t) = 1 - (1 - t)²`
112
158
///
113
- /// [unit domain ]: `Interval::UNIT`
159
+ /// [unit interval ]: `Interval::UNIT`
114
160
/// [`t = 0`]: `Self::quadratic_ease_in`
115
161
pub fn quadratic_ease_out ( ) -> Self {
116
162
fn f ( t : f32 ) -> f32 {
@@ -132,7 +178,7 @@ impl EasingCurve<f32, FunctionCurve<f32, fn(f32) -> f32>> {
132
178
///
133
179
/// It uses the function `f(t) = t² * (3 - 2t)`
134
180
///
135
- /// [unit domain ]: `Interval::UNIT`
181
+ /// [unit interval ]: `Interval::UNIT`
136
182
/// [sigmoid function]: https://en.wikipedia.org/wiki/Sigmoid_function
137
183
/// [smoothstep function]: https://en.wikipedia.org/wiki/Smoothstep
138
184
pub fn smoothstep ( ) -> Self {
@@ -150,7 +196,7 @@ impl EasingCurve<f32, FunctionCurve<f32, fn(f32) -> f32>> {
150
196
///
151
197
/// It uses the function `f(t) = t`
152
198
///
153
- /// [unit domain ]: `Interval::UNIT`
199
+ /// [unit interval ]: `Interval::UNIT`
154
200
pub fn identity ( ) -> Self {
155
201
Self {
156
202
start : 0.0 ,
@@ -219,7 +265,7 @@ where
219
265
/// - for `n >= 2` the curve has a start segment and an end segment of length `1 / (2 * n)` and in
220
266
/// between there are `n - 1` segments of length `1 / n`
221
267
///
222
- /// [unit domain ]: `Interval::UNIT`
268
+ /// [unit interval ]: `Interval::UNIT`
223
269
/// [`constant_curve(Interval::UNIT, 0.0)`]: `crate::curve::constant_curve`
224
270
#[ derive( Clone , Debug ) ]
225
271
#[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
@@ -265,7 +311,7 @@ impl StepCurve {
265
311
///
266
312
/// parametrized by `omega`
267
313
///
268
- /// [unit domain ]: `Interval::UNIT`
314
+ /// [unit interval ]: `Interval::UNIT`
269
315
/// [smoothstep function]: https://en.wikipedia.org/wiki/Smoothstep
270
316
/// [spring-mass-system]: https://notes.yvt.jp/Graphics/Easing-Functions/#elastic-easing
271
317
#[ derive( Clone , Debug ) ]
@@ -296,3 +342,81 @@ impl ElasticCurve {
296
342
Self { omega }
297
343
}
298
344
}
345
+
346
+ /// Curve functions over the [unit interval], commonly used for easing transitions.
347
+ ///
348
+ /// [unit interval]: `Interval::UNIT`
349
+ #[ derive( Debug , Copy , Clone , PartialEq ) ]
350
+ #[ cfg_attr( feature = "serialize" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
351
+ #[ cfg_attr( feature = "bevy_reflect" , derive( bevy_reflect:: Reflect ) ) ]
352
+ pub enum EaseFunction {
353
+ /// `f(t) = t²`
354
+ QuadraticIn ,
355
+ /// `f(t) = -(t * (t - 2.0))`
356
+ QuadraticOut ,
357
+ /// Behaves as `EaseFunction::QuadraticIn` for t < 0.5 and as `EaseFunction::QuadraticOut` for t >= 0.5
358
+ QuadraticInOut ,
359
+
360
+ /// `f(t) = t³`
361
+ CubicIn ,
362
+ /// `f(t) = (t - 1.0)³ + 1.0`
363
+ CubicOut ,
364
+ /// Behaves as `EaseFunction::CubicIn` for t < 0.5 and as `EaseFunction::CubicOut` for t >= 0.5
365
+ CubicInOut ,
366
+
367
+ /// `f(t) = t⁴`
368
+ QuarticIn ,
369
+ /// `f(t) = (t - 1.0)³ * (1.0 - t) + 1.0`
370
+ QuarticOut ,
371
+ /// Behaves as `EaseFunction::QuarticIn` for t < 0.5 and as `EaseFunction::QuarticOut` for t >= 0.5
372
+ QuarticInOut ,
373
+
374
+ /// `f(t) = t⁵`
375
+ QuinticIn ,
376
+ /// `f(t) = (t - 1.0)⁵ + 1.0`
377
+ QuinticOut ,
378
+ /// Behaves as `EaseFunction::QuinticIn` for t < 0.5 and as `EaseFunction::QuinticOut` for t >= 0.5
379
+ QuinticInOut ,
380
+
381
+ /// `f(t) = sin((t - 1.0) * π / 2.0) + 1.0`
382
+ SineIn ,
383
+ /// `f(t) = sin(t * π / 2.0)`
384
+ SineOut ,
385
+ /// Behaves as `EaseFunction::SineIn` for t < 0.5 and as `EaseFunction::SineOut` for t >= 0.5
386
+ SineInOut ,
387
+
388
+ /// `f(t) = 1.0 - sqrt(1.0 - t²)`
389
+ CircularIn ,
390
+ /// `f(t) = sqrt((2.0 - t) * t)`
391
+ CircularOut ,
392
+ /// Behaves as `EaseFunction::CircularIn` for t < 0.5 and as `EaseFunction::CircularOut` for t >= 0.5
393
+ CircularInOut ,
394
+
395
+ /// `f(t) = 2.0.powf(10.0 * (t - 1.0))`
396
+ ExponentialIn ,
397
+ /// `f(t) = 1.0 - 2.0.powf(-10.0 * t)`
398
+ ExponentialOut ,
399
+ /// Behaves as `EaseFunction::ExponentialIn` for t < 0.5 and as `EaseFunction::ExponentialOut` for t >= 0.5
400
+ ExponentialInOut ,
401
+
402
+ /// `f(t) = sin(13.0 * π / 2.0 * t) * 2.0.powf(10.0 * (t - 1.0))`
403
+ ElasticIn ,
404
+ /// `f(t) = sin(-13.0 * π / 2.0 * (t + 1.0)) * 2.0.powf(-10.0 * t) + 1.0`
405
+ ElasticOut ,
406
+ /// Behaves as `EaseFunction::ElasticIn` for t < 0.5 and as `EaseFunction::ElasticOut` for t >= 0.5
407
+ ElasticInOut ,
408
+
409
+ /// `f(t) = t³ - t * sin(t * π)`
410
+ BackIn ,
411
+ /// `f(t) = 1.0 - (1.0 - t)³ - t * sin((1.0 - t) * π))`
412
+ BackOut ,
413
+ /// Behaves as `EaseFunction::BackIn` for t < 0.5 and as `EaseFunction::BackOut` for t >= 0.5
414
+ BackInOut ,
415
+
416
+ /// bouncy at the start!
417
+ BounceIn ,
418
+ /// bouncy at the end!
419
+ BounceOut ,
420
+ /// Behaves as `EaseFunction::BounceIn` for t < 0.5 and as `EaseFunction::BounceOut` for t >= 0.5
421
+ BounceInOut ,
422
+ }
0 commit comments