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 UI_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 /////////////////////////////////////////////////////////////////////////////// 87 class UI_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 UI_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 UI_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 UI_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 UI_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 UI_EXPORT InterpolatedTransformAboutPivot : public InterpolatedTransform { 216 public: 217 // Takes ownership of the passed transform. 218 InterpolatedTransformAboutPivot(const gfx::Point& pivot, 219 InterpolatedTransform* transform); 220 221 // Takes ownership of the passed transform. 222 InterpolatedTransformAboutPivot(const gfx::Point& pivot, 223 InterpolatedTransform* transform, 224 float start_time, 225 float end_time); 226 virtual ~InterpolatedTransformAboutPivot(); 227 228 protected: 229 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 230 231 private: 232 void Init(const gfx::Point& pivot, InterpolatedTransform* transform); 233 234 scoped_ptr<InterpolatedTransform> transform_; 235 236 DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformAboutPivot); 237 }; 238 239 class UI_EXPORT InterpolatedMatrixTransform : public InterpolatedTransform { 240 public: 241 InterpolatedMatrixTransform(const gfx::Transform& start_transform, 242 const gfx::Transform& end_transform); 243 244 InterpolatedMatrixTransform(const gfx::Transform& start_transform, 245 const gfx::Transform& end_transform, 246 float start_time, 247 float end_time); 248 249 virtual ~InterpolatedMatrixTransform(); 250 251 protected: 252 virtual gfx::Transform InterpolateButDoNotCompose(float t) const OVERRIDE; 253 254 private: 255 void Init(const gfx::Transform& start_transform, 256 const gfx::Transform& end_transform); 257 258 gfx::DecomposedTransform start_decomp_; 259 gfx::DecomposedTransform end_decomp_; 260 }; 261 262 } // namespace ui 263 264 #endif // UI_GFX_INTERPOLATED_TRANSFORM_H_ 265