Chromium Code Reviews| Index: cc/animation/scroll_offset_animation_curve.cc |
| diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc |
| index b207994c092a327a70c753d99b7c93f4446bf4c2..70297044d67c40adfad5f83cd0f9a7d4b3570280 100644 |
| --- a/cc/animation/scroll_offset_animation_curve.cc |
| +++ b/cc/animation/scroll_offset_animation_curve.cc |
| @@ -30,6 +30,8 @@ const double kInverseDeltaSlope = |
| const double kInverseDeltaOffset = |
| kInverseDeltaMaxDuration - kInverseDeltaRampStartPx * kInverseDeltaSlope; |
| +const double kMinDuration = 5.0; |
| + |
| namespace cc { |
| namespace { |
| @@ -41,7 +43,8 @@ static float MaximumDimension(const gfx::Vector2dF& delta) { |
| } |
| static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta, |
| - DurationBehavior behavior) { |
| + DurationBehavior behavior, |
| + base::TimeDelta jank_adjustment) { |
| double duration = kConstantDuration; |
| switch (behavior) { |
| case DurationBehavior::CONSTANT: |
| @@ -60,8 +63,17 @@ static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta, |
| default: |
| NOTREACHED(); |
| } |
| - return base::TimeDelta::FromMicroseconds(duration / kDurationDivisor * |
| - base::Time::kMicrosecondsPerSecond); |
| + |
| + base::TimeDelta td = base::TimeDelta::FromMicroseconds( |
| + duration / kDurationDivisor * base::Time::kMicrosecondsPerSecond); |
| + base::TimeDelta min_td = base::TimeDelta::FromMicroseconds( |
| + kMinDuration / kDurationDivisor * base::Time::kMicrosecondsPerSecond); |
| + // jank_adjustment is the time delay between now and when we were actually |
| + // asked to scroll. If the delay is large, setting the duration to 0 will |
| + // scroll to the target position instantly. |
| + if (td - jank_adjustment > min_td) |
| + return td - jank_adjustment; |
| + return base::TimeDelta(); |
|
ymalik
2016/06/21 23:46:02
@skobes, If the animation duration is < 83ms, this
|
| } |
| static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity( |
| @@ -98,11 +110,13 @@ ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve( |
| ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() {} |
| void ScrollOffsetAnimationCurve::SetInitialValue( |
| - const gfx::ScrollOffset& initial_value) { |
| + const gfx::ScrollOffset& initial_value, |
| + base::TimeDelta jank_adjustment) { |
| initial_value_ = initial_value; |
| has_set_initial_value_ = true; |
| - total_animation_duration_ = SegmentDuration( |
| - target_value_.DeltaFrom(initial_value_), duration_behavior_); |
| + total_animation_duration_ = |
| + SegmentDuration(target_value_.DeltaFrom(initial_value_), |
| + duration_behavior_, jank_adjustment); |
| } |
| bool ScrollOffsetAnimationCurve::HasSetInitialValue() const { |
| @@ -120,12 +134,12 @@ gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue( |
| base::TimeDelta duration = total_animation_duration_ - last_retarget_; |
| t -= last_retarget_; |
| - if (t <= base::TimeDelta()) |
| - return initial_value_; |
| - |
| if (t >= duration) |
| return target_value_; |
| + if (t <= base::TimeDelta()) |
| + return initial_value_; |
| + |
| double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration)); |
| return gfx::ScrollOffset( |
| gfx::Tween::FloatValueBetween( |
| @@ -201,6 +215,13 @@ void ScrollOffsetAnimationCurve::UpdateTarget( |
| double old_duration = |
| (total_animation_duration_ - last_retarget_).InSecondsF(); |
| + |
| + if (old_duration < kEpsilon) { |
| + // We had an almost instant animation previously, don't try to animate. |
| + target_value_ = new_target; |
| + return; |
| + } |
| + |
|
ymalik
2016/06/21 23:46:02
Reasoning: I think updating an animation which had
|
| double old_normalized_velocity = timing_function_->Velocity( |
| (t - last_retarget_.InSecondsF()) / old_duration); |
| @@ -208,7 +229,8 @@ void ScrollOffsetAnimationCurve::UpdateTarget( |
| // segment duration. This minimizes the "rubber-band" bouncing effect when |
| // old_normalized_velocity is large and new_delta is small. |
| double new_duration = |
| - std::min(SegmentDuration(new_delta, duration_behavior_).InSecondsF(), |
| + std::min(SegmentDuration(new_delta, duration_behavior_, base::TimeDelta()) |
| + .InSecondsF(), |
| VelocityBasedDurationBound(old_delta, old_normalized_velocity, |
| old_duration, new_delta)); |