Skip to main content

tween/tweens/
bounce.rs

1const MAGIC: f32 = 7.5625;
2const STAGE_ZERO: f32 = 1.0 / 2.75;
3const STAGE_ONE: f32 = 2.0 / 2.75;
4const STAGE_TWO: f32 = 2.5 / 2.75;
5
6declare_tween!(
7    /// A bouncy tween, similar to gravity. Go [here](https://easings.net/#easeInBounce) for a visual demonstration.
8    pub struct BounceIn;
9
10    /// Creates a new [BounceIn] Tweener.
11    pub fn bounce_in;
12
13    /// Creates a new [BounceIn] Tweener at the given time.
14    pub fn bounce_in_at;
15
16    pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, mut percent: f32) -> Value {
17        percent = 1.0 - percent;
18
19        let v = {
20            let multip = if percent < STAGE_ZERO {
21                MAGIC * percent * percent
22            } else if percent < STAGE_ONE {
23                let t = percent - 1.5 / 2.75;
24                MAGIC * t * t + 0.75
25            } else if percent < STAGE_TWO {
26                let t = percent - 2.25 / 2.75;
27                MAGIC * t * t + 0.9375
28            } else {
29                let t = percent - 2.625 / 2.75;
30
31                MAGIC * t * t + 0.984375
32            };
33
34            value_delta.scale(multip)
35        };
36
37        value_delta - v
38    }
39
40);
41
42declare_tween!(
43    /// A bouncy tween, similar to gravity. Go [here](https://easings.net/#easeOutBounce) for a visual demonstration.
44    pub struct BounceOut;
45
46    /// Creates a new [BounceOut] Tweener.
47    pub fn bounce_out;
48
49    /// Creates a new [BounceOut] Tweener at the given time.
50    pub fn bounce_out_at;
51
52    pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, percent: f32) -> Value {
53        let multip = if percent < STAGE_ZERO {
54            MAGIC * percent * percent
55        } else if percent < STAGE_ONE {
56            let t = percent - 1.5 / 2.75;
57            MAGIC * t * t + 0.75
58        } else if percent < STAGE_TWO {
59            let t = percent - 2.25 / 2.75;
60            MAGIC * t * t + 0.9375
61        } else {
62            let t = percent - 2.625 / 2.75;
63
64            MAGIC * t * t + 0.984375
65        };
66
67        value_delta.scale(multip)
68    }
69);
70
71declare_tween!(
72    /// A bouncy tween, similar to gravity. Go [here](https://easings.net/#easeInOutBounce) for a visual demonstration.
73    pub struct BounceInOut;
74
75    /// Creates a new [BounceInOut] Tweener.
76    pub fn bounce_in_out;
77
78    /// Creates a new [BounceInOut] Tweener at the given time.
79    pub fn bounce_in_out_at;
80
81    pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, mut percent: f32) -> Value {
82        if percent < 0.5 {
83            percent = 1.0 - percent * 2.0;
84            // (duration - current_time * 2.0) / duration
85
86            let multip = if percent < STAGE_ZERO {
87                MAGIC * percent * percent
88            } else if percent < STAGE_ONE {
89                let t = percent - 1.5 / 2.75;
90                MAGIC * t * t + 0.75
91            } else if percent < STAGE_TWO {
92                let t = percent - 2.25 / 2.75;
93                MAGIC * t * t + 0.9375
94            } else {
95                let t = percent - 2.625 / 2.75;
96
97                MAGIC * t * t + 0.984375
98            };
99
100            (value_delta - value_delta.scale(multip)).scale(0.5)
101        } else {
102            percent = (percent - 0.5) * 2.0;
103
104            let multip = if percent < STAGE_ZERO {
105                MAGIC * percent * percent
106            } else if percent < STAGE_ONE {
107                let t = percent - 1.5 / 2.75;
108                MAGIC * t * t + 0.75
109            } else if percent < STAGE_TWO {
110                let t = percent - 2.25 / 2.75;
111                MAGIC * t * t + 0.9375
112            } else {
113                let t = percent - 2.625 / 2.75;
114
115                MAGIC * t * t + 0.984375
116            };
117
118            value_delta.scale(multip).scale(0.5) + value_delta.scale(0.5)
119        }
120    }
121
122);
123
124test_tween!(Bounce);