Home | History | Annotate | Download | only in animation
      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>
     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 
     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 
     45 ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
     46 }
     47 
     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 
     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 
     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 
     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 
     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
    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 
    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 
    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