scrollbar_animation_controller_linear_fade.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright 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
5#include "cc/animation/scrollbar_animation_controller_linear_fade.h"
6
7#include "base/time/time.h"
8#include "cc/layers/layer_impl.h"
9#include "cc/layers/scrollbar_layer_impl_base.h"
10
11namespace cc {
12
13scoped_ptr<ScrollbarAnimationControllerLinearFade>
14ScrollbarAnimationControllerLinearFade::Create(LayerImpl* scroll_layer,
15                                               base::TimeDelta fadeout_delay,
16                                               base::TimeDelta fadeout_length) {
17  return make_scoped_ptr(new ScrollbarAnimationControllerLinearFade(
18      scroll_layer, fadeout_delay, fadeout_length));
19}
20
21ScrollbarAnimationControllerLinearFade::ScrollbarAnimationControllerLinearFade(
22    LayerImpl* scroll_layer,
23    base::TimeDelta fadeout_delay,
24    base::TimeDelta fadeout_length)
25    : ScrollbarAnimationController(),
26      scroll_layer_(scroll_layer),
27      scroll_gesture_in_progress_(false),
28      scroll_gesture_has_scrolled_(false),
29      fadeout_delay_(fadeout_delay),
30      fadeout_length_(fadeout_length) {}
31
32ScrollbarAnimationControllerLinearFade::
33    ~ScrollbarAnimationControllerLinearFade() {}
34
35bool ScrollbarAnimationControllerLinearFade::IsAnimating() const {
36  return !last_awaken_time_.is_null();
37}
38
39base::TimeDelta ScrollbarAnimationControllerLinearFade::DelayBeforeStart(
40    base::TimeTicks now) const {
41  if (now > last_awaken_time_ + fadeout_delay_)
42    return base::TimeDelta();
43  return fadeout_delay_ - (now - last_awaken_time_);
44}
45
46bool ScrollbarAnimationControllerLinearFade::Animate(base::TimeTicks now) {
47  float opacity = OpacityAtTime(now);
48  ApplyOpacityToScrollbars(opacity);
49  if (!opacity)
50    last_awaken_time_ = base::TimeTicks();
51  return IsAnimating() && DelayBeforeStart(now) == base::TimeDelta();
52}
53
54void ScrollbarAnimationControllerLinearFade::DidScrollGestureBegin() {
55  scroll_gesture_in_progress_ = true;
56  scroll_gesture_has_scrolled_ = false;
57}
58
59void ScrollbarAnimationControllerLinearFade::DidScrollGestureEnd(
60    base::TimeTicks now) {
61  // The animation should not be triggered if no scrolling has occurred.
62  if (scroll_gesture_has_scrolled_)
63    last_awaken_time_ = now;
64  scroll_gesture_has_scrolled_ = false;
65  scroll_gesture_in_progress_ = false;
66}
67
68bool ScrollbarAnimationControllerLinearFade::DidScrollUpdate(
69    base::TimeTicks now) {
70  ApplyOpacityToScrollbars(1.0f);
71  // The animation should only be activated if the scroll updated occurred
72  // programatically, outside the scope of a scroll gesture.
73  if (scroll_gesture_in_progress_) {
74    last_awaken_time_ = base::TimeTicks();
75    scroll_gesture_has_scrolled_ = true;
76    return true;
77  }
78
79  last_awaken_time_ = now;
80  return false;
81}
82
83float ScrollbarAnimationControllerLinearFade::OpacityAtTime(
84    base::TimeTicks now) {
85  if (scroll_gesture_has_scrolled_)
86    return 1.0f;
87
88  if (last_awaken_time_.is_null())
89    return 0.0f;
90
91  base::TimeDelta delta = now - last_awaken_time_;
92
93  if (delta <= fadeout_delay_)
94    return 1.0f;
95  if (delta < fadeout_delay_ + fadeout_length_) {
96    return (fadeout_delay_ + fadeout_length_ - delta).InSecondsF() /
97           fadeout_length_.InSecondsF();
98  }
99  return 0.0f;
100}
101
102void ScrollbarAnimationControllerLinearFade::ApplyOpacityToScrollbars(
103    float opacity) {
104  ScrollbarLayerImplBase* horizontal_scrollbar =
105      scroll_layer_->horizontal_scrollbar_layer();
106  if (horizontal_scrollbar)
107    horizontal_scrollbar->SetOpacity(opacity);
108
109  ScrollbarLayerImplBase* vertical_scrollbar =
110      scroll_layer_->vertical_scrollbar_layer();
111  if (vertical_scrollbar)
112    vertical_scrollbar->SetOpacity(opacity);
113}
114
115}  // namespace cc
116