diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-10-23 14:53:28 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-10-23 14:53:28 +0300 |
commit | 0c9806529bc33f02431570ba0cc2d48039b8afe1 (patch) | |
tree | c8915ed3b93aa7b9b5c67bea100e800f0cda0598 /src/ui/util.c | |
parent | 97fd3c886ee1aa069784da881dc206741d282b3c (diff) |
Improved smooth scrolling
Use proper easing curves for a smoother animation. Ensure that mouse hover on links is disabled when scrolling.
Diffstat (limited to 'src/ui/util.c')
-rw-r--r-- | src/ui/util.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/src/ui/util.c b/src/ui/util.c index bef839dc..38124b22 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -135,8 +135,9 @@ iBool isFinished_Anim(const iAnim *d) { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | void init_Anim(iAnim *d, float value) { | 137 | void init_Anim(iAnim *d, float value) { |
138 | d->due = d->when = frameTime_Window(get_Window()); | 138 | d->due = d->when = SDL_GetTicks(); // frameTime_Window(get_Window()); |
139 | d->from = d->to = value; | 139 | d->from = d->to = value; |
140 | d->flags = 0; | ||
140 | } | 141 | } |
141 | 142 | ||
142 | void setValue_Anim(iAnim *d, float to, uint32_t span) { | 143 | void setValue_Anim(iAnim *d, float to, uint32_t span) { |
@@ -149,6 +150,54 @@ void setValue_Anim(iAnim *d, float to, uint32_t span) { | |||
149 | } | 150 | } |
150 | } | 151 | } |
151 | 152 | ||
153 | iLocalDef float pos_Anim_(const iAnim *d, uint32_t now) { | ||
154 | return (float) (now - d->when) / (float) (d->due - d->when); | ||
155 | } | ||
156 | |||
157 | void setValueEased_Anim(iAnim *d, float to, uint32_t span) { | ||
158 | if (fabsf(to - d->to) <= 0.00001f) { | ||
159 | d->to = to; /* Pretty much unchanged. */ | ||
160 | return; | ||
161 | } | ||
162 | const uint32_t now = SDL_GetTicks(); | ||
163 | if (isFinished_Anim(d)) { | ||
164 | d->from = d->to; | ||
165 | d->when = now; | ||
166 | d->flags = easeBoth_AnimFlag; | ||
167 | } | ||
168 | else { | ||
169 | d->from = value_Anim(d); | ||
170 | d->when = frameTime_Window(get_Window()); /* to match the timing of value_Anim */ | ||
171 | d->flags = easeOut_AnimFlag; | ||
172 | } | ||
173 | d->to = to; | ||
174 | d->due = now + span; | ||
175 | } | ||
176 | |||
177 | void setFlags_Anim(iAnim *d, int flags, iBool set) { | ||
178 | iChangeFlags(d->flags, flags, set); | ||
179 | } | ||
180 | |||
181 | void stop_Anim(iAnim *d) { | ||
182 | d->from = d->to = value_Anim(d); | ||
183 | d->when = d->due = SDL_GetTicks(); | ||
184 | } | ||
185 | |||
186 | iLocalDef float easeIn_(float t) { | ||
187 | return t * t; | ||
188 | } | ||
189 | |||
190 | iLocalDef float easeOut_(float t) { | ||
191 | return t * (2.0f - t); | ||
192 | } | ||
193 | |||
194 | iLocalDef float easeBoth_(float t) { | ||
195 | if (t < 0.5f) { | ||
196 | return easeIn_(t * 2.0f) * 0.5f; | ||
197 | } | ||
198 | return 0.5f + easeOut_((t - 0.5f) * 2.0f) * 0.5f; | ||
199 | } | ||
200 | |||
152 | float value_Anim(const iAnim *d) { | 201 | float value_Anim(const iAnim *d) { |
153 | const uint32_t now = frameTime_Window(get_Window()); | 202 | const uint32_t now = frameTime_Window(get_Window()); |
154 | if (now >= d->due) { | 203 | if (now >= d->due) { |
@@ -157,8 +206,17 @@ float value_Anim(const iAnim *d) { | |||
157 | if (now <= d->when) { | 206 | if (now <= d->when) { |
158 | return d->from; | 207 | return d->from; |
159 | } | 208 | } |
160 | const float pos = (float) (now - d->when) / (float) (d->due - d->when); | 209 | float t = pos_Anim_(d, now); |
161 | return d->from * (1.0f - pos) + d->to * pos; | 210 | if ((d->flags & easeBoth_AnimFlag) == easeBoth_AnimFlag) { |
211 | t = easeBoth_(t); | ||
212 | } | ||
213 | else if (d->flags & easeIn_AnimFlag) { | ||
214 | t = easeIn_(t); | ||
215 | } | ||
216 | else if (d->flags & easeOut_AnimFlag) { | ||
217 | t = easeOut_(t); | ||
218 | } | ||
219 | return d->from * (1.0f - t) + d->to * t; | ||
162 | } | 220 | } |
163 | 221 | ||
164 | /*-----------------------------------------------------------------------------------------------*/ | 222 | /*-----------------------------------------------------------------------------------------------*/ |