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 "chrome/browser/ui/autofill/loading_animation.h"
6
7#include "base/logging.h"
8#include "ui/gfx/animation/tween.h"
9
10namespace autofill {
11
12// Duration of one cycle of the animation.
13static const int kDurationMs = 1800;
14
15// The frame rate of the animation.
16static const int kHertz = 60;
17
18LoadingAnimation::LoadingAnimation(gfx::AnimationDelegate* delegate,
19                                   int font_height)
20    : LinearAnimation(kDurationMs, kHertz, delegate),
21      first_cycle_(true),
22      font_height_(font_height) {}
23
24LoadingAnimation::~LoadingAnimation() {}
25
26void LoadingAnimation::Step(base::TimeTicks time_now) {
27  LinearAnimation::Step(time_now);
28
29  if (!is_animating()) {
30    first_cycle_ = false;
31    Start();
32  }
33}
34
35double LoadingAnimation::GetCurrentValueForDot(size_t dot_i) const {
36  double base_value = gfx::LinearAnimation::GetCurrentValue();
37
38  const double kSecondDotDelayMs = 100.0;
39  const double kThirdDotDelayMs = 300.0;
40  if (dot_i == 1)
41    base_value -= kSecondDotDelayMs / kDurationMs;
42  else if (dot_i == 2)
43    base_value -= kThirdDotDelayMs / kDurationMs;
44
45  if (base_value < 0.0)
46    base_value = first_cycle_ ? 0.0 : base_value + 1.0;
47
48  double value = gfx::Tween::CalculateValue(gfx::Tween::EASE_OUT, base_value);
49
50  static AnimationFrame kAnimationFrames[] = {
51    { 0.0, 0.0 },
52    { 0.55, 0.0 },
53    { 0.6, -1.0 },
54    { 0.8, 0.3 },
55    { 0.9, -0.2 },
56    { 0.95, 0.1 },
57    { 1.0, 0.0 },
58  };
59
60  for (size_t i = 0; i < arraysize(kAnimationFrames); ++i) {
61    if (value > kAnimationFrames[i].value)
62      continue;
63
64    double position;
65    if (i == 0) {
66      position = kAnimationFrames[i].position;
67    } else {
68      double inter_frame_value =
69          (value - kAnimationFrames[i - 1].value) /
70          (kAnimationFrames[i].value - kAnimationFrames[i - 1].value);
71      position = gfx::Tween::FloatValueBetween(inter_frame_value,
72                                               kAnimationFrames[i - 1].position,
73                                               kAnimationFrames[i].position);
74    }
75    return position * font_height_ / 2.0;
76  }
77
78  NOTREACHED();
79  return 0.0;
80}
81
82void LoadingAnimation::Reset() {
83  Stop();
84  first_cycle_ = true;
85}
86
87}  // namespace autofill
88