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 16 namespace 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 /////////////////////////////////////////////////////////////////////////////// 28 class 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) SetReversed(bool reversed)48 void SetReversed(bool reversed) { 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 start_time()63 float start_time() const { return start_time_; } end_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 /////////////////////////////////////////////////////////////////////////////// 87 class 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 /////////////////////////////////////////////////////////////////////////////// 112 class 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 /////////////////////////////////////////////////////////////////////////////// 141 class 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 164 class 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 /////////////////////////////////////////////////////////////////////////////// 193 class 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 /////////////////////////////////////////////////////////////////////////////// 215 class 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 240 class 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