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

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: Rebase. 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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/animation/keyframed_animation_curve.h ('k') | cc/animation/keyframed_animation_curve_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698