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