keyframed_animation_curve.cc revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright 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#include "cc/animation/keyframed_animation_curve.h" 6#include "ui/gfx/box_f.h" 7 8namespace cc { 9 10namespace { 11 12template <class Keyframe> 13void InsertKeyframe(scoped_ptr<Keyframe> keyframe, 14 ScopedPtrVector<Keyframe>& keyframes) { 15 // Usually, the keyframes will be added in order, so this loop would be 16 // unnecessary and we should skip it if possible. 17 if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) { 18 for (size_t i = 0; i < keyframes.size(); ++i) { 19 if (keyframe->Time() < keyframes[i]->Time()) { 20 keyframes.insert(keyframes.begin() + i, keyframe.Pass()); 21 return; 22 } 23 } 24 } 25 26 keyframes.push_back(keyframe.Pass()); 27} 28 29scoped_ptr<TimingFunction> CloneTimingFunction( 30 const TimingFunction* timing_function) { 31 DCHECK(timing_function); 32 scoped_ptr<AnimationCurve> curve(timing_function->Clone()); 33 return scoped_ptr<TimingFunction>( 34 static_cast<TimingFunction*>(curve.release())); 35} 36 37} // namespace 38 39Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function) 40 : time_(time), 41 timing_function_(timing_function.Pass()) {} 42 43Keyframe::~Keyframe() {} 44 45double Keyframe::Time() const { 46 return time_; 47} 48 49scoped_ptr<FloatKeyframe> FloatKeyframe::Create( 50 double time, 51 float value, 52 scoped_ptr<TimingFunction> timing_function) { 53 return make_scoped_ptr( 54 new FloatKeyframe(time, value, timing_function.Pass())); 55} 56 57FloatKeyframe::FloatKeyframe(double time, 58 float value, 59 scoped_ptr<TimingFunction> timing_function) 60 : Keyframe(time, timing_function.Pass()), 61 value_(value) {} 62 63FloatKeyframe::~FloatKeyframe() {} 64 65float FloatKeyframe::Value() const { 66 return value_; 67} 68 69scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const { 70 scoped_ptr<TimingFunction> func; 71 if (timing_function()) 72 func = CloneTimingFunction(timing_function()); 73 return FloatKeyframe::Create(Time(), Value(), func.Pass()); 74} 75 76scoped_ptr<TransformKeyframe> TransformKeyframe::Create( 77 double time, 78 const TransformOperations& value, 79 scoped_ptr<TimingFunction> timing_function) { 80 return make_scoped_ptr( 81 new TransformKeyframe(time, value, timing_function.Pass())); 82} 83 84TransformKeyframe::TransformKeyframe(double time, 85 const TransformOperations& value, 86 scoped_ptr<TimingFunction> timing_function) 87 : Keyframe(time, timing_function.Pass()), 88 value_(value) {} 89 90TransformKeyframe::~TransformKeyframe() {} 91 92const TransformOperations& TransformKeyframe::Value() const { 93 return value_; 94} 95 96scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const { 97 scoped_ptr<TimingFunction> func; 98 if (timing_function()) 99 func = CloneTimingFunction(timing_function()); 100 return TransformKeyframe::Create(Time(), Value(), func.Pass()); 101} 102 103scoped_ptr<FilterKeyframe> FilterKeyframe::Create( 104 double time, 105 const FilterOperations& value, 106 scoped_ptr<TimingFunction> timing_function) { 107 return make_scoped_ptr( 108 new FilterKeyframe(time, value, timing_function.Pass())); 109} 110 111FilterKeyframe::FilterKeyframe(double time, 112 const FilterOperations& value, 113 scoped_ptr<TimingFunction> timing_function) 114 : Keyframe(time, timing_function.Pass()), 115 value_(value) {} 116 117FilterKeyframe::~FilterKeyframe() {} 118 119const FilterOperations& FilterKeyframe::Value() const { 120 return value_; 121} 122 123scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const { 124 scoped_ptr<TimingFunction> func; 125 if (timing_function()) 126 func = CloneTimingFunction(timing_function()); 127 return FilterKeyframe::Create(Time(), Value(), func.Pass()); 128} 129 130scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: 131 Create() { 132 return make_scoped_ptr(new KeyframedFloatAnimationCurve); 133} 134 135KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {} 136 137KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {} 138 139void KeyframedFloatAnimationCurve::AddKeyframe( 140 scoped_ptr<FloatKeyframe> keyframe) { 141 InsertKeyframe(keyframe.Pass(), keyframes_); 142} 143 144double KeyframedFloatAnimationCurve::Duration() const { 145 return keyframes_.back()->Time() - keyframes_.front()->Time(); 146} 147 148scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { 149 scoped_ptr<KeyframedFloatAnimationCurve> to_return( 150 KeyframedFloatAnimationCurve::Create()); 151 for (size_t i = 0; i < keyframes_.size(); ++i) 152 to_return->AddKeyframe(keyframes_[i]->Clone()); 153 return to_return.PassAs<AnimationCurve>(); 154} 155 156float KeyframedFloatAnimationCurve::GetValue(double t) const { 157 if (t <= keyframes_.front()->Time()) 158 return keyframes_.front()->Value(); 159 160 if (t >= keyframes_.back()->Time()) 161 return keyframes_.back()->Value(); 162 163 size_t i = 0; 164 for (; i < keyframes_.size() - 1; ++i) { 165 if (t < keyframes_[i+1]->Time()) 166 break; 167 } 168 169 float progress = 170 static_cast<float>((t - keyframes_[i]->Time()) / 171 (keyframes_[i+1]->Time() - keyframes_[i]->Time())); 172 173 if (keyframes_[i]->timing_function()) 174 progress = keyframes_[i]->timing_function()->GetValue(progress); 175 176 return keyframes_[i]->Value() + 177 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; 178} 179 180scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: 181 Create() { 182 return make_scoped_ptr(new KeyframedTransformAnimationCurve); 183} 184 185KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} 186 187KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} 188 189void KeyframedTransformAnimationCurve::AddKeyframe( 190 scoped_ptr<TransformKeyframe> keyframe) { 191 InsertKeyframe(keyframe.Pass(), keyframes_); 192} 193 194double KeyframedTransformAnimationCurve::Duration() const { 195 return keyframes_.back()->Time() - keyframes_.front()->Time(); 196} 197 198scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { 199 scoped_ptr<KeyframedTransformAnimationCurve> to_return( 200 KeyframedTransformAnimationCurve::Create()); 201 for (size_t i = 0; i < keyframes_.size(); ++i) 202 to_return->AddKeyframe(keyframes_[i]->Clone()); 203 return to_return.PassAs<AnimationCurve>(); 204} 205 206// Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time(). 207template<typename ValueType, typename KeyframeType> 208static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes, 209 double t) { 210 size_t i = 0; 211 for (; i < keyframes->size() - 1; ++i) { 212 if (t < (*keyframes)[i+1]->Time()) 213 break; 214 } 215 216 double progress = (t - (*keyframes)[i]->Time()) / 217 ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time()); 218 219 if ((*keyframes)[i]->timing_function()) 220 progress = (*keyframes)[i]->timing_function()->GetValue(progress); 221 222 return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress); 223} 224 225gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { 226 if (t <= keyframes_.front()->Time()) 227 return keyframes_.front()->Value().Apply(); 228 229 if (t >= keyframes_.back()->Time()) 230 return keyframes_.back()->Value().Apply(); 231 232 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t); 233} 234 235bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( 236 const gfx::BoxF& box, 237 gfx::BoxF* bounds) const { 238 DCHECK_GE(keyframes_.size(), 2ul); 239 *bounds = gfx::BoxF(); 240 for (size_t i = 0; i < keyframes_.size() - 1; ++i) { 241 gfx::BoxF bounds_for_step; 242 float min_progress = 0.0; 243 float max_progress = 1.0; 244 if (keyframes_[i]->timing_function()) 245 keyframes_[i]->timing_function()->Range(&min_progress, &max_progress); 246 if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box, 247 keyframes_[i]->Value(), 248 min_progress, 249 max_progress, 250 &bounds_for_step)) 251 return false; 252 bounds->Union(bounds_for_step); 253 } 254 return true; 255} 256 257scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve:: 258 Create() { 259 return make_scoped_ptr(new KeyframedFilterAnimationCurve); 260} 261 262KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {} 263 264KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {} 265 266void KeyframedFilterAnimationCurve::AddKeyframe( 267 scoped_ptr<FilterKeyframe> keyframe) { 268 InsertKeyframe(keyframe.Pass(), keyframes_); 269} 270 271double KeyframedFilterAnimationCurve::Duration() const { 272 return keyframes_.back()->Time() - keyframes_.front()->Time(); 273} 274 275scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { 276 scoped_ptr<KeyframedFilterAnimationCurve> to_return( 277 KeyframedFilterAnimationCurve::Create()); 278 for (size_t i = 0; i < keyframes_.size(); ++i) 279 to_return->AddKeyframe(keyframes_[i]->Clone()); 280 return to_return.PassAs<AnimationCurve>(); 281} 282 283FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { 284 if (t <= keyframes_.front()->Time()) 285 return keyframes_.front()->Value(); 286 287 if (t >= keyframes_.back()->Time()) 288 return keyframes_.back()->Value(); 289 290 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t); 291} 292 293} // namespace cc 294