scroll_animator.cc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/views/animation/scroll_animator.h"
  5. #include <algorithm>
  6. #include <cmath>
  7. #include "base/check.h"
  8. #include "ui/gfx/animation/slide_animation.h"
  9. namespace {
  10. constexpr float kDefaultAcceleration = -1500.0f; // in pixels per second^2
  11. // Assumes that d0 == 0.0f
  12. float GetPosition(float v0, float a, float t) {
  13. float max_t = -v0 / a;
  14. if (t > max_t)
  15. t = max_t;
  16. return t * (v0 + 0.5f * a * t);
  17. }
  18. float GetDelta(float v0, float a, float t1, float t2) {
  19. return GetPosition(v0, a, t2) - GetPosition(v0, a, t1);
  20. }
  21. } // namespace
  22. namespace views {
  23. ScrollAnimator::ScrollAnimator(ScrollDelegate* delegate)
  24. : delegate_(delegate), acceleration_(kDefaultAcceleration) {
  25. DCHECK(delegate);
  26. }
  27. ScrollAnimator::~ScrollAnimator() {
  28. Stop();
  29. }
  30. void ScrollAnimator::Start(float velocity_x, float velocity_y) {
  31. if (acceleration_ >= 0.0f)
  32. acceleration_ = kDefaultAcceleration;
  33. float v = std::max(fabs(velocity_x), fabs(velocity_y));
  34. last_t_ = 0.0f;
  35. velocity_x_ = velocity_x * velocity_multiplier_;
  36. velocity_y_ = velocity_y * velocity_multiplier_;
  37. duration_ = -v / acceleration_; // in seconds
  38. animation_ = std::make_unique<gfx::SlideAnimation>(this);
  39. animation_->SetSlideDuration(base::Seconds(duration_));
  40. animation_->Show();
  41. }
  42. void ScrollAnimator::Stop() {
  43. velocity_x_ = velocity_y_ = last_t_ = duration_ = 0.0f;
  44. animation_.reset();
  45. }
  46. void ScrollAnimator::AnimationEnded(const gfx::Animation* animation) {
  47. Stop();
  48. delegate_->OnFlingScrollEnded();
  49. }
  50. void ScrollAnimator::AnimationProgressed(const gfx::Animation* animation) {
  51. float t = static_cast<float>(animation->GetCurrentValue()) * duration_;
  52. float a_x = velocity_x_ > 0 ? acceleration_ : -acceleration_;
  53. float a_y = velocity_y_ > 0 ? acceleration_ : -acceleration_;
  54. float dx = GetDelta(velocity_x_, a_x, last_t_, t);
  55. float dy = GetDelta(velocity_y_, a_y, last_t_, t);
  56. last_t_ = t;
  57. delegate_->OnScroll(dx, dy);
  58. }
  59. void ScrollAnimator::AnimationCanceled(const gfx::Animation* animation) {
  60. Stop();
  61. }
  62. } // namespace views