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 11namespace cc { 12 13ScrollbarAnimationController::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 26ScrollbarAnimationController::~ScrollbarAnimationController() { 27} 28 29void 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 45float 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 52void ScrollbarAnimationController::DidScrollBegin() { 53 currently_scrolling_ = true; 54} 55 56void 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 68void ScrollbarAnimationController::DidScrollEnd() { 69 if (scroll_gesture_has_scrolled_) { 70 PostDelayedFade(); 71 scroll_gesture_has_scrolled_ = false; 72 } 73 74 currently_scrolling_ = false; 75} 76 77void 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 85void ScrollbarAnimationController::StartAnimation() { 86 delayed_scrollbar_fade_.Cancel(); 87 is_animating_ = true; 88 last_awaken_time_ = base::TimeTicks(); 89 client_->SetNeedsScrollbarAnimationFrame(); 90} 91 92void ScrollbarAnimationController::StopAnimation() { 93 is_animating_ = false; 94} 95 96} // namespace cc 97