1// Copyright (c) 2012 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#ifndef UI_GFX_INTERPOLATED_TRANSFORM_H_ 6#define UI_GFX_INTERPOLATED_TRANSFORM_H_ 7 8#include "base/basictypes.h" 9#include "base/memory/scoped_ptr.h" 10#include "ui/gfx/point.h" 11#include "ui/gfx/point3_f.h" 12#include "ui/gfx/transform.h" 13#include "ui/gfx/transform_util.h" 14#include "ui/gfx/vector3d_f.h" 15 16namespace ui { 17 18/////////////////////////////////////////////////////////////////////////////// 19// class InterpolatedTransform 20// 21// Abstract base class for transforms that animate over time. These 22// interpolated transforms can be combined to allow for more sophisticated 23// animations. For example, you might combine a rotation of 90 degrees between 24// times 0 and 1, with a scale from 1 to 0.3 between times 0 and 0.25 and a 25// scale from 0.3 to 1 from between times 0.75 and 1. 26// 27/////////////////////////////////////////////////////////////////////////////// 28class GFX_EXPORT InterpolatedTransform { 29 public: 30 InterpolatedTransform(); 31 // The interpolated transform varies only when t in (start_time, end_time). 32 // If t <= start_time, Interpolate(t) will return the initial transform, and 33 // if t >= end_time, Interpolate(t) will return the final transform. 34 InterpolatedTransform(float start_time, float end_time); 35 virtual ~InterpolatedTransform(); 36 37 // Returns the interpolated transform at time t. Note: not virtual. 38 gfx::Transform Interpolate(float t) const; 39 40 // The Intepolate ultimately returns the product of our transform at time t 41 // and our child's transform at time t (if we have one). 42 // 43 // This function takes ownership of the passed InterpolatedTransform. 44 void SetChild(InterpolatedTransform* child); 45 46 // If the interpolated transform is reversed, Interpolate(t) will return 47 // Interpolate(1 - t) 48 void SetReversed(bool reversed) { reversed_ = reversed; } 49 bool Reversed() const { return reversed_; } 50 51 protected: 52 // Calculates the interpolated transform without considering our child. 53 virtual gfx::Transform InterpolateButDoNotCompose(float t) const = 0; 54 55 // If time in (start_time_, end_time_], this function linearly interpolates 56 // between start_value and end_value. More precisely it returns 57 // (1 - t) * start_value + t * end_value where 58 // t = (start_time_ - time) / (end_time_ - start_time_). 59 // If time < start_time_ it returns start_value, and if time >= end_time_ 60 // it returns end_value. 61 float ValueBetween(float time, float start_value, float end_value) const; 62 63 float start_time() const { return start_time_; } 64 float end_time() const { return end_time_; } 65 66 private: 67 const float start_time_; 68 const float end_time_; 69 70 // The child transform. If you consider an interpolated transform as a 71 // function of t. If, without a child, we are f(t), and our child is 72 // g(t), then with a child we become f'(t) = f(t) * g(t). Using a child 73 // transform, we can chain collections of transforms together. 74 scoped_ptr<InterpolatedTransform> child_; 75 76 bool reversed_; 77 78 DISALLOW_COPY_AND_ASSIGN(InterpolatedTransform); 79}; 80 81/////////////////////////////////////////////////////////////////////////////// 82// class InterpolatedRotation 83// 84// Represents an animated rotation. 85// 86/////////////////////////////////////////////////////////////////////////////// 87class GFX_EXPORT InterpolatedRotation : public InterpolatedTransform { 88 public: 89 InterpolatedRotation(float start_degrees, float end_degrees); 90 InterpolatedRotation(float start_degrees, 91 float end_degrees, 92 float start_time, 93 float end_time); 94 virtual ~InterpolatedRotation(); 95 96 protected: 97 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 98 99 private: 100 const float start_degrees_; 101 const float end_degrees_; 102 103 DISALLOW_COPY_AND_ASSIGN(InterpolatedRotation); 104}; 105 106/////////////////////////////////////////////////////////////////////////////// 107// class InterpolatedAxisAngleRotation 108// 109// Represents an animated rotation. 110// 111/////////////////////////////////////////////////////////////////////////////// 112class GFX_EXPORT InterpolatedAxisAngleRotation : public InterpolatedTransform { 113 public: 114 InterpolatedAxisAngleRotation(const gfx::Vector3dF& axis, 115 float start_degrees, 116 float end_degrees); 117 InterpolatedAxisAngleRotation(const gfx::Vector3dF& axis, 118 float start_degrees, 119 float end_degrees, 120 float start_time, 121 float end_time); 122 virtual ~InterpolatedAxisAngleRotation(); 123 124 protected: 125 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 126 127 private: 128 gfx::Vector3dF axis_; 129 const float start_degrees_; 130 const float end_degrees_; 131 132 DISALLOW_COPY_AND_ASSIGN(InterpolatedAxisAngleRotation); 133}; 134 135/////////////////////////////////////////////////////////////////////////////// 136// class InterpolatedScale 137// 138// Represents an animated scale. 139// 140/////////////////////////////////////////////////////////////////////////////// 141class GFX_EXPORT InterpolatedScale : public InterpolatedTransform { 142 public: 143 InterpolatedScale(float start_scale, float end_scale); 144 InterpolatedScale(float start_scale, float end_scale, 145 float start_time, float end_time); 146 InterpolatedScale(const gfx::Point3F& start_scale, 147 const gfx::Point3F& end_scale); 148 InterpolatedScale(const gfx::Point3F& start_scale, 149 const gfx::Point3F& end_scale, 150 float start_time, 151 float end_time); 152 virtual ~InterpolatedScale(); 153 154 protected: 155 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 156 157 private: 158 const gfx::Point3F start_scale_; 159 const gfx::Point3F end_scale_; 160 161 DISALLOW_COPY_AND_ASSIGN(InterpolatedScale); 162}; 163 164class GFX_EXPORT InterpolatedTranslation : public InterpolatedTransform { 165 public: 166 InterpolatedTranslation(const gfx::Point& start_pos, 167 const gfx::Point& end_pos); 168 InterpolatedTranslation(const gfx::Point& start_pos, 169 const gfx::Point& end_pos, 170 float start_time, 171 float end_time); 172 virtual ~InterpolatedTranslation(); 173 174 protected: 175 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 176 177 private: 178 const gfx::Point start_pos_; 179 const gfx::Point end_pos_; 180 181 DISALLOW_COPY_AND_ASSIGN(InterpolatedTranslation); 182}; 183 184/////////////////////////////////////////////////////////////////////////////// 185// class InterpolatedConstantTransform 186// 187// Represents a transform that is constant over time. This is only useful when 188// composed with other interpolated transforms. 189// 190// See InterpolatedTransformAboutPivot for an example of its usage. 191// 192/////////////////////////////////////////////////////////////////////////////// 193class GFX_EXPORT InterpolatedConstantTransform : public InterpolatedTransform { 194 public: 195 explicit InterpolatedConstantTransform(const gfx::Transform& transform); 196 virtual ~InterpolatedConstantTransform(); 197 198 protected: 199 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 200 201 private: 202 const gfx::Transform transform_; 203 204 DISALLOW_COPY_AND_ASSIGN(InterpolatedConstantTransform); 205}; 206 207/////////////////////////////////////////////////////////////////////////////// 208// class InterpolatedTransformAboutPivot 209// 210// Represents an animated transform with a transformed origin. Essentially, 211// at each time, t, the interpolated transform is created by composing 212// P * T * P^-1 where P is a constant transform to the new origin. 213// 214/////////////////////////////////////////////////////////////////////////////// 215class GFX_EXPORT InterpolatedTransformAboutPivot 216 : public InterpolatedTransform { 217 public: 218 // Takes ownership of the passed transform. 219 InterpolatedTransformAboutPivot(const gfx::Point& pivot, 220 InterpolatedTransform* transform); 221 222 // Takes ownership of the passed transform. 223 InterpolatedTransformAboutPivot(const gfx::Point& pivot, 224 InterpolatedTransform* transform, 225 float start_time, 226 float end_time); 227 virtual ~InterpolatedTransformAboutPivot(); 228 229 protected: 230 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 231 232 private: 233 void Init(const gfx::Point& pivot, InterpolatedTransform* transform); 234 235 scoped_ptr<InterpolatedTransform> transform_; 236 237 DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformAboutPivot); 238}; 239 240class GFX_EXPORT InterpolatedMatrixTransform : public InterpolatedTransform { 241 public: 242 InterpolatedMatrixTransform(const gfx::Transform& start_transform, 243 const gfx::Transform& end_transform); 244 245 InterpolatedMatrixTransform(const gfx::Transform& start_transform, 246 const gfx::Transform& end_transform, 247 float start_time, 248 float end_time); 249 250 virtual ~InterpolatedMatrixTransform(); 251 252 protected: 253 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 254 255 private: 256 void Init(const gfx::Transform& start_transform, 257 const gfx::Transform& end_transform); 258 259 gfx::DecomposedTransform start_decomp_; 260 gfx::DecomposedTransform end_decomp_; 261}; 262 263} // namespace ui 264 265#endif // UI_GFX_INTERPOLATED_TRANSFORM_H_ 266