Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: ui/gfx/geometry/cubic_bezier.cc

Issue 143413020: Use a bezier timing function for the overview mode animation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/geometry/cubic_bezier.h ('k') | ui/gfx/geometry/cubic_bezier_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/geometry/cubic_bezier.h"
6
5 #include <algorithm> 7 #include <algorithm>
6 #include <cmath> 8 #include <cmath>
7 9
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "cc/animation/timing_function.h"
10 11
11 namespace cc { 12 namespace gfx {
12 13
13 namespace { 14 namespace {
14 15
15 static const double kBezierEpsilon = 1e-7; 16 static const double kBezierEpsilon = 1e-7;
16 static const int MAX_STEPS = 30; 17 static const int MAX_STEPS = 30;
17 18
18 static double eval_bezier(double x1, double x2, double t) { 19 static double eval_bezier(double x1, double x2, double t) {
19 const double x1_times_3 = 3.0 * x1; 20 const double x1_times_3 = 3.0 * x1;
20 const double x2_times_3 = 3.0 * x2; 21 const double x2_times_3 = 3.0 * x2;
21 const double h3 = x1_times_3; 22 const double h3 = x1_times_3;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // We should have terminated the above loop because we got close to x, not 57 // We should have terminated the above loop because we got close to x, not
57 // because we exceeded MAX_STEPS. Do a DCHECK here to confirm. 58 // because we exceeded MAX_STEPS. Do a DCHECK here to confirm.
58 DCHECK_GT(kBezierEpsilon, std::abs(eval_bezier(x1, x2, t) - x)); 59 DCHECK_GT(kBezierEpsilon, std::abs(eval_bezier(x1, x2, t) - x));
59 60
60 // Step 2. Return the interpolated y values at the t we computed above. 61 // Step 2. Return the interpolated y values at the t we computed above.
61 return eval_bezier(y1, y2, t); 62 return eval_bezier(y1, y2, t);
62 } 63 }
63 64
64 } // namespace 65 } // namespace
65 66
66 TimingFunction::TimingFunction() {} 67 CubicBezier::CubicBezier(double x1, double y1, double x2, double y2)
67 68 : x1_(x1),
68 TimingFunction::~TimingFunction() {} 69 y1_(y1),
69 70 x2_(x2),
70 double TimingFunction::Duration() const { 71 y2_(y2) {
71 return 1.0;
72 } 72 }
73 73
74 scoped_ptr<CubicBezierTimingFunction> CubicBezierTimingFunction::Create( 74 CubicBezier::~CubicBezier() {
75 double x1, double y1, double x2, double y2) {
76 return make_scoped_ptr(new CubicBezierTimingFunction(x1, y1, x2, y2));
77 } 75 }
78 76
79 CubicBezierTimingFunction::CubicBezierTimingFunction(double x1, 77 double CubicBezier::Solve(double x) const {
80 double y1, 78 return bezier_interp(x1_, y1_, x2_, y2_, x);
81 double x2,
82 double y2)
83 : x1_(x1), y1_(y1), x2_(x2), y2_(y2) {}
84
85 CubicBezierTimingFunction::~CubicBezierTimingFunction() {}
86
87 float CubicBezierTimingFunction::GetValue(double x) const {
88 return static_cast<float>(bezier_interp(x1_, y1_, x2_, y2_, x));
89 } 79 }
90 80
91 scoped_ptr<AnimationCurve> CubicBezierTimingFunction::Clone() const { 81 void CubicBezier::Range(double* min, double* max) const {
92 return make_scoped_ptr( 82 *min = 0;
93 new CubicBezierTimingFunction(*this)).PassAs<AnimationCurve>(); 83 *max = 1;
94 } 84 if (0 <= y1_ && y1_ < 1 && 0 <= y2_ && y2_ <= 1)
95
96 void CubicBezierTimingFunction::Range(float* min, float* max) const {
97 *min = 0.f;
98 *max = 1.f;
99 if (0.f <= y1_ && y1_ < 1.f && 0.f <= y2_ && y2_ <= 1.f)
100 return; 85 return;
101 86
102 // Represent the function's derivative in the form at^2 + bt + c. 87 // Represent the function's derivative in the form at^2 + bt + c.
103 float a = 3.f * (y1_ - y2_) + 1.f; 88 double a = 3 * (y1_ - y2_) + 1;
104 float b = 2.f * (y2_ - 2.f * y1_); 89 double b = 2 * (y2_ - 2 * y1_);
105 float c = y1_; 90 double c = y1_;
106 91
107 // Check if the derivative is constant. 92 // Check if the derivative is constant.
108 if (std::abs(a) < kBezierEpsilon && 93 if (std::abs(a) < kBezierEpsilon &&
109 std::abs(b) < kBezierEpsilon) 94 std::abs(b) < kBezierEpsilon)
110 return; 95 return;
111 96
112 // Zeros of the function's derivative. 97 // Zeros of the function's derivative.
113 float t_1 = 0.f; 98 double t_1 = 0;
114 float t_2 = 0.f; 99 double t_2 = 0;
115 100
116 if (std::abs(a) < kBezierEpsilon) { 101 if (std::abs(a) < kBezierEpsilon) {
117 // The function's derivative is linear. 102 // The function's derivative is linear.
118 t_1 = -c / b; 103 t_1 = -c / b;
119 } else { 104 } else {
120 // The function's derivative is a quadratic. We find the zeros of this 105 // The function's derivative is a quadratic. We find the zeros of this
121 // quadratic using the quadratic formula. 106 // quadratic using the quadratic formula.
122 float discriminant = b * b - 4 * a * c; 107 double discriminant = b * b - 4 * a * c;
123 if (discriminant < 0.f) 108 if (discriminant < 0)
124 return; 109 return;
125 float discriminant_sqrt = sqrt(discriminant); 110 double discriminant_sqrt = sqrt(discriminant);
126 t_1 = (-b + discriminant_sqrt) / (2.f * a); 111 t_1 = (-b + discriminant_sqrt) / (2 * a);
127 t_2 = (-b - discriminant_sqrt) / (2.f * a); 112 t_2 = (-b - discriminant_sqrt) / (2 * a);
128 } 113 }
129 114
130 float sol_1 = 0.f; 115 double sol_1 = 0;
131 float sol_2 = 0.f; 116 double sol_2 = 0;
132 117
133 if (0.f < t_1 && t_1 < 1.f) 118 if (0 < t_1 && t_1 < 1)
134 sol_1 = eval_bezier(y1_, y2_, t_1); 119 sol_1 = eval_bezier(y1_, y2_, t_1);
135 120
136 if (0.f < t_2 && t_2 < 1.f) 121 if (0 < t_2 && t_2 < 1)
137 sol_2 = eval_bezier(y1_, y2_, t_2); 122 sol_2 = eval_bezier(y1_, y2_, t_2);
138 123
139 *min = std::min(std::min(*min, sol_1), sol_2); 124 *min = std::min(std::min(*min, sol_1), sol_2);
140 *max = std::max(std::max(*max, sol_1), sol_2); 125 *max = std::max(std::max(*max, sol_1), sol_2);
141 } 126 }
142 127
143 // These numbers come from 128 } // namespace gfx
144 // http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag.
145 scoped_ptr<TimingFunction> EaseTimingFunction::Create() {
146 return CubicBezierTimingFunction::Create(
147 0.25, 0.1, 0.25, 1.0).PassAs<TimingFunction>();
148 }
149
150 scoped_ptr<TimingFunction> EaseInTimingFunction::Create() {
151 return CubicBezierTimingFunction::Create(
152 0.42, 0.0, 1.0, 1.0).PassAs<TimingFunction>();
153 }
154
155 scoped_ptr<TimingFunction> EaseOutTimingFunction::Create() {
156 return CubicBezierTimingFunction::Create(
157 0.0, 0.0, 0.58, 1.0).PassAs<TimingFunction>();
158 }
159
160 scoped_ptr<TimingFunction> EaseInOutTimingFunction::Create() {
161 return CubicBezierTimingFunction::Create(
162 0.42, 0.0, 0.58, 1).PassAs<TimingFunction>();
163 }
164
165 } // namespace cc
OLDNEW
« no previous file with comments | « ui/gfx/geometry/cubic_bezier.h ('k') | ui/gfx/geometry/cubic_bezier_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698