Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(470)

Side by Side Diff: cc/animation/keyframed_animation_curve.cc

Issue 598853003: CC: Add curve (whole animation) timing function to compositor animations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renamed functions. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 11 matching lines...) Expand all
22 if (keyframe->Time() < keyframes[i]->Time()) { 22 if (keyframe->Time() < keyframes[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 Keyframe>
ajuma 2014/09/25 14:44:38 I see the naming of this has been discussed alread
ikilpatrick 2014/09/25 22:54:58 Done.
33 float GetProgress(double t, size_t i, const Keyframes& keyframes) { 33 double TransformedAnimationTime(const ScopedPtrVector<Keyframe>& keyframes,
34 float progress = 34 const scoped_ptr<TimingFunction>& timing_function,
35 static_cast<float>((t - keyframes[i]->Time()) / 35 double time) {
36 (keyframes[i + 1]->Time() - keyframes[i]->Time())); 36 if (timing_function) {
37 double start_time = keyframes.front()->Time();
38 double duration = keyframes.back()->Time() - start_time;
39 double progress = (time - start_time) / duration;
37 40
38 if (keyframes[i]->timing_function()) 41 time = timing_function->GetValue(progress) * duration + start_time;
42 }
43
44 return time;
45 }
46
47 template <typename Keyframe>
48 size_t GetActiveKeyframe(const ScopedPtrVector<Keyframe>& keyframes,
49 double time) {
ajuma 2014/09/25 14:44:38 DCHECK_GE(keyframes.size(), 2ul);
ikilpatrick 2014/09/25 22:54:58 Done.
50 size_t i = 0;
51 for (; i < keyframes.size() - 2; ++i) { // Last keyframe is never active.
52 if (time < keyframes[i + 1]->Time())
53 break;
54 }
55
56 return i;
57 }
58
59 template <typename Keyframe>
60 double TransformedKeyframeProgress(const ScopedPtrVector<Keyframe>& keyframes,
61 double time,
62 size_t i) {
63 double progress = (time - keyframes[i]->Time()) /
64 (keyframes[i + 1]->Time() - keyframes[i]->Time());
65
66 if (keyframes[i]->timing_function()) {
39 progress = keyframes[i]->timing_function()->GetValue(progress); 67 progress = keyframes[i]->timing_function()->GetValue(progress);
68 }
69
40 return progress; 70 return progress;
41 } 71 }
42 72
43 scoped_ptr<TimingFunction> CloneTimingFunction( 73 scoped_ptr<TimingFunction> CloneTimingFunction(
44 const TimingFunction* timing_function) { 74 const TimingFunction* timing_function) {
45 DCHECK(timing_function); 75 DCHECK(timing_function);
46 scoped_ptr<AnimationCurve> curve(timing_function->Clone()); 76 scoped_ptr<AnimationCurve> curve(timing_function->Clone());
47 return scoped_ptr<TimingFunction>( 77 return scoped_ptr<TimingFunction>(
48 static_cast<TimingFunction*>(curve.release())); 78 static_cast<TimingFunction*>(curve.release()));
49 } 79 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 212
183 double KeyframedColorAnimationCurve::Duration() const { 213 double KeyframedColorAnimationCurve::Duration() const {
184 return keyframes_.back()->Time() - keyframes_.front()->Time(); 214 return keyframes_.back()->Time() - keyframes_.front()->Time();
185 } 215 }
186 216
187 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { 217 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
188 scoped_ptr<KeyframedColorAnimationCurve> to_return( 218 scoped_ptr<KeyframedColorAnimationCurve> to_return(
189 KeyframedColorAnimationCurve::Create()); 219 KeyframedColorAnimationCurve::Create());
190 for (size_t i = 0; i < keyframes_.size(); ++i) 220 for (size_t i = 0; i < keyframes_.size(); ++i)
191 to_return->AddKeyframe(keyframes_[i]->Clone()); 221 to_return->AddKeyframe(keyframes_[i]->Clone());
222
223 if (timing_function_)
224 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
225
192 return to_return.PassAs<AnimationCurve>(); 226 return to_return.PassAs<AnimationCurve>();
193 } 227 }
194 228
195 SkColor KeyframedColorAnimationCurve::GetValue(double t) const { 229 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
196 if (t <= keyframes_.front()->Time()) 230 if (t <= keyframes_.front()->Time())
197 return keyframes_.front()->Value(); 231 return keyframes_.front()->Value();
198 232
199 if (t >= keyframes_.back()->Time()) 233 if (t >= keyframes_.back()->Time())
200 return keyframes_.back()->Value(); 234 return keyframes_.back()->Value();
201 235
202 size_t i = 0; 236 t = TransformedAnimationTime(keyframes_, timing_function_, t);
203 for (; i < keyframes_.size() - 1; ++i) { 237 size_t i = GetActiveKeyframe(keyframes_, t);
204 if (t < keyframes_[i + 1]->Time()) 238 double progress = TransformedKeyframeProgress(keyframes_, t, i);
205 break;
206 }
207
208 float progress = GetProgress(t, i, keyframes_);
209 239
210 return gfx::Tween::ColorValueBetween( 240 return gfx::Tween::ColorValueBetween(
211 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value()); 241 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
212 } 242 }
213 243
214 // KeyframedFloatAnimationCurve 244 // KeyframedFloatAnimationCurve
215 245
216 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: 246 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
217 Create() { 247 Create() {
218 return make_scoped_ptr(new KeyframedFloatAnimationCurve); 248 return make_scoped_ptr(new KeyframedFloatAnimationCurve);
(...skipping 10 matching lines...) Expand all
229 259
230 double KeyframedFloatAnimationCurve::Duration() const { 260 double KeyframedFloatAnimationCurve::Duration() const {
231 return keyframes_.back()->Time() - keyframes_.front()->Time(); 261 return keyframes_.back()->Time() - keyframes_.front()->Time();
232 } 262 }
233 263
234 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { 264 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
235 scoped_ptr<KeyframedFloatAnimationCurve> to_return( 265 scoped_ptr<KeyframedFloatAnimationCurve> to_return(
236 KeyframedFloatAnimationCurve::Create()); 266 KeyframedFloatAnimationCurve::Create());
237 for (size_t i = 0; i < keyframes_.size(); ++i) 267 for (size_t i = 0; i < keyframes_.size(); ++i)
238 to_return->AddKeyframe(keyframes_[i]->Clone()); 268 to_return->AddKeyframe(keyframes_[i]->Clone());
269
270 if (timing_function_)
271 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
272
239 return to_return.PassAs<AnimationCurve>(); 273 return to_return.PassAs<AnimationCurve>();
240 } 274 }
241 275
242 float KeyframedFloatAnimationCurve::GetValue(double t) const { 276 float KeyframedFloatAnimationCurve::GetValue(double t) const {
243 if (t <= keyframes_.front()->Time()) 277 if (t <= keyframes_.front()->Time())
244 return keyframes_.front()->Value(); 278 return keyframes_.front()->Value();
245 279
246 if (t >= keyframes_.back()->Time()) 280 if (t >= keyframes_.back()->Time())
247 return keyframes_.back()->Value(); 281 return keyframes_.back()->Value();
248 282
249 size_t i = 0; 283 t = TransformedAnimationTime(keyframes_, timing_function_, t);
250 for (; i < keyframes_.size() - 1; ++i) { 284 size_t i = GetActiveKeyframe(keyframes_, t);
251 if (t < keyframes_[i+1]->Time()) 285 double progress = TransformedKeyframeProgress(keyframes_, t, i);
252 break;
253 }
254
255 float progress = GetProgress(t, i, keyframes_);
256 286
257 return keyframes_[i]->Value() + 287 return keyframes_[i]->Value() +
258 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; 288 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
259 } 289 }
260 290
261 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: 291 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
262 Create() { 292 Create() {
263 return make_scoped_ptr(new KeyframedTransformAnimationCurve); 293 return make_scoped_ptr(new KeyframedTransformAnimationCurve);
264 } 294 }
265 295
266 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} 296 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
267 297
268 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} 298 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
269 299
270 void KeyframedTransformAnimationCurve::AddKeyframe( 300 void KeyframedTransformAnimationCurve::AddKeyframe(
271 scoped_ptr<TransformKeyframe> keyframe) { 301 scoped_ptr<TransformKeyframe> keyframe) {
272 InsertKeyframe(keyframe.Pass(), keyframes_); 302 InsertKeyframe(keyframe.Pass(), keyframes_);
273 } 303 }
274 304
275 double KeyframedTransformAnimationCurve::Duration() const { 305 double KeyframedTransformAnimationCurve::Duration() const {
276 return keyframes_.back()->Time() - keyframes_.front()->Time(); 306 return keyframes_.back()->Time() - keyframes_.front()->Time();
277 } 307 }
278 308
279 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { 309 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
280 scoped_ptr<KeyframedTransformAnimationCurve> to_return( 310 scoped_ptr<KeyframedTransformAnimationCurve> to_return(
281 KeyframedTransformAnimationCurve::Create()); 311 KeyframedTransformAnimationCurve::Create());
282 for (size_t i = 0; i < keyframes_.size(); ++i) 312 for (size_t i = 0; i < keyframes_.size(); ++i)
283 to_return->AddKeyframe(keyframes_[i]->Clone()); 313 to_return->AddKeyframe(keyframes_[i]->Clone());
314
315 if (timing_function_)
316 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
317
284 return to_return.PassAs<AnimationCurve>(); 318 return to_return.PassAs<AnimationCurve>();
285 } 319 }
286 320
287 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
288 template<typename ValueType, typename KeyframeType>
289 static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
290 double t) {
291 size_t i = 0;
292 for (; i < keyframes->size() - 1; ++i) {
293 if (t < (*keyframes)[i+1]->Time())
294 break;
295 }
296
297 double progress = (t - (*keyframes)[i]->Time()) /
298 ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
299
300 if ((*keyframes)[i]->timing_function())
301 progress = (*keyframes)[i]->timing_function()->GetValue(progress);
302
303 return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
304 }
305
306 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { 321 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
307 if (t <= keyframes_.front()->Time()) 322 if (t <= keyframes_.front()->Time())
308 return keyframes_.front()->Value().Apply(); 323 return keyframes_.front()->Value().Apply();
309 324
310 if (t >= keyframes_.back()->Time()) 325 if (t >= keyframes_.back()->Time())
311 return keyframes_.back()->Value().Apply(); 326 return keyframes_.back()->Value().Apply();
312 327
313 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t); 328 t = TransformedAnimationTime(keyframes_, timing_function_, t);
329 size_t i = GetActiveKeyframe(keyframes_, t);
330 double progress = TransformedKeyframeProgress(keyframes_, t, i);
331
332 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
314 } 333 }
315 334
316 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( 335 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
317 const gfx::BoxF& box, 336 const gfx::BoxF& box,
318 gfx::BoxF* bounds) const { 337 gfx::BoxF* bounds) const {
319 DCHECK_GE(keyframes_.size(), 2ul); 338 DCHECK_GE(keyframes_.size(), 2ul);
320 *bounds = gfx::BoxF(); 339 *bounds = gfx::BoxF();
321 for (size_t i = 0; i < keyframes_.size() - 1; ++i) { 340 for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
322 gfx::BoxF bounds_for_step; 341 gfx::BoxF bounds_for_step;
323 float min_progress = 0.0; 342 float min_progress = 0.0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 408
390 double KeyframedFilterAnimationCurve::Duration() const { 409 double KeyframedFilterAnimationCurve::Duration() const {
391 return keyframes_.back()->Time() - keyframes_.front()->Time(); 410 return keyframes_.back()->Time() - keyframes_.front()->Time();
392 } 411 }
393 412
394 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { 413 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
395 scoped_ptr<KeyframedFilterAnimationCurve> to_return( 414 scoped_ptr<KeyframedFilterAnimationCurve> to_return(
396 KeyframedFilterAnimationCurve::Create()); 415 KeyframedFilterAnimationCurve::Create());
397 for (size_t i = 0; i < keyframes_.size(); ++i) 416 for (size_t i = 0; i < keyframes_.size(); ++i)
398 to_return->AddKeyframe(keyframes_[i]->Clone()); 417 to_return->AddKeyframe(keyframes_[i]->Clone());
418
419 if (timing_function_)
420 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
421
399 return to_return.PassAs<AnimationCurve>(); 422 return to_return.PassAs<AnimationCurve>();
400 } 423 }
401 424
402 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { 425 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
403 if (t <= keyframes_.front()->Time()) 426 if (t <= keyframes_.front()->Time())
404 return keyframes_.front()->Value(); 427 return keyframes_.front()->Value();
405 428
406 if (t >= keyframes_.back()->Time()) 429 if (t >= keyframes_.back()->Time())
407 return keyframes_.back()->Value(); 430 return keyframes_.back()->Value();
408 431
409 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t); 432 t = TransformedAnimationTime(keyframes_, timing_function_, t);
433 size_t i = GetActiveKeyframe(keyframes_, t);
434 double progress = TransformedKeyframeProgress(keyframes_, t, i);
435
436 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
410 } 437 }
411 438
412 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const { 439 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
413 for (size_t i = 0; i < keyframes_.size(); ++i) { 440 for (size_t i = 0; i < keyframes_.size(); ++i) {
414 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) { 441 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
415 return true; 442 return true;
416 } 443 }
417 } 444 }
418 return false; 445 return false;
419 } 446 }
420 447
421 } // namespace cc 448 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698