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

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: Created 6 years, 2 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 // Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
samli 2014/09/24 07:55:32 Use a DCHECK to assert this assumption
ikilpatrick 2014/09/25 04:33:25 Acknowledged.
33 float GetProgress(double t, size_t i, const Keyframes& keyframes) { 33 template <typename KeyframeType>
samli 2014/09/24 07:55:32 Is there a reason for renaming from Keyframes to K
ikilpatrick 2014/09/25 04:33:25 A lot of this came from deleted GetCurveValue belo
samli 2014/09/25 07:03:48 Keyframe IMO
34 float progress = 34 double GetProgress(const ScopedPtrVector<KeyframeType>* keyframes,
samli 2014/09/24 07:55:32 Can you separate the curve timing function logic t
samli 2014/09/24 07:55:32 Use references instead
ikilpatrick 2014/09/25 04:33:25 Done. PTAL.
ikilpatrick 2014/09/25 04:33:25 Done.
samli 2014/09/25 07:03:48 Looks good
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 size_t* i) {
38 double t = time;
samli 2014/09/24 07:55:32 Unnecessary variable
ikilpatrick 2014/09/25 04:33:25 Done.
39 double end_time = (*keyframes).back()->Time();
37 40
38 if (keyframes[i]->timing_function()) 41 // Apply the curve timing function.
39 progress = keyframes[i]->timing_function()->GetValue(progress); 42 if (*timing_function) {
43 double start_time = (*keyframes).front()->Time();
44 double duration = end_time - start_time;
45 double animationProgress = (t - start_time) / duration;
46
47 t = (*timing_function)->GetValue(animationProgress) * duration + start_time;
48 }
49
50 // May have exceeded the end time of the last keyframe.
51 if (t >= end_time)
52 return 1.;
53
54 // Find the active keyframe.
55 *i = 0;
56 for (; *i < keyframes->size() - 1; ++*i) {
57 if (t < (*keyframes)[*i + 1]->Time())
58 break;
59 }
60
61 double progress = (t - (*keyframes)[*i]->Time()) /
62 ((*keyframes)[*i + 1]->Time() - (*keyframes)[*i]->Time());
63
64 if ((*keyframes)[*i]->timing_function())
65 // Clamp progress as timing functions only valid for inputs [0,1].
66 progress = (*keyframes)[*i]->timing_function()->GetValue(
67 std::min(std::max(progress, 0.), 1.));
samli 2014/09/24 07:55:32 No need for 0., just use 0
ikilpatrick 2014/09/25 04:33:25 Need to use 0. as template won't match. "deduced c
samli 2014/09/25 07:03:48 Ah. I think the correct style for double is 0.0
68
40 return progress; 69 return progress;
41 } 70 }
42 71
43 scoped_ptr<TimingFunction> CloneTimingFunction( 72 scoped_ptr<TimingFunction> CloneTimingFunction(
44 const TimingFunction* timing_function) { 73 const TimingFunction* timing_function) {
45 DCHECK(timing_function); 74 DCHECK(timing_function);
46 scoped_ptr<AnimationCurve> curve(timing_function->Clone()); 75 scoped_ptr<AnimationCurve> curve(timing_function->Clone());
47 return scoped_ptr<TimingFunction>( 76 return scoped_ptr<TimingFunction>(
48 static_cast<TimingFunction*>(curve.release())); 77 static_cast<TimingFunction*>(curve.release()));
49 } 78 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 211
183 double KeyframedColorAnimationCurve::Duration() const { 212 double KeyframedColorAnimationCurve::Duration() const {
184 return keyframes_.back()->Time() - keyframes_.front()->Time(); 213 return keyframes_.back()->Time() - keyframes_.front()->Time();
185 } 214 }
186 215
187 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { 216 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
188 scoped_ptr<KeyframedColorAnimationCurve> to_return( 217 scoped_ptr<KeyframedColorAnimationCurve> to_return(
189 KeyframedColorAnimationCurve::Create()); 218 KeyframedColorAnimationCurve::Create());
190 for (size_t i = 0; i < keyframes_.size(); ++i) 219 for (size_t i = 0; i < keyframes_.size(); ++i)
191 to_return->AddKeyframe(keyframes_[i]->Clone()); 220 to_return->AddKeyframe(keyframes_[i]->Clone());
221
222 if (timing_function_)
223 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
224
192 return to_return.PassAs<AnimationCurve>(); 225 return to_return.PassAs<AnimationCurve>();
193 } 226 }
194 227
195 SkColor KeyframedColorAnimationCurve::GetValue(double t) const { 228 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
196 if (t <= keyframes_.front()->Time()) 229 if (t <= keyframes_.front()->Time())
197 return keyframes_.front()->Value(); 230 return keyframes_.front()->Value();
198 231
199 if (t >= keyframes_.back()->Time()) 232 if (t >= keyframes_.back()->Time())
200 return keyframes_.back()->Value(); 233 return keyframes_.back()->Value();
201 234
202 size_t i = 0; 235 size_t i = 0;
203 for (; i < keyframes_.size() - 1; ++i) { 236 double progress = GetProgress(&keyframes_, &timing_function_, t, &i);
204 if (t < keyframes_[i + 1]->Time())
205 break;
206 }
207 237
208 float progress = GetProgress(t, i, keyframes_); 238 if (progress >= 1.)
239 return keyframes_.back()->Value();
209 240
210 return gfx::Tween::ColorValueBetween( 241 return gfx::Tween::ColorValueBetween(
211 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value()); 242 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
212 } 243 }
213 244
214 // KeyframedFloatAnimationCurve 245 // KeyframedFloatAnimationCurve
215 246
216 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve:: 247 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
217 Create() { 248 Create() {
218 return make_scoped_ptr(new KeyframedFloatAnimationCurve); 249 return make_scoped_ptr(new KeyframedFloatAnimationCurve);
(...skipping 10 matching lines...) Expand all
229 260
230 double KeyframedFloatAnimationCurve::Duration() const { 261 double KeyframedFloatAnimationCurve::Duration() const {
231 return keyframes_.back()->Time() - keyframes_.front()->Time(); 262 return keyframes_.back()->Time() - keyframes_.front()->Time();
232 } 263 }
233 264
234 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { 265 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
235 scoped_ptr<KeyframedFloatAnimationCurve> to_return( 266 scoped_ptr<KeyframedFloatAnimationCurve> to_return(
236 KeyframedFloatAnimationCurve::Create()); 267 KeyframedFloatAnimationCurve::Create());
237 for (size_t i = 0; i < keyframes_.size(); ++i) 268 for (size_t i = 0; i < keyframes_.size(); ++i)
238 to_return->AddKeyframe(keyframes_[i]->Clone()); 269 to_return->AddKeyframe(keyframes_[i]->Clone());
270
271 if (timing_function_)
272 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
273
239 return to_return.PassAs<AnimationCurve>(); 274 return to_return.PassAs<AnimationCurve>();
240 } 275 }
241 276
242 float KeyframedFloatAnimationCurve::GetValue(double t) const { 277 float KeyframedFloatAnimationCurve::GetValue(double t) const {
243 if (t <= keyframes_.front()->Time()) 278 if (t <= keyframes_.front()->Time())
244 return keyframes_.front()->Value(); 279 return keyframes_.front()->Value();
245 280
246 if (t >= keyframes_.back()->Time()) 281 if (t >= keyframes_.back()->Time())
247 return keyframes_.back()->Value(); 282 return keyframes_.back()->Value();
248 283
249 size_t i = 0; 284 size_t i = 0;
250 for (; i < keyframes_.size() - 1; ++i) { 285 double progress = GetProgress(&keyframes_, &timing_function_, t, &i);
251 if (t < keyframes_[i+1]->Time())
252 break;
253 }
254 286
255 float progress = GetProgress(t, i, keyframes_); 287 if (progress >= 1.)
288 return keyframes_.back()->Value();
256 289
257 return keyframes_[i]->Value() + 290 return keyframes_[i]->Value() +
258 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; 291 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
259 } 292 }
260 293
261 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve:: 294 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
262 Create() { 295 Create() {
263 return make_scoped_ptr(new KeyframedTransformAnimationCurve); 296 return make_scoped_ptr(new KeyframedTransformAnimationCurve);
264 } 297 }
265 298
266 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {} 299 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
267 300
268 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {} 301 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
269 302
270 void KeyframedTransformAnimationCurve::AddKeyframe( 303 void KeyframedTransformAnimationCurve::AddKeyframe(
271 scoped_ptr<TransformKeyframe> keyframe) { 304 scoped_ptr<TransformKeyframe> keyframe) {
272 InsertKeyframe(keyframe.Pass(), keyframes_); 305 InsertKeyframe(keyframe.Pass(), keyframes_);
273 } 306 }
274 307
275 double KeyframedTransformAnimationCurve::Duration() const { 308 double KeyframedTransformAnimationCurve::Duration() const {
276 return keyframes_.back()->Time() - keyframes_.front()->Time(); 309 return keyframes_.back()->Time() - keyframes_.front()->Time();
277 } 310 }
278 311
279 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { 312 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
280 scoped_ptr<KeyframedTransformAnimationCurve> to_return( 313 scoped_ptr<KeyframedTransformAnimationCurve> to_return(
281 KeyframedTransformAnimationCurve::Create()); 314 KeyframedTransformAnimationCurve::Create());
282 for (size_t i = 0; i < keyframes_.size(); ++i) 315 for (size_t i = 0; i < keyframes_.size(); ++i)
283 to_return->AddKeyframe(keyframes_[i]->Clone()); 316 to_return->AddKeyframe(keyframes_[i]->Clone());
317
318 if (timing_function_)
319 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
320
284 return to_return.PassAs<AnimationCurve>(); 321 return to_return.PassAs<AnimationCurve>();
285 } 322 }
286 323
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 { 324 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
307 if (t <= keyframes_.front()->Time()) 325 if (t <= keyframes_.front()->Time())
308 return keyframes_.front()->Value().Apply(); 326 return keyframes_.front()->Value().Apply();
309 327
310 if (t >= keyframes_.back()->Time()) 328 if (t >= keyframes_.back()->Time())
311 return keyframes_.back()->Value().Apply(); 329 return keyframes_.back()->Value().Apply();
312 330
313 return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t); 331 size_t i = 0;
332 double progress = GetProgress(&keyframes_, &timing_function_, t, &i);
333
334 if (progress >= 1.)
335 return keyframes_.back()->Value().Apply();
336
337 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
314 } 338 }
315 339
316 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( 340 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
317 const gfx::BoxF& box, 341 const gfx::BoxF& box,
318 gfx::BoxF* bounds) const { 342 gfx::BoxF* bounds) const {
319 DCHECK_GE(keyframes_.size(), 2ul); 343 DCHECK_GE(keyframes_.size(), 2ul);
320 *bounds = gfx::BoxF(); 344 *bounds = gfx::BoxF();
321 for (size_t i = 0; i < keyframes_.size() - 1; ++i) { 345 for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
322 gfx::BoxF bounds_for_step; 346 gfx::BoxF bounds_for_step;
323 float min_progress = 0.0; 347 float min_progress = 0.0;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 413
390 double KeyframedFilterAnimationCurve::Duration() const { 414 double KeyframedFilterAnimationCurve::Duration() const {
391 return keyframes_.back()->Time() - keyframes_.front()->Time(); 415 return keyframes_.back()->Time() - keyframes_.front()->Time();
392 } 416 }
393 417
394 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { 418 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
395 scoped_ptr<KeyframedFilterAnimationCurve> to_return( 419 scoped_ptr<KeyframedFilterAnimationCurve> to_return(
396 KeyframedFilterAnimationCurve::Create()); 420 KeyframedFilterAnimationCurve::Create());
397 for (size_t i = 0; i < keyframes_.size(); ++i) 421 for (size_t i = 0; i < keyframes_.size(); ++i)
398 to_return->AddKeyframe(keyframes_[i]->Clone()); 422 to_return->AddKeyframe(keyframes_[i]->Clone());
423
424 if (timing_function_)
425 to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get()));
426
399 return to_return.PassAs<AnimationCurve>(); 427 return to_return.PassAs<AnimationCurve>();
400 } 428 }
401 429
402 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { 430 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
403 if (t <= keyframes_.front()->Time()) 431 if (t <= keyframes_.front()->Time())
404 return keyframes_.front()->Value(); 432 return keyframes_.front()->Value();
405 433
406 if (t >= keyframes_.back()->Time()) 434 if (t >= keyframes_.back()->Time())
407 return keyframes_.back()->Value(); 435 return keyframes_.back()->Value();
408 436
409 return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t); 437 size_t i = 0;
438 double progress = GetProgress(&keyframes_, &timing_function_, t, &i);
439
440 if (progress >= 1.)
441 return keyframes_.back()->Value();
442
443 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
410 } 444 }
411 445
412 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const { 446 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
413 for (size_t i = 0; i < keyframes_.size(); ++i) { 447 for (size_t i = 0; i < keyframes_.size(); ++i) {
414 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) { 448 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
415 return true; 449 return true;
416 } 450 }
417 } 451 }
418 return false; 452 return false;
419 } 453 }
420 454
421 } // namespace cc 455 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698