| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "cc/animation/keyframed_animation_curve.h" | 7 #include "cc/animation/keyframed_animation_curve.h" |
| 8 #include "ui/gfx/animation/tween.h" | 8 #include "ui/gfx/animation/tween.h" |
| 9 #include "ui/gfx/box_f.h" | 9 #include "ui/gfx/box_f.h" |
| 10 | 10 |
| 11 namespace cc { | 11 namespace cc { |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 template <class Keyframe> | 15 template <class KeyframeType> |
| 16 void InsertKeyframe(scoped_ptr<Keyframe> keyframe, | 16 void InsertKeyframe(scoped_ptr<KeyframeType> keyframe, |
| 17 ScopedPtrVector<Keyframe>* keyframes) { | 17 ScopedPtrVector<KeyframeType>* keyframes) { |
| 18 // Usually, the keyframes will be added in order, so this loop would be | 18 // Usually, the keyframes will be added in order, so this loop would be |
| 19 // unnecessary and we should skip it if possible. | 19 // unnecessary and we should skip it if possible. |
| 20 if (!keyframes->empty() && keyframe->Time() < keyframes->back()->Time()) { | 20 if (!keyframes->empty() && keyframe->Time() < keyframes->back()->Time()) { |
| 21 for (size_t i = 0; i < keyframes->size(); ++i) { | 21 for (size_t i = 0; i < keyframes->size(); ++i) { |
| 22 if (keyframe->Time() < keyframes->at(i)->Time()) { | 22 if (keyframe->Time() < keyframes->at(i)->Time()) { |
| 23 keyframes->insert(keyframes->begin() + i, keyframe.Pass()); | 23 keyframes->insert(keyframes->begin() + i, keyframe.Pass()); |
| 24 return; | 24 return; |
| 25 } | 25 } |
| 26 } | 26 } |
| 27 } | 27 } |
| 28 | 28 |
| 29 keyframes->push_back(keyframe.Pass()); | 29 keyframes->push_back(keyframe.Pass()); |
| 30 } | 30 } |
| 31 | 31 |
| 32 template <class Keyframes> | 32 template <typename KeyframeType> |
| 33 float GetProgress(double t, size_t i, const Keyframes& keyframes) { | 33 double TransformedAnimationTime( |
| 34 float progress = | 34 const ScopedPtrVector<KeyframeType>& keyframes, |
| 35 static_cast<float>((t - keyframes[i]->Time()) / | 35 const scoped_ptr<TimingFunction>& timing_function, |
| 36 (keyframes[i + 1]->Time() - keyframes[i]->Time())); | 36 double time) { |
| 37 if (timing_function) { |
| 38 double start_time = keyframes.front()->Time(); |
| 39 double duration = keyframes.back()->Time() - start_time; |
| 40 double progress = (time - start_time) / duration; |
| 37 | 41 |
| 38 if (keyframes[i]->timing_function()) | 42 time = timing_function->GetValue(progress) * duration + start_time; |
| 43 } |
| 44 |
| 45 return time; |
| 46 } |
| 47 |
| 48 template <typename KeyframeType> |
| 49 size_t GetActiveKeyframe(const ScopedPtrVector<KeyframeType>& keyframes, |
| 50 double time) { |
| 51 DCHECK_GE(keyframes.size(), 2ul); |
| 52 size_t i = 0; |
| 53 for (; i < keyframes.size() - 2; ++i) { // Last keyframe is never active. |
| 54 if (time < keyframes[i + 1]->Time()) |
| 55 break; |
| 56 } |
| 57 |
| 58 return i; |
| 59 } |
| 60 |
| 61 template <typename KeyframeType> |
| 62 double TransformedKeyframeProgress( |
| 63 const ScopedPtrVector<KeyframeType>& keyframes, |
| 64 double time, |
| 65 size_t i) { |
| 66 double progress = (time - keyframes[i]->Time()) / |
| 67 (keyframes[i + 1]->Time() - keyframes[i]->Time()); |
| 68 |
| 69 if (keyframes[i]->timing_function()) { |
| 39 progress = keyframes[i]->timing_function()->GetValue(progress); | 70 progress = keyframes[i]->timing_function()->GetValue(progress); |
| 71 } |
| 72 |
| 40 return progress; | 73 return progress; |
| 41 } | 74 } |
| 42 | 75 |
| 43 } // namespace | 76 } // namespace |
| 44 | 77 |
| 45 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function) | 78 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function) |
| 46 : time_(time), | 79 : time_(time), |
| 47 timing_function_(timing_function.Pass()) {} | 80 timing_function_(timing_function.Pass()) {} |
| 48 | 81 |
| 49 Keyframe::~Keyframe() {} | 82 Keyframe::~Keyframe() {} |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 | 207 |
| 175 double KeyframedColorAnimationCurve::Duration() const { | 208 double KeyframedColorAnimationCurve::Duration() const { |
| 176 return keyframes_.back()->Time() - keyframes_.front()->Time(); | 209 return keyframes_.back()->Time() - keyframes_.front()->Time(); |
| 177 } | 210 } |
| 178 | 211 |
| 179 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { | 212 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { |
| 180 scoped_ptr<KeyframedColorAnimationCurve> to_return = | 213 scoped_ptr<KeyframedColorAnimationCurve> to_return = |
| 181 KeyframedColorAnimationCurve::Create(); | 214 KeyframedColorAnimationCurve::Create(); |
| 182 for (size_t i = 0; i < keyframes_.size(); ++i) | 215 for (size_t i = 0; i < keyframes_.size(); ++i) |
| 183 to_return->AddKeyframe(keyframes_[i]->Clone()); | 216 to_return->AddKeyframe(keyframes_[i]->Clone()); |
| 217 |
| 218 if (timing_function_) |
| 219 to_return->SetTimingFunction(timing_function_->Clone()); |
| 220 |
| 184 return to_return.Pass(); | 221 return to_return.Pass(); |
| 185 } | 222 } |
| 186 | 223 |
| 187 SkColor KeyframedColorAnimationCurve::GetValue(double t) const { | 224 SkColor KeyframedColorAnimationCurve::GetValue(double t) const { |
| 188 if (t <= keyframes_.front()->Time()) | 225 if (t <= keyframes_.front()->Time()) |
| 189 return keyframes_.front()->Value(); | 226 return keyframes_.front()->Value(); |
| 190 | 227 |
| 191 if (t >= keyframes_.back()->Time()) | 228 if (t >= keyframes_.back()->Time()) |
| 192 return keyframes_.back()->Value(); | 229 return keyframes_.back()->Value(); |
| 193 | 230 |
| 194 size_t i = 0; | 231 t = TransformedAnimationTime(keyframes_, timing_function_, t); |
| 195 for (; i < keyframes_.size() - 1; ++i) { | 232 size_t i = GetActiveKeyframe(keyframes_, t); |
| 196 if (t < keyframes_[i + 1]->Time()) | 233 double progress = TransformedKeyframeProgress(keyframes_, t, i); |
| 197 break; | |
| 198 } | |
| 199 | |
| 200 float progress = GetProgress(t, i, keyframes_); | |
| 201 | 234 |
| 202 return gfx::Tween::ColorValueBetween( | 235 return gfx::Tween::ColorValueBetween( |
| 203 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value()); | 236 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value()); |
| 204 } | 237 } |
| 205 | 238 |
| 206 // KeyframedFloatAnimationCurve | 239 // KeyframedFloatAnimationCurve |
| 207 | 240 |
| 208 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: | 241 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: |
| 209 Create() { | 242 Create() { |
| 210 return make_scoped_ptr(new KeyframedFloatAnimationCurve); | 243 return make_scoped_ptr(new KeyframedFloatAnimationCurve); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 221 | 254 |
| 222 double KeyframedFloatAnimationCurve::Duration() const { | 255 double KeyframedFloatAnimationCurve::Duration() const { |
| 223 return keyframes_.back()->Time() - keyframes_.front()->Time(); | 256 return keyframes_.back()->Time() - keyframes_.front()->Time(); |
| 224 } | 257 } |
| 225 | 258 |
| 226 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { | 259 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { |
| 227 scoped_ptr<KeyframedFloatAnimationCurve> to_return = | 260 scoped_ptr<KeyframedFloatAnimationCurve> to_return = |
| 228 KeyframedFloatAnimationCurve::Create(); | 261 KeyframedFloatAnimationCurve::Create(); |
| 229 for (size_t i = 0; i < keyframes_.size(); ++i) | 262 for (size_t i = 0; i < keyframes_.size(); ++i) |
| 230 to_return->AddKeyframe(keyframes_[i]->Clone()); | 263 to_return->AddKeyframe(keyframes_[i]->Clone()); |
| 264 |
| 265 if (timing_function_) |
| 266 to_return->SetTimingFunction(timing_function_->Clone()); |
| 267 |
| 231 return to_return.Pass(); | 268 return to_return.Pass(); |
| 232 } | 269 } |
| 233 | 270 |
| 234 float KeyframedFloatAnimationCurve::GetValue(double t) const { | 271 float KeyframedFloatAnimationCurve::GetValue(double t) const { |
| 235 if (t <= keyframes_.front()->Time()) | 272 if (t <= keyframes_.front()->Time()) |
| 236 return keyframes_.front()->Value(); | 273 return keyframes_.front()->Value(); |
| 237 | 274 |
| 238 if (t >= keyframes_.back()->Time()) | 275 if (t >= keyframes_.back()->Time()) |
| 239 return keyframes_.back()->Value(); | 276 return keyframes_.back()->Value(); |
| 240 | 277 |
| 241 size_t i = 0; | 278 t = TransformedAnimationTime(keyframes_, timing_function_, t); |
| 242 for (; i < keyframes_.size() - 1; ++i) { | 279 size_t i = GetActiveKeyframe(keyframes_, t); |
| 243 if (t < keyframes_[i+1]->Time()) | 280 double progress = TransformedKeyframeProgress(keyframes_, t, i); |
| 244 break; | |
| 245 } | |
| 246 | |
| 247 float progress = GetProgress(t, i, keyframes_); | |
| 248 | 281 |
| 249 return keyframes_[i]->Value() + | 282 return keyframes_[i]->Value() + |
| 250 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; | 283 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; |
| 251 } | 284 } |
| 252 | 285 |
| 253 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: | 286 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: |
| 254 Create() { | 287 Create() { |
| 255 return make_scoped_ptr(new KeyframedTransformAnimationCurve); | 288 return make_scoped_ptr(new KeyframedTransformAnimationCurve); |
| 256 } | 289 } |
| 257 | 290 |
| 258 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} | 291 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} |
| 259 | 292 |
| 260 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} | 293 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} |
| 261 | 294 |
| 262 void KeyframedTransformAnimationCurve::AddKeyframe( | 295 void KeyframedTransformAnimationCurve::AddKeyframe( |
| 263 scoped_ptr<TransformKeyframe> keyframe) { | 296 scoped_ptr<TransformKeyframe> keyframe) { |
| 264 InsertKeyframe(keyframe.Pass(), &keyframes_); | 297 InsertKeyframe(keyframe.Pass(), &keyframes_); |
| 265 } | 298 } |
| 266 | 299 |
| 267 double KeyframedTransformAnimationCurve::Duration() const { | 300 double KeyframedTransformAnimationCurve::Duration() const { |
| 268 return keyframes_.back()->Time() - keyframes_.front()->Time(); | 301 return keyframes_.back()->Time() - keyframes_.front()->Time(); |
| 269 } | 302 } |
| 270 | 303 |
| 271 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { | 304 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { |
| 272 scoped_ptr<KeyframedTransformAnimationCurve> to_return = | 305 scoped_ptr<KeyframedTransformAnimationCurve> to_return = |
| 273 KeyframedTransformAnimationCurve::Create(); | 306 KeyframedTransformAnimationCurve::Create(); |
| 274 for (size_t i = 0; i < keyframes_.size(); ++i) | 307 for (size_t i = 0; i < keyframes_.size(); ++i) |
| 275 to_return->AddKeyframe(keyframes_[i]->Clone()); | 308 to_return->AddKeyframe(keyframes_[i]->Clone()); |
| 309 |
| 310 if (timing_function_) |
| 311 to_return->SetTimingFunction(timing_function_->Clone()); |
| 312 |
| 276 return to_return.Pass(); | 313 return to_return.Pass(); |
| 277 } | 314 } |
| 278 | 315 |
| 279 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time(). | |
| 280 template<typename ValueType, typename KeyframeType> | |
| 281 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes, | |
| 282 double t) { | |
| 283 size_t i = 0; | |
| 284 for (; i < keyframes->size() - 1; ++i) { | |
| 285 if (t < (*keyframes)[i+1]->Time()) | |
| 286 break; | |
| 287 } | |
| 288 | |
| 289 double progress = (t - (*keyframes)[i]->Time()) / | |
| 290 ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time()); | |
| 291 | |
| 292 if ((*keyframes)[i]->timing_function()) | |
| 293 progress = (*keyframes)[i]->timing_function()->GetValue(progress); | |
| 294 | |
| 295 return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress); | |
| 296 } | |
| 297 | |
| 298 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { | 316 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { |
| 299 if (t <= keyframes_.front()->Time()) | 317 if (t <= keyframes_.front()->Time()) |
| 300 return keyframes_.front()->Value().Apply(); | 318 return keyframes_.front()->Value().Apply(); |
| 301 | 319 |
| 302 if (t >= keyframes_.back()->Time()) | 320 if (t >= keyframes_.back()->Time()) |
| 303 return keyframes_.back()->Value().Apply(); | 321 return keyframes_.back()->Value().Apply(); |
| 304 | 322 |
| 305 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t); | 323 t = TransformedAnimationTime(keyframes_, timing_function_, t); |
| 324 size_t i = GetActiveKeyframe(keyframes_, t); |
| 325 double progress = TransformedKeyframeProgress(keyframes_, t, i); |
| 326 |
| 327 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress); |
| 306 } | 328 } |
| 307 | 329 |
| 308 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( | 330 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( |
| 309 const gfx::BoxF& box, | 331 const gfx::BoxF& box, |
| 310 gfx::BoxF* bounds) const { | 332 gfx::BoxF* bounds) const { |
| 311 DCHECK_GE(keyframes_.size(), 2ul); | 333 DCHECK_GE(keyframes_.size(), 2ul); |
| 312 *bounds = gfx::BoxF(); | 334 *bounds = gfx::BoxF(); |
| 313 for (size_t i = 0; i < keyframes_.size() - 1; ++i) { | 335 for (size_t i = 0; i < keyframes_.size() - 1; ++i) { |
| 314 gfx::BoxF bounds_for_step; | 336 gfx::BoxF bounds_for_step; |
| 315 float min_progress = 0.0; | 337 float min_progress = 0.0; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 | 403 |
| 382 double KeyframedFilterAnimationCurve::Duration() const { | 404 double KeyframedFilterAnimationCurve::Duration() const { |
| 383 return keyframes_.back()->Time() - keyframes_.front()->Time(); | 405 return keyframes_.back()->Time() - keyframes_.front()->Time(); |
| 384 } | 406 } |
| 385 | 407 |
| 386 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { | 408 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { |
| 387 scoped_ptr<KeyframedFilterAnimationCurve> to_return = | 409 scoped_ptr<KeyframedFilterAnimationCurve> to_return = |
| 388 KeyframedFilterAnimationCurve::Create(); | 410 KeyframedFilterAnimationCurve::Create(); |
| 389 for (size_t i = 0; i < keyframes_.size(); ++i) | 411 for (size_t i = 0; i < keyframes_.size(); ++i) |
| 390 to_return->AddKeyframe(keyframes_[i]->Clone()); | 412 to_return->AddKeyframe(keyframes_[i]->Clone()); |
| 413 |
| 414 if (timing_function_) |
| 415 to_return->SetTimingFunction(timing_function_->Clone()); |
| 416 |
| 391 return to_return.Pass(); | 417 return to_return.Pass(); |
| 392 } | 418 } |
| 393 | 419 |
| 394 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { | 420 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { |
| 395 if (t <= keyframes_.front()->Time()) | 421 if (t <= keyframes_.front()->Time()) |
| 396 return keyframes_.front()->Value(); | 422 return keyframes_.front()->Value(); |
| 397 | 423 |
| 398 if (t >= keyframes_.back()->Time()) | 424 if (t >= keyframes_.back()->Time()) |
| 399 return keyframes_.back()->Value(); | 425 return keyframes_.back()->Value(); |
| 400 | 426 |
| 401 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t); | 427 t = TransformedAnimationTime(keyframes_, timing_function_, t); |
| 428 size_t i = GetActiveKeyframe(keyframes_, t); |
| 429 double progress = TransformedKeyframeProgress(keyframes_, t, i); |
| 430 |
| 431 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress); |
| 402 } | 432 } |
| 403 | 433 |
| 404 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const { | 434 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const { |
| 405 for (size_t i = 0; i < keyframes_.size(); ++i) { | 435 for (size_t i = 0; i < keyframes_.size(); ++i) { |
| 406 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) { | 436 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) { |
| 407 return true; | 437 return true; |
| 408 } | 438 } |
| 409 } | 439 } |
| 410 return false; | 440 return false; |
| 411 } | 441 } |
| 412 | 442 |
| 413 } // namespace cc | 443 } // namespace cc |
| OLD | NEW |