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

Side by Side Diff: ui/gfx/interpolated_transform.cc

Issue 7273073: Animated Rotation (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Address reviewer comments Created 9 years, 3 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/interpolated_transform.h ('k') | ui/gfx/interpolated_transform_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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/interpolated_transform.h" 5 #include "ui/gfx/interpolated_transform.h"
6 6
7 #include <cmath>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
8 #include "ui/base/animation/tween.h" 10 #include "ui/base/animation/tween.h"
9 11
12 namespace {
13
14 static const float EPSILON = 1e-6f;
15
16 } // namespace
17
10 namespace ui { 18 namespace ui {
11 19
12 /////////////////////////////////////////////////////////////////////////////// 20 ///////////////////////////////////////////////////////////////////////////////
13 // InterpolatedTransform 21 // InterpolatedTransform
14 // 22 //
15 23
16 InterpolatedTransform::InterpolatedTransform() 24 InterpolatedTransform::InterpolatedTransform()
17 : start_time_(0.0f), 25 : start_time_(0.0f),
18 end_time_(1.0f) { 26 end_time_(1.0f) {
19 } 27 }
(...skipping 11 matching lines...) Expand all
31 if (child_.get()) { 39 if (child_.get()) {
32 result.ConcatTransform(child_->Interpolate(t)); 40 result.ConcatTransform(child_->Interpolate(t));
33 } 41 }
34 return result; 42 return result;
35 } 43 }
36 44
37 void InterpolatedTransform::SetChild(InterpolatedTransform* child) { 45 void InterpolatedTransform::SetChild(InterpolatedTransform* child) {
38 child_.reset(child); 46 child_.reset(child);
39 } 47 }
40 48
49 bool InterpolatedTransform::FactorTRS(const ui::Transform& transform,
50 gfx::Point* translation,
51 float* rotation,
52 gfx::Point3f* scale) {
53 const SkMatrix44& m = transform.matrix();
54 float m00 = m.get(0, 0);
55 float m01 = m.get(0, 1);
56 float m10 = m.get(1, 0);
57 float m11 = m.get(1, 1);
58
59 // A factorable 2D TRS matrix must be of the form:
60 // [ sx*cos_theta -(sy*sin_theta) 0 tx ]
61 // [ sx*sin_theta sy*cos_theta 0 ty ]
62 // [ 0 0 1 0 ]
63 // [ 0 0 0 1 ]
64 if (m.get(0, 2) != 0 ||
65 m.get(1, 2) != 0 ||
66 m.get(2, 0) != 0 ||
67 m.get(2, 1) != 0 ||
68 m.get(2, 2) != 1 ||
69 m.get(2, 3) != 0 ||
70 m.get(3, 0) != 0 ||
71 m.get(3, 1) != 0 ||
72 m.get(3, 2) != 0 ||
73 m.get(3, 3) != 1) {
74 return false;
75 }
76
77 float scale_x = sqrt(m00 * m00 + m10 * m10);
78 float scale_y = sqrt(m01 * m01 + m11 * m11);
79
80 if (scale_x == 0 || scale_y == 0)
81 return false;
82
83 float cos_theta = m00 / scale_x;
84 float sin_theta = m10 / scale_x;
85
86 if ((fabs(cos_theta - (m11 / scale_y))) > EPSILON ||
87 (fabs(sin_theta + (m01 / scale_y))) > EPSILON ||
88 (fabs(cos_theta*cos_theta + sin_theta*sin_theta - 1.0f) > EPSILON)) {
89 return false;
90 }
91
92 float radians = atan2(sin_theta, cos_theta);
93
94 if (translation)
95 *translation = gfx::Point(m.get(0, 3), m.get(1, 3));
96 if (rotation)
97 *rotation = radians * 180 / M_PI;
98 if (scale)
99 *scale = gfx::Point3f(scale_x, scale_y, 1.0f);
100
101 return true;
102 }
103
41 inline float InterpolatedTransform::ValueBetween(float time, 104 inline float InterpolatedTransform::ValueBetween(float time,
42 float start_value, 105 float start_value,
43 float end_value) const { 106 float end_value) const {
44 // can't handle NaN 107 // can't handle NaN
45 DCHECK(time == time && start_time_ == start_time_ && end_time_ == end_time_); 108 DCHECK(time == time && start_time_ == start_time_ && end_time_ == end_time_);
46 if (time != time || start_time_ != start_time_ || end_time_ != end_time_) 109 if (time != time || start_time_ != start_time_ || end_time_ != end_time_)
47 return start_value; 110 return start_value;
48 111
49 // Ok if equal -- we'll get a step function. Note: if end_time_ == 112 // Ok if equal -- we'll get a step function. Note: if end_time_ ==
50 // start_time_ == x, then if none of the numbers are NaN, then it 113 // start_time_ == x, then if none of the numbers are NaN, then it
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 ui::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const { 150 ui::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const {
88 ui::Transform result; 151 ui::Transform result;
89 result.SetRotate(ValueBetween(t, start_degrees_, end_degrees_)); 152 result.SetRotate(ValueBetween(t, start_degrees_, end_degrees_));
90 return result; 153 return result;
91 } 154 }
92 155
93 /////////////////////////////////////////////////////////////////////////////// 156 ///////////////////////////////////////////////////////////////////////////////
94 // InterpolatedScale 157 // InterpolatedScale
95 // 158 //
96 159
97 InterpolatedScale::InterpolatedScale(float start_scale, 160 InterpolatedScale::InterpolatedScale(float start_scale, float end_scale)
98 float end_scale) 161 : InterpolatedTransform(),
162 start_scale_(gfx::Point3f(start_scale, start_scale, start_scale)),
163 end_scale_(gfx::Point3f(end_scale, end_scale, end_scale)) {
164 }
165
166 InterpolatedScale::InterpolatedScale(float start_scale, float end_scale,
167 float start_time, float end_time)
168 : InterpolatedTransform(start_time, end_time),
169 start_scale_(gfx::Point3f(start_scale, start_scale, start_scale)),
170 end_scale_(gfx::Point3f(end_scale, end_scale, end_scale)) {
171 }
172
173 InterpolatedScale::InterpolatedScale(const gfx::Point3f& start_scale,
174 const gfx::Point3f& end_scale)
99 : InterpolatedTransform(), 175 : InterpolatedTransform(),
100 start_scale_(start_scale), 176 start_scale_(start_scale),
101 end_scale_(end_scale) { 177 end_scale_(end_scale) {
102 } 178 }
103 179
104 InterpolatedScale::InterpolatedScale(float start_scale, 180 InterpolatedScale::InterpolatedScale(const gfx::Point3f& start_scale,
105 float end_scale, 181 const gfx::Point3f& end_scale,
106 float start_time, 182 float start_time,
107 float end_time) 183 float end_time)
108 : InterpolatedTransform(start_time, end_time), 184 : InterpolatedTransform(start_time, end_time),
109 start_scale_(start_scale), 185 start_scale_(start_scale),
110 end_scale_(end_scale) { 186 end_scale_(end_scale) {
111 } 187 }
112 188
113 InterpolatedScale::~InterpolatedScale() {} 189 InterpolatedScale::~InterpolatedScale() {}
114 190
115 ui::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const { 191 ui::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const {
116 ui::Transform result; 192 ui::Transform result;
117 float interpolated_scale = ValueBetween(t, start_scale_, end_scale_); 193 float scale_x = ValueBetween(t, start_scale_.x(), end_scale_.x());
194 float scale_y = ValueBetween(t, start_scale_.y(), end_scale_.y());
118 // TODO(vollick) 3d xforms. 195 // TODO(vollick) 3d xforms.
119 result.SetScale(interpolated_scale, interpolated_scale); 196 result.SetScale(scale_x, scale_y);
120 return result; 197 return result;
121 } 198 }
122 199
123 /////////////////////////////////////////////////////////////////////////////// 200 ///////////////////////////////////////////////////////////////////////////////
124 // InterpolatedTranslation 201 // InterpolatedTranslation
125 // 202 //
126 203
127 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos, 204 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos,
128 const gfx::Point& end_pos) 205 const gfx::Point& end_pos)
129 : InterpolatedTransform(), 206 : InterpolatedTransform(),
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 Init(pivot, transform); 266 Init(pivot, transform);
190 } 267 }
191 268
192 InterpolatedTransformAboutPivot::~InterpolatedTransformAboutPivot() {} 269 InterpolatedTransformAboutPivot::~InterpolatedTransformAboutPivot() {}
193 270
194 ui::Transform 271 ui::Transform
195 InterpolatedTransformAboutPivot::InterpolateButDoNotCompose(float t) const { 272 InterpolatedTransformAboutPivot::InterpolateButDoNotCompose(float t) const {
196 if (transform_.get()) { 273 if (transform_.get()) {
197 return transform_->Interpolate(t); 274 return transform_->Interpolate(t);
198 } 275 }
199 return ui::Transform(); 276 return Transform();
200 } 277 }
201 278
202 void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot, 279 void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
203 InterpolatedTransform* xform) { 280 InterpolatedTransform* xform) {
204 ui::Transform to_pivot; 281 ui::Transform to_pivot;
205 ui::Transform from_pivot; 282 ui::Transform from_pivot;
206 to_pivot.SetTranslate(-pivot.x(), -pivot.y()); 283 to_pivot.SetTranslate(-pivot.x(), -pivot.y());
207 from_pivot.SetTranslate(pivot.x(), pivot.y()); 284 from_pivot.SetTranslate(pivot.x(), pivot.y());
208 285
209 scoped_ptr<InterpolatedTransform> pre_transform( 286 scoped_ptr<InterpolatedTransform> pre_transform(
210 new InterpolatedConstantTransform(to_pivot)); 287 new InterpolatedConstantTransform(to_pivot));
211 scoped_ptr<InterpolatedTransform> post_transform( 288 scoped_ptr<InterpolatedTransform> post_transform(
212 new InterpolatedConstantTransform(from_pivot)); 289 new InterpolatedConstantTransform(from_pivot));
213 290
214 pre_transform->SetChild(xform); 291 pre_transform->SetChild(xform);
215 xform->SetChild(post_transform.release()); 292 xform->SetChild(post_transform.release());
216 transform_.reset(pre_transform.release()); 293 transform_.reset(pre_transform.release());
217 } 294 }
218 295
296 InterpolatedTRSTransform::InterpolatedTRSTransform(
297 const ui::Transform& start_transform,
298 const ui::Transform& end_transform)
299 : InterpolatedTransform() {
300 Init(start_transform, end_transform);
301 }
302
303 InterpolatedTRSTransform::InterpolatedTRSTransform(
304 const ui::Transform& start_transform,
305 const ui::Transform& end_transform,
306 float start_time,
307 float end_time)
308 : InterpolatedTransform() {
309 Init(start_transform, end_transform);
310 }
311
312 InterpolatedTRSTransform::~InterpolatedTRSTransform() {}
313
314 ui::Transform
315 InterpolatedTRSTransform::InterpolateButDoNotCompose(float t) const {
316 if (transform_.get()) {
317 return transform_->Interpolate(t);
318 }
319 return Transform();
320 }
321
322 void InterpolatedTRSTransform::Init(const Transform& start_transform,
323 const Transform& end_transform) {
324 gfx::Point start_translation, end_translation;
325 gfx::Point3f start_scale, end_scale;
326 float start_degrees, end_degrees;
327 if (FactorTRS(start_transform,
328 &start_translation,
329 &start_degrees,
330 &start_scale) &&
331 FactorTRS(end_transform,
332 &end_translation,
333 &end_degrees,
334 &end_scale)) {
335 scoped_ptr<InterpolatedTranslation> translation(
336 new InterpolatedTranslation(start_translation, end_translation,
337 start_time(), end_time()));
338
339 scoped_ptr<InterpolatedScale> scale(
340 new InterpolatedScale(start_scale, end_scale,
341 start_time(), end_time()));
342
343 scoped_ptr<InterpolatedRotation> rotation(
344 new InterpolatedRotation(start_degrees, end_degrees,
345 start_time(), end_time()));
346
347 rotation->SetChild(translation.release());
348 scale->SetChild(rotation.release());
349 transform_.reset(scale.release());
350 } else {
351 transform_.reset(new InterpolatedConstantTransform(end_transform));
352 }
353 }
354
219 } // namespace ui 355 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/interpolated_transform.h ('k') | ui/gfx/interpolated_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698