• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "cc/animation/scrollbar_animation_controller.h"
6 
7 #include <algorithm>
8 
9 #include "base/time/time.h"
10 
11 namespace cc {
12 
ScrollbarAnimationController(ScrollbarAnimationControllerClient * client,base::TimeDelta delay_before_starting,base::TimeDelta duration)13 ScrollbarAnimationController::ScrollbarAnimationController(
14     ScrollbarAnimationControllerClient* client,
15     base::TimeDelta delay_before_starting,
16     base::TimeDelta duration)
17     : client_(client),
18       delay_before_starting_(delay_before_starting),
19       duration_(duration),
20       is_animating_(false),
21       currently_scrolling_(false),
22       scroll_gesture_has_scrolled_(false),
23       weak_factory_(this) {
24 }
25 
~ScrollbarAnimationController()26 ScrollbarAnimationController::~ScrollbarAnimationController() {
27 }
28 
Animate(base::TimeTicks now)29 void ScrollbarAnimationController::Animate(base::TimeTicks now) {
30   if (!is_animating_)
31     return;
32 
33   if (last_awaken_time_.is_null())
34     last_awaken_time_ = now;
35 
36   float progress = AnimationProgressAtTime(now);
37   RunAnimationFrame(progress);
38 
39   if (is_animating_) {
40     delayed_scrollbar_fade_.Cancel();
41     client_->SetNeedsScrollbarAnimationFrame();
42   }
43 }
44 
AnimationProgressAtTime(base::TimeTicks now)45 float ScrollbarAnimationController::AnimationProgressAtTime(
46     base::TimeTicks now) {
47   base::TimeDelta delta = now - last_awaken_time_;
48   float progress = delta.InSecondsF() / duration_.InSecondsF();
49   return std::max(std::min(progress, 1.f), 0.f);
50 }
51 
DidScrollBegin()52 void ScrollbarAnimationController::DidScrollBegin() {
53   currently_scrolling_ = true;
54 }
55 
DidScrollUpdate()56 void ScrollbarAnimationController::DidScrollUpdate() {
57   StopAnimation();
58   delayed_scrollbar_fade_.Cancel();
59 
60   // As an optimization, we avoid spamming fade delay tasks during active fast
61   // scrolls.  But if we're not within one, we need to post every scroll update.
62   if (!currently_scrolling_)
63     PostDelayedFade();
64   else
65     scroll_gesture_has_scrolled_ = true;
66 }
67 
DidScrollEnd()68 void ScrollbarAnimationController::DidScrollEnd() {
69   if (scroll_gesture_has_scrolled_) {
70     PostDelayedFade();
71     scroll_gesture_has_scrolled_ = false;
72   }
73 
74   currently_scrolling_ = false;
75 }
76 
PostDelayedFade()77 void ScrollbarAnimationController::PostDelayedFade() {
78   delayed_scrollbar_fade_.Reset(
79       base::Bind(&ScrollbarAnimationController::StartAnimation,
80                  weak_factory_.GetWeakPtr()));
81   client_->PostDelayedScrollbarFade(delayed_scrollbar_fade_.callback(),
82                                     delay_before_starting_);
83 }
84 
StartAnimation()85 void ScrollbarAnimationController::StartAnimation() {
86   delayed_scrollbar_fade_.Cancel();
87   is_animating_ = true;
88   last_awaken_time_ = base::TimeTicks();
89   client_->SetNeedsScrollbarAnimationFrame();
90 }
91 
StopAnimation()92 void ScrollbarAnimationController::StopAnimation() {
93   is_animating_ = false;
94 }
95 
96 }  // namespace cc
97