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.
5 #include "cc/animation/scrollbar_animation_controller_thinning.h"
7 #include "base/time/time.h"
8 #include "cc/layers/layer_impl.h"
9 #include "cc/layers/scrollbar_layer_impl_base.h"
10 #include "cc/trees/layer_tree_impl.h"
13 const float kIdleThicknessScale
= 0.4f
;
14 const float kIdleOpacity
= 0.7f
;
15 const float kDefaultMouseMoveDistanceToTriggerAnimation
= 25.f
;
20 scoped_ptr
<ScrollbarAnimationControllerThinning
>
21 ScrollbarAnimationControllerThinning::Create(
22 LayerImpl
* scroll_layer
,
23 ScrollbarAnimationControllerClient
* client
,
24 base::TimeDelta delay_before_starting
,
25 base::TimeDelta resize_delay_before_starting
,
26 base::TimeDelta duration
) {
27 return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
28 scroll_layer
, client
, delay_before_starting
, resize_delay_before_starting
,
32 ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
33 LayerImpl
* scroll_layer
,
34 ScrollbarAnimationControllerClient
* client
,
35 base::TimeDelta delay_before_starting
,
36 base::TimeDelta resize_delay_before_starting
,
37 base::TimeDelta duration
)
38 : ScrollbarAnimationController(scroll_layer
,
40 delay_before_starting
,
41 resize_delay_before_starting
,
43 mouse_is_over_scrollbar_(false),
44 mouse_is_near_scrollbar_(false),
45 thickness_change_(NONE
),
46 opacity_change_(NONE
),
47 mouse_move_distance_to_trigger_animation_(
48 kDefaultMouseMoveDistanceToTriggerAnimation
) {
49 ApplyOpacityAndThumbThicknessScale(kIdleOpacity
, kIdleThicknessScale
);
52 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
55 void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress
) {
56 float opacity
= OpacityAtAnimationProgress(progress
);
57 float thumb_thickness_scale
=
58 ThumbThicknessScaleAtAnimationProgress(progress
);
59 ApplyOpacityAndThumbThicknessScale(opacity
, thumb_thickness_scale
);
60 client_
->SetNeedsRedrawForScrollbarAnimation();
61 if (progress
== 1.f
) {
62 opacity_change_
= NONE
;
63 thickness_change_
= NONE
;
68 void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() {
69 mouse_is_over_scrollbar_
= false;
70 mouse_is_near_scrollbar_
= false;
71 opacity_change_
= DECREASE
;
72 thickness_change_
= DECREASE
;
76 void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize
) {
77 ScrollbarAnimationController::DidScrollUpdate(on_resize
);
78 ApplyOpacityAndThumbThicknessScale(
79 1, mouse_is_near_scrollbar_
? 1.f
: kIdleThicknessScale
);
81 if (!mouse_is_over_scrollbar_
)
82 opacity_change_
= DECREASE
;
85 void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance
) {
86 bool mouse_is_over_scrollbar
= distance
== 0.0;
87 bool mouse_is_near_scrollbar
=
88 distance
< mouse_move_distance_to_trigger_animation_
;
90 if (mouse_is_over_scrollbar
== mouse_is_over_scrollbar_
&&
91 mouse_is_near_scrollbar
== mouse_is_near_scrollbar_
)
94 if (mouse_is_over_scrollbar_
!= mouse_is_over_scrollbar
) {
95 mouse_is_over_scrollbar_
= mouse_is_over_scrollbar
;
96 opacity_change_
= mouse_is_over_scrollbar_
? INCREASE
: DECREASE
;
99 if (mouse_is_near_scrollbar_
!= mouse_is_near_scrollbar
) {
100 mouse_is_near_scrollbar_
= mouse_is_near_scrollbar
;
101 thickness_change_
= mouse_is_near_scrollbar_
? INCREASE
: DECREASE
;
107 float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
109 if (opacity_change_
== NONE
)
110 return mouse_is_over_scrollbar_
? 1.f
: kIdleOpacity
;
111 float factor
= opacity_change_
== INCREASE
? progress
: (1.f
- progress
);
112 float ret
= ((1.f
- kIdleOpacity
) * factor
) + kIdleOpacity
;
116 float ScrollbarAnimationControllerThinning::
117 ThumbThicknessScaleAtAnimationProgress(float progress
) {
118 if (thickness_change_
== NONE
)
119 return mouse_is_near_scrollbar_
? 1.f
: kIdleThicknessScale
;
120 float factor
= thickness_change_
== INCREASE
? progress
: (1.f
- progress
);
121 return ((1.f
- kIdleThicknessScale
) * factor
) + kIdleThicknessScale
;
124 float ScrollbarAnimationControllerThinning::AdjustScale(
127 AnimationChange animation_change
) {
128 if (animation_change
== INCREASE
&& current_value
> new_value
)
129 return current_value
;
130 if (animation_change
== DECREASE
&& current_value
< new_value
)
131 return current_value
;
135 void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
137 float thumb_thickness_scale
) {
138 if (!scroll_layer_
->scrollbars())
141 LayerImpl::ScrollbarSet
* scrollbars
= scroll_layer_
->scrollbars();
142 for (LayerImpl::ScrollbarSet::iterator it
= scrollbars
->begin();
143 it
!= scrollbars
->end(); ++it
) {
144 ScrollbarLayerImplBase
* scrollbar
= *it
;
145 if (scrollbar
->is_overlay_scrollbar()) {
146 float effectiveOpacity
=
147 scrollbar
->CanScrollOrientation()
148 ? AdjustScale(opacity
, scrollbar
->opacity(), opacity_change_
)
151 scrollbar
->SetOpacity(effectiveOpacity
);
152 scrollbar
->SetThumbThicknessScaleFactor(AdjustScale(
153 thumb_thickness_scale
, scrollbar
->thumb_thickness_scale_factor(),