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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/interpolated_transform.h ('k') | ui/gfx/interpolated_transform_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/interpolated_transform.cc
diff --git a/ui/gfx/interpolated_transform.cc b/ui/gfx/interpolated_transform.cc
index 1f37f84909a35d6e12c290aad8fb1e614474af05..6378082962bcb9492af12df0e7ad1c7da38bb72f 100644
--- a/ui/gfx/interpolated_transform.cc
+++ b/ui/gfx/interpolated_transform.cc
@@ -4,9 +4,17 @@
#include "ui/gfx/interpolated_transform.h"
+#include <cmath>
+
#include "base/logging.h"
#include "ui/base/animation/tween.h"
+namespace {
+
+static const float EPSILON = 1e-6f;
+
+} // namespace
+
namespace ui {
///////////////////////////////////////////////////////////////////////////////
@@ -38,6 +46,61 @@ void InterpolatedTransform::SetChild(InterpolatedTransform* child) {
child_.reset(child);
}
+bool InterpolatedTransform::FactorTRS(const ui::Transform& transform,
+ gfx::Point* translation,
+ float* rotation,
+ gfx::Point3f* scale) {
+ const SkMatrix44& m = transform.matrix();
+ float m00 = m.get(0, 0);
+ float m01 = m.get(0, 1);
+ float m10 = m.get(1, 0);
+ float m11 = m.get(1, 1);
+
+ // A factorable 2D TRS matrix must be of the form:
+ // [ sx*cos_theta -(sy*sin_theta) 0 tx ]
+ // [ sx*sin_theta sy*cos_theta 0 ty ]
+ // [ 0 0 1 0 ]
+ // [ 0 0 0 1 ]
+ if (m.get(0, 2) != 0 ||
+ m.get(1, 2) != 0 ||
+ m.get(2, 0) != 0 ||
+ m.get(2, 1) != 0 ||
+ m.get(2, 2) != 1 ||
+ m.get(2, 3) != 0 ||
+ m.get(3, 0) != 0 ||
+ m.get(3, 1) != 0 ||
+ m.get(3, 2) != 0 ||
+ m.get(3, 3) != 1) {
+ return false;
+ }
+
+ float scale_x = sqrt(m00 * m00 + m10 * m10);
+ float scale_y = sqrt(m01 * m01 + m11 * m11);
+
+ if (scale_x == 0 || scale_y == 0)
+ return false;
+
+ float cos_theta = m00 / scale_x;
+ float sin_theta = m10 / scale_x;
+
+ if ((fabs(cos_theta - (m11 / scale_y))) > EPSILON ||
+ (fabs(sin_theta + (m01 / scale_y))) > EPSILON ||
+ (fabs(cos_theta*cos_theta + sin_theta*sin_theta - 1.0f) > EPSILON)) {
+ return false;
+ }
+
+ float radians = atan2(sin_theta, cos_theta);
+
+ if (translation)
+ *translation = gfx::Point(m.get(0, 3), m.get(1, 3));
+ if (rotation)
+ *rotation = radians * 180 / M_PI;
+ if (scale)
+ *scale = gfx::Point3f(scale_x, scale_y, 1.0f);
+
+ return true;
+}
+
inline float InterpolatedTransform::ValueBetween(float time,
float start_value,
float end_value) const {
@@ -94,15 +157,28 @@ ui::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const {
// InterpolatedScale
//
-InterpolatedScale::InterpolatedScale(float start_scale,
- float end_scale)
+InterpolatedScale::InterpolatedScale(float start_scale, float end_scale)
+ : InterpolatedTransform(),
+ start_scale_(gfx::Point3f(start_scale, start_scale, start_scale)),
+ end_scale_(gfx::Point3f(end_scale, end_scale, end_scale)) {
+}
+
+InterpolatedScale::InterpolatedScale(float start_scale, float end_scale,
+ float start_time, float end_time)
+ : InterpolatedTransform(start_time, end_time),
+ start_scale_(gfx::Point3f(start_scale, start_scale, start_scale)),
+ end_scale_(gfx::Point3f(end_scale, end_scale, end_scale)) {
+}
+
+InterpolatedScale::InterpolatedScale(const gfx::Point3f& start_scale,
+ const gfx::Point3f& end_scale)
: InterpolatedTransform(),
start_scale_(start_scale),
end_scale_(end_scale) {
}
-InterpolatedScale::InterpolatedScale(float start_scale,
- float end_scale,
+InterpolatedScale::InterpolatedScale(const gfx::Point3f& start_scale,
+ const gfx::Point3f& end_scale,
float start_time,
float end_time)
: InterpolatedTransform(start_time, end_time),
@@ -114,9 +190,10 @@ InterpolatedScale::~InterpolatedScale() {}
ui::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const {
ui::Transform result;
- float interpolated_scale = ValueBetween(t, start_scale_, end_scale_);
+ float scale_x = ValueBetween(t, start_scale_.x(), end_scale_.x());
+ float scale_y = ValueBetween(t, start_scale_.y(), end_scale_.y());
// TODO(vollick) 3d xforms.
- result.SetScale(interpolated_scale, interpolated_scale);
+ result.SetScale(scale_x, scale_y);
return result;
}
@@ -196,7 +273,7 @@ InterpolatedTransformAboutPivot::InterpolateButDoNotCompose(float t) const {
if (transform_.get()) {
return transform_->Interpolate(t);
}
- return ui::Transform();
+ return Transform();
}
void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
@@ -216,4 +293,63 @@ void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
transform_.reset(pre_transform.release());
}
+InterpolatedTRSTransform::InterpolatedTRSTransform(
+ const ui::Transform& start_transform,
+ const ui::Transform& end_transform)
+ : InterpolatedTransform() {
+ Init(start_transform, end_transform);
+}
+
+InterpolatedTRSTransform::InterpolatedTRSTransform(
+ const ui::Transform& start_transform,
+ const ui::Transform& end_transform,
+ float start_time,
+ float end_time)
+ : InterpolatedTransform() {
+ Init(start_transform, end_transform);
+}
+
+InterpolatedTRSTransform::~InterpolatedTRSTransform() {}
+
+ui::Transform
+InterpolatedTRSTransform::InterpolateButDoNotCompose(float t) const {
+ if (transform_.get()) {
+ return transform_->Interpolate(t);
+ }
+ return Transform();
+}
+
+void InterpolatedTRSTransform::Init(const Transform& start_transform,
+ const Transform& end_transform) {
+ gfx::Point start_translation, end_translation;
+ gfx::Point3f start_scale, end_scale;
+ float start_degrees, end_degrees;
+ if (FactorTRS(start_transform,
+ &start_translation,
+ &start_degrees,
+ &start_scale) &&
+ FactorTRS(end_transform,
+ &end_translation,
+ &end_degrees,
+ &end_scale)) {
+ scoped_ptr<InterpolatedTranslation> translation(
+ new InterpolatedTranslation(start_translation, end_translation,
+ start_time(), end_time()));
+
+ scoped_ptr<InterpolatedScale> scale(
+ new InterpolatedScale(start_scale, end_scale,
+ start_time(), end_time()));
+
+ scoped_ptr<InterpolatedRotation> rotation(
+ new InterpolatedRotation(start_degrees, end_degrees,
+ start_time(), end_time()));
+
+ rotation->SetChild(translation.release());
+ scale->SetChild(rotation.release());
+ transform_.reset(scale.release());
+ } else {
+ transform_.reset(new InterpolatedConstantTransform(end_transform));
+ }
+}
+
} // namespace ui
« 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