Roll src/third_party/WebKit 2146135:dc7c4b0 (svn 202183:202185)
[chromium-blink-merge.git] / cc / animation / scrollbar_animation_controller_thinning.cc
blobaf6987e0e0b03ff23bfcfb713cfd22d9aa3ebef4
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"
12 namespace {
13 const float kIdleThicknessScale = 0.4f;
14 const float kIdleOpacity = 0.7f;
15 const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
18 namespace cc {
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,
29 duration));
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,
39 client,
40 delay_before_starting,
41 resize_delay_before_starting,
42 duration),
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;
64 StopAnimation();
68 void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() {
69 mouse_is_over_scrollbar_ = false;
70 mouse_is_near_scrollbar_ = false;
71 opacity_change_ = DECREASE;
72 thickness_change_ = DECREASE;
73 StartAnimation();
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_)
92 return;
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;
104 StartAnimation();
107 float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
108 float progress) {
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;
113 return ret;
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(
125 float new_value,
126 float current_value,
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;
132 return new_value;
135 void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
136 float opacity,
137 float thumb_thickness_scale) {
138 if (!scroll_layer_->scrollbars())
139 return;
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_)
149 : 0;
151 scrollbar->SetOpacity(effectiveOpacity);
152 scrollbar->SetThumbThicknessScaleFactor(AdjustScale(
153 thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(),
154 thickness_change_));
159 } // namespace cc