• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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_thinning.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 
11 namespace {
12 const float kIdleThicknessScale = 0.4f;
13 const float kIdleOpacity = 0.7f;
14 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
15 }
16 
17 namespace cc {
18 
19 scoped_ptr<ScrollbarAnimationControllerThinning>
Create(LayerImpl * scroll_layer,ScrollbarAnimationControllerClient * client,base::TimeDelta delay_before_starting,base::TimeDelta duration)20 ScrollbarAnimationControllerThinning::Create(
21     LayerImpl* scroll_layer,
22     ScrollbarAnimationControllerClient* client,
23     base::TimeDelta delay_before_starting,
24     base::TimeDelta duration) {
25   return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
26       scroll_layer, client, delay_before_starting, duration));
27 }
28 
ScrollbarAnimationControllerThinning(LayerImpl * scroll_layer,ScrollbarAnimationControllerClient * client,base::TimeDelta delay_before_starting,base::TimeDelta duration)29 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
30     LayerImpl* scroll_layer,
31     ScrollbarAnimationControllerClient* client,
32     base::TimeDelta delay_before_starting,
33     base::TimeDelta duration)
34     : ScrollbarAnimationController(client, delay_before_starting, duration),
35       scroll_layer_(scroll_layer),
36       mouse_is_over_scrollbar_(false),
37       mouse_is_near_scrollbar_(false),
38       thickness_change_(NONE),
39       opacity_change_(NONE),
40       mouse_move_distance_to_trigger_animation_(
41           kDefaultMouseMoveDistanceToTriggerAnimation) {
42   ApplyOpacityAndThumbThicknessScale(kIdleOpacity, kIdleThicknessScale);
43 }
44 
~ScrollbarAnimationControllerThinning()45 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
46 }
47 
RunAnimationFrame(float progress)48 void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) {
49   float opacity = OpacityAtAnimationProgress(progress);
50   float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
51       progress);
52   ApplyOpacityAndThumbThicknessScale(opacity, thumb_thickness_scale);
53   if (progress == 1.f) {
54     opacity_change_ = NONE;
55     thickness_change_ = NONE;
56     StopAnimation();
57   }
58 }
59 
DidMouseMoveOffScrollbar()60 void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() {
61   mouse_is_over_scrollbar_ = false;
62   mouse_is_near_scrollbar_ = false;
63   opacity_change_ = DECREASE;
64   thickness_change_ = DECREASE;
65   StartAnimation();
66 }
67 
DidScrollUpdate()68 void ScrollbarAnimationControllerThinning::DidScrollUpdate() {
69   ScrollbarAnimationController::DidScrollUpdate();
70   ApplyOpacityAndThumbThicknessScale(
71     1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
72 
73   if (!mouse_is_over_scrollbar_)
74     opacity_change_ = DECREASE;
75 }
76 
DidMouseMoveNear(float distance)77 void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance) {
78   bool mouse_is_over_scrollbar = distance == 0.0;
79   bool mouse_is_near_scrollbar =
80       distance < mouse_move_distance_to_trigger_animation_;
81 
82   if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
83       mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
84     return;
85 
86   if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) {
87     mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
88     opacity_change_ = mouse_is_over_scrollbar_ ? INCREASE : DECREASE;
89   }
90 
91   if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) {
92     mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
93     thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
94   }
95 
96   StartAnimation();
97 }
98 
OpacityAtAnimationProgress(float progress)99 float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
100     float progress) {
101   if (opacity_change_ == NONE)
102     return mouse_is_over_scrollbar_ ? 1.f : kIdleOpacity;
103   float factor = opacity_change_ == INCREASE ? progress : (1.f - progress);
104   float ret = ((1.f - kIdleOpacity) * factor) + kIdleOpacity;
105   return ret;
106 }
107 
108 float
ThumbThicknessScaleAtAnimationProgress(float progress)109 ScrollbarAnimationControllerThinning::ThumbThicknessScaleAtAnimationProgress(
110     float progress) {
111   if (thickness_change_ == NONE)
112     return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale;
113   float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
114   return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale;
115 }
116 
AdjustScale(float new_value,float current_value,AnimationChange animation_change)117 float ScrollbarAnimationControllerThinning::AdjustScale(
118     float new_value,
119     float current_value,
120     AnimationChange animation_change) {
121   if (animation_change == INCREASE && current_value > new_value)
122     return current_value;
123   if (animation_change == DECREASE && current_value < new_value)
124     return current_value;
125   return new_value;
126 }
127 
ApplyOpacityAndThumbThicknessScale(float opacity,float thumb_thickness_scale)128 void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
129     float opacity, float thumb_thickness_scale) {
130   if (!scroll_layer_->scrollbars())
131     return;
132 
133   LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars();
134   for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
135        it != scrollbars->end();
136        ++it) {
137     ScrollbarLayerImplBase* scrollbar = *it;
138     if (scrollbar->is_overlay_scrollbar()) {
139       scrollbar->SetOpacity(
140           AdjustScale(opacity, scrollbar->opacity(), opacity_change_));
141       scrollbar->SetThumbThicknessScaleFactor(
142           AdjustScale(thumb_thickness_scale,
143                       scrollbar->thumb_thickness_scale_factor(),
144                       thickness_change_));
145     }
146   }
147 }
148 
149 }  // namespace cc
150