OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/android/scroller.h" | 5 #include "ui/events/android/scroller.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 | 10 |
11 namespace gfx { | 11 namespace ui { |
12 namespace { | 12 namespace { |
13 | 13 |
14 // Default scroll duration from android.widget.Scroller. | 14 // Default scroll duration from android.widget.Scroller. |
15 const int kDefaultDurationMs = 250; | 15 const int kDefaultDurationMs = 250; |
16 | 16 |
17 // Default friction constant in android.view.ViewConfiguration. | 17 // Default friction constant in android.view.ViewConfiguration. |
18 const float kDefaultFriction = 0.015f; | 18 const float kDefaultFriction = 0.015f; |
19 | 19 |
20 // == std::log(0.78f) / std::log(0.9f) | 20 // == std::log(0.78f) / std::log(0.9f) |
21 const float kDecelerationRate = 2.3582018f; | 21 const float kDecelerationRate = 2.3582018f; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 const float t_inf = static_cast<float>(index) / NUM_SAMPLES; | 115 const float t_inf = static_cast<float>(index) / NUM_SAMPLES; |
116 const float t_sup = static_cast<float>(index + 1) / NUM_SAMPLES; | 116 const float t_sup = static_cast<float>(index + 1) / NUM_SAMPLES; |
117 const float d_inf = spline_position_[index]; | 117 const float d_inf = spline_position_[index]; |
118 const float d_sup = spline_position_[index + 1]; | 118 const float d_sup = spline_position_[index + 1]; |
119 *velocity_coef = (d_sup - d_inf) / (t_sup - t_inf); | 119 *velocity_coef = (d_sup - d_inf) / (t_sup - t_inf); |
120 *distance_coef = d_inf + (t - t_inf) * *velocity_coef; | 120 *distance_coef = d_inf + (t - t_inf) * *velocity_coef; |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 private: | 124 private: |
125 enum { | 125 enum { NUM_SAMPLES = 100 }; |
126 NUM_SAMPLES = 100 | |
127 }; | |
128 | 126 |
129 float spline_position_[NUM_SAMPLES + 1]; | 127 float spline_position_[NUM_SAMPLES + 1]; |
130 float spline_time_[NUM_SAMPLES + 1]; | 128 float spline_time_[NUM_SAMPLES + 1]; |
131 | 129 |
132 DISALLOW_COPY_AND_ASSIGN(SplineConstants); | 130 DISALLOW_COPY_AND_ASSIGN(SplineConstants); |
133 }; | 131 }; |
134 | 132 |
135 float ComputeDeceleration(float friction) { | 133 float ComputeDeceleration(float friction) { |
136 const float kGravityEarth = 9.80665f; | 134 const float kGravityEarth = 9.80665f; |
137 return kGravityEarth // g (m/s^2) | 135 return kGravityEarth // g (m/s^2) |
(...skipping 15 matching lines...) Expand all Loading... |
153 // Leaky to allow access from the impl thread. | 151 // Leaky to allow access from the impl thread. |
154 base::LazyInstance<ViscosityConstants>::Leaky g_viscosity_constants = | 152 base::LazyInstance<ViscosityConstants>::Leaky g_viscosity_constants = |
155 LAZY_INSTANCE_INITIALIZER; | 153 LAZY_INSTANCE_INITIALIZER; |
156 | 154 |
157 base::LazyInstance<SplineConstants>::Leaky g_spline_constants = | 155 base::LazyInstance<SplineConstants>::Leaky g_spline_constants = |
158 LAZY_INSTANCE_INITIALIZER; | 156 LAZY_INSTANCE_INITIALIZER; |
159 | 157 |
160 } // namespace | 158 } // namespace |
161 | 159 |
162 Scroller::Config::Config() | 160 Scroller::Config::Config() |
163 : fling_friction(kDefaultFriction), | 161 : fling_friction(kDefaultFriction), flywheel_enabled(false) { |
164 flywheel_enabled(false) {} | 162 } |
165 | 163 |
166 Scroller::Scroller(const Config& config) | 164 Scroller::Scroller(const Config& config) |
167 : mode_(UNDEFINED), | 165 : mode_(UNDEFINED), |
168 start_x_(0), | 166 start_x_(0), |
169 start_y_(0), | 167 start_y_(0), |
170 final_x_(0), | 168 final_x_(0), |
171 final_y_(0), | 169 final_y_(0), |
172 min_x_(0), | 170 min_x_(0), |
173 max_x_(0), | 171 max_x_(0), |
174 min_y_(0), | 172 min_y_(0), |
175 max_y_(0), | 173 max_y_(0), |
176 curr_x_(0), | 174 curr_x_(0), |
177 curr_y_(0), | 175 curr_y_(0), |
178 duration_seconds_reciprocal_(1), | 176 duration_seconds_reciprocal_(1), |
179 delta_x_(0), | 177 delta_x_(0), |
180 delta_x_norm_(1), | 178 delta_x_norm_(1), |
181 delta_y_(0), | 179 delta_y_(0), |
182 delta_y_norm_(1), | 180 delta_y_norm_(1), |
183 finished_(true), | 181 finished_(true), |
184 flywheel_enabled_(config.flywheel_enabled), | 182 flywheel_enabled_(config.flywheel_enabled), |
185 velocity_(0), | 183 velocity_(0), |
186 curr_velocity_(0), | 184 curr_velocity_(0), |
187 distance_(0), | 185 distance_(0), |
188 fling_friction_(config.fling_friction), | 186 fling_friction_(config.fling_friction), |
189 deceleration_(ComputeDeceleration(fling_friction_)), | 187 deceleration_(ComputeDeceleration(fling_friction_)), |
190 tuning_coeff_(ComputeDeceleration(0.84f)) {} | 188 tuning_coeff_(ComputeDeceleration(0.84f)) { |
| 189 } |
191 | 190 |
192 Scroller::~Scroller() {} | 191 Scroller::~Scroller() { |
| 192 } |
| 193 |
| 194 bool Scroller::ComputeScrollOffset(base::TimeTicks time, |
| 195 gfx::Vector2dF* offset, |
| 196 gfx::Vector2dF* velocity) { |
| 197 DCHECK(offset); |
| 198 DCHECK(velocity); |
| 199 if (!ComputeScrollOffsetInternal(time)) { |
| 200 *offset = gfx::Vector2dF(GetFinalX(), GetFinalY()); |
| 201 *velocity = gfx::Vector2dF(); |
| 202 return false; |
| 203 } |
| 204 |
| 205 *offset = gfx::Vector2dF(GetCurrX(), GetCurrY()); |
| 206 *velocity = gfx::Vector2dF(GetCurrVelocityX(), GetCurrVelocityY()); |
| 207 return true; |
| 208 } |
193 | 209 |
194 void Scroller::StartScroll(float start_x, | 210 void Scroller::StartScroll(float start_x, |
195 float start_y, | 211 float start_y, |
196 float dx, | 212 float dx, |
197 float dy, | 213 float dy, |
198 base::TimeTicks start_time) { | 214 base::TimeTicks start_time) { |
199 StartScroll(start_x, | 215 StartScroll(start_x, |
200 start_y, | 216 start_y, |
201 dx, | 217 dx, |
202 dy, | 218 dy, |
203 start_time, | 219 start_time, |
204 base::TimeDelta::FromMilliseconds(kDefaultDurationMs)); | 220 base::TimeDelta::FromMilliseconds(kDefaultDurationMs)); |
205 } | 221 } |
206 | 222 |
207 void Scroller::StartScroll(float start_x, | 223 void Scroller::StartScroll(float start_x, |
208 float start_y, | 224 float start_y, |
209 float dx, | 225 float dx, |
210 float dy, | 226 float dy, |
211 base::TimeTicks start_time, | 227 base::TimeTicks start_time, |
212 base::TimeDelta duration) { | 228 base::TimeDelta duration) { |
| 229 DCHECK_GT(duration.ToInternalValue(), 0); |
213 mode_ = SCROLL_MODE; | 230 mode_ = SCROLL_MODE; |
214 finished_ = false; | 231 finished_ = false; |
215 duration_ = duration; | 232 duration_ = duration; |
216 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); | 233 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); |
217 start_time_ = start_time; | 234 start_time_ = start_time; |
218 curr_x_ = start_x_ = start_x; | 235 curr_x_ = start_x_ = start_x; |
219 curr_y_ = start_y_ = start_y; | 236 curr_y_ = start_y_ = start_y; |
220 final_x_ = start_x + dx; | 237 final_x_ = start_x + dx; |
221 final_y_ = start_y + dy; | 238 final_y_ = start_y + dy; |
222 RecomputeDeltas(); | 239 RecomputeDeltas(); |
223 curr_time_ = start_time_; | 240 curr_time_ = start_time_; |
224 } | 241 } |
225 | 242 |
226 void Scroller::Fling(float start_x, | 243 void Scroller::Fling(float start_x, |
227 float start_y, | 244 float start_y, |
228 float velocity_x, | 245 float velocity_x, |
229 float velocity_y, | 246 float velocity_y, |
230 float min_x, | 247 float min_x, |
231 float max_x, | 248 float max_x, |
232 float min_y, | 249 float min_y, |
233 float max_y, | 250 float max_y, |
234 base::TimeTicks start_time) { | 251 base::TimeTicks start_time) { |
| 252 DCHECK(velocity_x || velocity_y); |
| 253 |
235 // Continue a scroll or fling in progress. | 254 // Continue a scroll or fling in progress. |
236 if (flywheel_enabled_ && !finished_) { | 255 if (flywheel_enabled_ && !finished_) { |
237 float old_velocity_x = GetCurrVelocityX(); | 256 float old_velocity_x = GetCurrVelocityX(); |
238 float old_velocity_y = GetCurrVelocityY(); | 257 float old_velocity_y = GetCurrVelocityY(); |
239 if (Signum(velocity_x) == Signum(old_velocity_x) && | 258 if (Signum(velocity_x) == Signum(old_velocity_x) && |
240 Signum(velocity_y) == Signum(old_velocity_y)) { | 259 Signum(velocity_y) == Signum(old_velocity_y)) { |
241 velocity_x += old_velocity_x; | 260 velocity_x += old_velocity_x; |
242 velocity_y += old_velocity_y; | 261 velocity_y += old_velocity_y; |
243 } | 262 } |
244 } | 263 } |
245 | 264 |
246 mode_ = FLING_MODE; | 265 mode_ = FLING_MODE; |
247 finished_ = false; | 266 finished_ = false; |
248 | 267 |
249 float velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y); | 268 float velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y); |
250 | 269 |
251 velocity_ = velocity; | 270 velocity_ = velocity; |
252 duration_ = GetSplineFlingDuration(velocity); | 271 duration_ = GetSplineFlingDuration(velocity); |
| 272 DCHECK_GT(duration_.ToInternalValue(), 0); |
253 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); | 273 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); |
254 start_time_ = start_time; | 274 start_time_ = start_time; |
255 curr_time_ = start_time_; | 275 curr_time_ = start_time_; |
256 curr_x_ = start_x_ = start_x; | 276 curr_x_ = start_x_ = start_x; |
257 curr_y_ = start_y_ = start_y; | 277 curr_y_ = start_y_ = start_y; |
258 | 278 |
259 float coeff_x = velocity == 0 ? 1.0f : velocity_x / velocity; | 279 float coeff_x = velocity == 0 ? 1.0f : velocity_x / velocity; |
260 float coeff_y = velocity == 0 ? 1.0f : velocity_y / velocity; | 280 float coeff_y = velocity == 0 ? 1.0f : velocity_y / velocity; |
261 | 281 |
262 double total_distance = GetSplineFlingDistance(velocity); | 282 double total_distance = GetSplineFlingDistance(velocity); |
263 distance_ = total_distance * Signum(velocity); | 283 distance_ = total_distance * Signum(velocity); |
264 | 284 |
265 min_x_ = min_x; | 285 min_x_ = min_x; |
266 max_x_ = max_x; | 286 max_x_ = max_x; |
267 min_y_ = min_y; | 287 min_y_ = min_y; |
268 max_y_ = max_y; | 288 max_y_ = max_y; |
269 | 289 |
270 final_x_ = start_x + total_distance * coeff_x; | 290 final_x_ = start_x + total_distance * coeff_x; |
271 final_x_ = Clamped(final_x_, min_x_, max_x_); | 291 final_x_ = Clamped(final_x_, min_x_, max_x_); |
272 | 292 |
273 final_y_ = start_y + total_distance * coeff_y; | 293 final_y_ = start_y + total_distance * coeff_y; |
274 final_y_ = Clamped(final_y_, min_y_, max_y_); | 294 final_y_ = Clamped(final_y_, min_y_, max_y_); |
275 | 295 |
276 RecomputeDeltas(); | 296 RecomputeDeltas(); |
277 } | 297 } |
278 | 298 |
279 bool Scroller::ComputeScrollOffset(base::TimeTicks time) { | |
280 if (finished_) | |
281 return false; | |
282 | |
283 if (time == curr_time_) | |
284 return true; | |
285 | |
286 base::TimeDelta time_passed = time - start_time_; | |
287 | |
288 if (time_passed < base::TimeDelta()) { | |
289 time_passed = base::TimeDelta(); | |
290 } | |
291 | |
292 if (time_passed >= duration_) { | |
293 curr_x_ = final_x_; | |
294 curr_y_ = final_y_; | |
295 curr_time_ = start_time_ + duration_; | |
296 finished_ = true; | |
297 return true; | |
298 } | |
299 | |
300 curr_time_ = time; | |
301 | |
302 const float t = time_passed.InSecondsF() * duration_seconds_reciprocal_; | |
303 | |
304 switch (mode_) { | |
305 case UNDEFINED: | |
306 NOTREACHED() << "|StartScroll()| or |Fling()| must be called prior to " | |
307 "scroll offset computation."; | |
308 return false; | |
309 | |
310 case SCROLL_MODE: { | |
311 float x = g_viscosity_constants.Get().ApplyViscosity(t); | |
312 | |
313 curr_x_ = start_x_ + x * delta_x_; | |
314 curr_y_ = start_y_ + x * delta_y_; | |
315 } break; | |
316 | |
317 case FLING_MODE: { | |
318 float distance_coef = 1.f; | |
319 float velocity_coef = 0.f; | |
320 g_spline_constants.Get().CalculateCoefficients( | |
321 t, &distance_coef, &velocity_coef); | |
322 | |
323 curr_velocity_ = velocity_coef * distance_ * duration_seconds_reciprocal_; | |
324 | |
325 curr_x_ = start_x_ + distance_coef * delta_x_; | |
326 curr_x_ = Clamped(curr_x_, min_x_, max_x_); | |
327 | |
328 curr_y_ = start_y_ + distance_coef * delta_y_; | |
329 curr_y_ = Clamped(curr_y_, min_y_, max_y_); | |
330 | |
331 float diff_x = std::abs(curr_x_ - final_x_); | |
332 float diff_y = std::abs(curr_y_ - final_y_); | |
333 if (diff_x < kThresholdForFlingEnd && diff_y < kThresholdForFlingEnd) | |
334 finished_ = true; | |
335 } break; | |
336 } | |
337 | |
338 return true; | |
339 } | |
340 | |
341 void Scroller::ExtendDuration(base::TimeDelta extend) { | 299 void Scroller::ExtendDuration(base::TimeDelta extend) { |
342 base::TimeDelta passed = GetTimePassed(); | 300 base::TimeDelta passed = GetTimePassed(); |
343 duration_ = passed + extend; | 301 duration_ = passed + extend; |
344 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); | 302 duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF(); |
345 finished_ = false; | 303 finished_ = false; |
346 } | 304 } |
347 | 305 |
348 void Scroller::SetFinalX(float new_x) { | 306 void Scroller::SetFinalX(float new_x) { |
349 final_x_ = new_x; | 307 final_x_ = new_x; |
350 finished_ = false; | 308 finished_ = false; |
351 RecomputeDeltas(); | 309 RecomputeDeltas(); |
352 } | 310 } |
353 | 311 |
354 void Scroller::SetFinalY(float new_y) { | 312 void Scroller::SetFinalY(float new_y) { |
355 final_y_ = new_y; | 313 final_y_ = new_y; |
356 finished_ = false; | 314 finished_ = false; |
357 RecomputeDeltas(); | 315 RecomputeDeltas(); |
358 } | 316 } |
359 | 317 |
360 void Scroller::AbortAnimation() { | 318 void Scroller::AbortAnimation() { |
361 curr_x_ = final_x_; | 319 curr_x_ = final_x_; |
362 curr_y_ = final_y_; | 320 curr_y_ = final_y_; |
363 curr_velocity_ = 0; | 321 curr_velocity_ = 0; |
364 curr_time_ = start_time_ + duration_; | 322 curr_time_ = start_time_ + duration_; |
365 finished_ = true; | 323 finished_ = true; |
366 } | 324 } |
367 | 325 |
368 void Scroller::ForceFinished(bool finished) { finished_ = finished; } | 326 void Scroller::ForceFinished(bool finished) { |
| 327 finished_ = finished; |
| 328 } |
369 | 329 |
370 bool Scroller::IsFinished() const { return finished_; } | 330 bool Scroller::IsFinished() const { |
| 331 return finished_; |
| 332 } |
371 | 333 |
372 base::TimeDelta Scroller::GetTimePassed() const { | 334 base::TimeDelta Scroller::GetTimePassed() const { |
373 return curr_time_ - start_time_; | 335 return curr_time_ - start_time_; |
374 } | 336 } |
375 | 337 |
376 base::TimeDelta Scroller::GetDuration() const { return duration_; } | 338 base::TimeDelta Scroller::GetDuration() const { |
| 339 return duration_; |
| 340 } |
377 | 341 |
378 float Scroller::GetCurrX() const { return curr_x_; } | 342 float Scroller::GetCurrX() const { |
| 343 return curr_x_; |
| 344 } |
379 | 345 |
380 float Scroller::GetCurrY() const { return curr_y_; } | 346 float Scroller::GetCurrY() const { |
| 347 return curr_y_; |
| 348 } |
381 | 349 |
382 float Scroller::GetCurrVelocity() const { | 350 float Scroller::GetCurrVelocity() const { |
383 if (finished_) | 351 if (finished_) |
384 return 0; | 352 return 0; |
385 if (mode_ == FLING_MODE) | 353 if (mode_ == FLING_MODE) |
386 return curr_velocity_; | 354 return curr_velocity_; |
387 return velocity_ - deceleration_ * GetTimePassed().InSecondsF() * 0.5f; | 355 return velocity_ - deceleration_ * GetTimePassed().InSecondsF() * 0.5f; |
388 } | 356 } |
389 | 357 |
390 float Scroller::GetCurrVelocityX() const { | 358 float Scroller::GetCurrVelocityX() const { |
391 return delta_x_norm_ * GetCurrVelocity(); | 359 return delta_x_norm_ * GetCurrVelocity(); |
392 } | 360 } |
393 | 361 |
394 float Scroller::GetCurrVelocityY() const { | 362 float Scroller::GetCurrVelocityY() const { |
395 return delta_y_norm_ * GetCurrVelocity(); | 363 return delta_y_norm_ * GetCurrVelocity(); |
396 } | 364 } |
397 | 365 |
398 float Scroller::GetStartX() const { return start_x_; } | 366 float Scroller::GetStartX() const { |
| 367 return start_x_; |
| 368 } |
399 | 369 |
400 float Scroller::GetStartY() const { return start_y_; } | 370 float Scroller::GetStartY() const { |
| 371 return start_y_; |
| 372 } |
401 | 373 |
402 float Scroller::GetFinalX() const { return final_x_; } | 374 float Scroller::GetFinalX() const { |
| 375 return final_x_; |
| 376 } |
403 | 377 |
404 float Scroller::GetFinalY() const { return final_y_; } | 378 float Scroller::GetFinalY() const { |
| 379 return final_y_; |
| 380 } |
405 | 381 |
406 bool Scroller::IsScrollingInDirection(float xvel, float yvel) const { | 382 bool Scroller::IsScrollingInDirection(float xvel, float yvel) const { |
407 return !finished_ && Signum(xvel) == Signum(delta_x_) && | 383 return !finished_ && Signum(xvel) == Signum(delta_x_) && |
408 Signum(yvel) == Signum(delta_y_); | 384 Signum(yvel) == Signum(delta_y_); |
409 } | 385 } |
410 | 386 |
| 387 bool Scroller::ComputeScrollOffsetInternal(base::TimeTicks time) { |
| 388 if (finished_) |
| 389 return false; |
| 390 |
| 391 if (time <= start_time_) |
| 392 return true; |
| 393 |
| 394 if (time == curr_time_) |
| 395 return true; |
| 396 |
| 397 base::TimeDelta time_passed = time - start_time_; |
| 398 if (time_passed >= duration_) { |
| 399 AbortAnimation(); |
| 400 return false; |
| 401 } |
| 402 |
| 403 curr_time_ = time; |
| 404 |
| 405 const float u = time_passed.InSecondsF() * duration_seconds_reciprocal_; |
| 406 switch (mode_) { |
| 407 case UNDEFINED: |
| 408 NOTREACHED() << "|StartScroll()| or |Fling()| must be called prior to " |
| 409 "scroll offset computation."; |
| 410 return false; |
| 411 |
| 412 case SCROLL_MODE: { |
| 413 float x = g_viscosity_constants.Get().ApplyViscosity(u); |
| 414 |
| 415 curr_x_ = start_x_ + x * delta_x_; |
| 416 curr_y_ = start_y_ + x * delta_y_; |
| 417 } break; |
| 418 |
| 419 case FLING_MODE: { |
| 420 float distance_coef = 1.f; |
| 421 float velocity_coef = 0.f; |
| 422 g_spline_constants.Get().CalculateCoefficients( |
| 423 u, &distance_coef, &velocity_coef); |
| 424 |
| 425 curr_velocity_ = velocity_coef * distance_ * duration_seconds_reciprocal_; |
| 426 |
| 427 curr_x_ = start_x_ + distance_coef * delta_x_; |
| 428 curr_x_ = Clamped(curr_x_, min_x_, max_x_); |
| 429 |
| 430 curr_y_ = start_y_ + distance_coef * delta_y_; |
| 431 curr_y_ = Clamped(curr_y_, min_y_, max_y_); |
| 432 |
| 433 float diff_x = std::abs(curr_x_ - final_x_); |
| 434 float diff_y = std::abs(curr_y_ - final_y_); |
| 435 if (diff_x < kThresholdForFlingEnd && diff_y < kThresholdForFlingEnd) |
| 436 AbortAnimation(); |
| 437 } break; |
| 438 } |
| 439 |
| 440 return !finished_; |
| 441 } |
| 442 |
411 void Scroller::RecomputeDeltas() { | 443 void Scroller::RecomputeDeltas() { |
412 delta_x_ = final_x_ - start_x_; | 444 delta_x_ = final_x_ - start_x_; |
413 delta_y_ = final_y_ - start_y_; | 445 delta_y_ = final_y_ - start_y_; |
414 | 446 |
415 const float hyp = std::sqrt(delta_x_ * delta_x_ + delta_y_ * delta_y_); | 447 const float hyp = std::sqrt(delta_x_ * delta_x_ + delta_y_ * delta_y_); |
416 if (hyp > kEpsilon) { | 448 if (hyp > kEpsilon) { |
417 delta_x_norm_ = delta_x_ / hyp; | 449 delta_x_norm_ = delta_x_ / hyp; |
418 delta_y_norm_ = delta_y_ / hyp; | 450 delta_y_norm_ = delta_y_ / hyp; |
419 } else { | 451 } else { |
420 delta_x_norm_ = delta_y_norm_ = 1; | 452 delta_x_norm_ = delta_y_norm_ = 1; |
(...skipping 13 matching lines...) Expand all Loading... |
434 base::Time::kMicrosecondsPerSecond); | 466 base::Time::kMicrosecondsPerSecond); |
435 } | 467 } |
436 | 468 |
437 double Scroller::GetSplineFlingDistance(float velocity) const { | 469 double Scroller::GetSplineFlingDistance(float velocity) const { |
438 const double l = GetSplineDeceleration(velocity); | 470 const double l = GetSplineDeceleration(velocity); |
439 const double decel_minus_one = kDecelerationRate - 1.0; | 471 const double decel_minus_one = kDecelerationRate - 1.0; |
440 return fling_friction_ * tuning_coeff_ * | 472 return fling_friction_ * tuning_coeff_ * |
441 std::exp(kDecelerationRate / decel_minus_one * l); | 473 std::exp(kDecelerationRate / decel_minus_one * l); |
442 } | 474 } |
443 | 475 |
444 } // namespace gfx | 476 } // namespace ui |
OLD | NEW |