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 |