Index: cc/animation/keyframed_animation_curve.cc |
diff --git a/cc/animation/keyframed_animation_curve.cc b/cc/animation/keyframed_animation_curve.cc |
index 4522ca2e6d98029a155e540743d4a2a7a653c429..092ed5fd16a1eb5657bd36bd0060aa363add470c 100644 |
--- a/cc/animation/keyframed_animation_curve.cc |
+++ b/cc/animation/keyframed_animation_curve.cc |
@@ -29,14 +29,43 @@ void InsertKeyframe(scoped_ptr<Keyframe> keyframe, |
keyframes.push_back(keyframe.Pass()); |
} |
-template <class Keyframes> |
-float GetProgress(double t, size_t i, const Keyframes& keyframes) { |
- float progress = |
- static_cast<float>((t - keyframes[i]->Time()) / |
- (keyframes[i + 1]->Time() - keyframes[i]->Time())); |
- |
- if (keyframes[i]->timing_function()) |
- progress = keyframes[i]->timing_function()->GetValue(progress); |
+// 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.
|
+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
|
+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
|
+ const scoped_ptr<TimingFunction>* timing_function, |
+ double time, |
+ size_t* i) { |
+ double t = time; |
samli
2014/09/24 07:55:32
Unnecessary variable
ikilpatrick
2014/09/25 04:33:25
Done.
|
+ double end_time = (*keyframes).back()->Time(); |
+ |
+ // Apply the curve timing function. |
+ if (*timing_function) { |
+ double start_time = (*keyframes).front()->Time(); |
+ double duration = end_time - start_time; |
+ double animationProgress = (t - start_time) / duration; |
+ |
+ t = (*timing_function)->GetValue(animationProgress) * duration + start_time; |
+ } |
+ |
+ // May have exceeded the end time of the last keyframe. |
+ if (t >= end_time) |
+ return 1.; |
+ |
+ // Find the active keyframe. |
+ *i = 0; |
+ for (; *i < keyframes->size() - 1; ++*i) { |
+ if (t < (*keyframes)[*i + 1]->Time()) |
+ break; |
+ } |
+ |
+ double progress = (t - (*keyframes)[*i]->Time()) / |
+ ((*keyframes)[*i + 1]->Time() - (*keyframes)[*i]->Time()); |
+ |
+ if ((*keyframes)[*i]->timing_function()) |
+ // Clamp progress as timing functions only valid for inputs [0,1]. |
+ progress = (*keyframes)[*i]->timing_function()->GetValue( |
+ 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
|
+ |
return progress; |
} |
@@ -189,6 +218,10 @@ scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const { |
KeyframedColorAnimationCurve::Create()); |
for (size_t i = 0; i < keyframes_.size(); ++i) |
to_return->AddKeyframe(keyframes_[i]->Clone()); |
+ |
+ if (timing_function_) |
+ to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get())); |
+ |
return to_return.PassAs<AnimationCurve>(); |
} |
@@ -200,12 +233,10 @@ SkColor KeyframedColorAnimationCurve::GetValue(double t) const { |
return keyframes_.back()->Value(); |
size_t i = 0; |
- for (; i < keyframes_.size() - 1; ++i) { |
- if (t < keyframes_[i + 1]->Time()) |
- break; |
- } |
+ double progress = GetProgress(&keyframes_, &timing_function_, t, &i); |
- float progress = GetProgress(t, i, keyframes_); |
+ if (progress >= 1.) |
+ return keyframes_.back()->Value(); |
return gfx::Tween::ColorValueBetween( |
progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value()); |
@@ -236,6 +267,10 @@ scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const { |
KeyframedFloatAnimationCurve::Create()); |
for (size_t i = 0; i < keyframes_.size(); ++i) |
to_return->AddKeyframe(keyframes_[i]->Clone()); |
+ |
+ if (timing_function_) |
+ to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get())); |
+ |
return to_return.PassAs<AnimationCurve>(); |
} |
@@ -247,12 +282,10 @@ float KeyframedFloatAnimationCurve::GetValue(double t) const { |
return keyframes_.back()->Value(); |
size_t i = 0; |
- for (; i < keyframes_.size() - 1; ++i) { |
- if (t < keyframes_[i+1]->Time()) |
- break; |
- } |
+ double progress = GetProgress(&keyframes_, &timing_function_, t, &i); |
- float progress = GetProgress(t, i, keyframes_); |
+ if (progress >= 1.) |
+ return keyframes_.back()->Value(); |
return keyframes_[i]->Value() + |
(keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress; |
@@ -281,26 +314,11 @@ scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const { |
KeyframedTransformAnimationCurve::Create()); |
for (size_t i = 0; i < keyframes_.size(); ++i) |
to_return->AddKeyframe(keyframes_[i]->Clone()); |
- return to_return.PassAs<AnimationCurve>(); |
-} |
- |
-// Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time(). |
-template<typename ValueType, typename KeyframeType> |
-static ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes, |
- double t) { |
- size_t i = 0; |
- for (; i < keyframes->size() - 1; ++i) { |
- if (t < (*keyframes)[i+1]->Time()) |
- break; |
- } |
- |
- double progress = (t - (*keyframes)[i]->Time()) / |
- ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time()); |
- if ((*keyframes)[i]->timing_function()) |
- progress = (*keyframes)[i]->timing_function()->GetValue(progress); |
+ if (timing_function_) |
+ to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get())); |
- return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress); |
+ return to_return.PassAs<AnimationCurve>(); |
} |
gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { |
@@ -310,7 +328,13 @@ gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const { |
if (t >= keyframes_.back()->Time()) |
return keyframes_.back()->Value().Apply(); |
- return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t); |
+ size_t i = 0; |
+ double progress = GetProgress(&keyframes_, &timing_function_, t, &i); |
+ |
+ if (progress >= 1.) |
+ return keyframes_.back()->Value().Apply(); |
+ |
+ return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress); |
} |
bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox( |
@@ -396,6 +420,10 @@ scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const { |
KeyframedFilterAnimationCurve::Create()); |
for (size_t i = 0; i < keyframes_.size(); ++i) |
to_return->AddKeyframe(keyframes_[i]->Clone()); |
+ |
+ if (timing_function_) |
+ to_return->SetTimingFunction(CloneTimingFunction(timing_function_.get())); |
+ |
return to_return.PassAs<AnimationCurve>(); |
} |
@@ -406,7 +434,13 @@ FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const { |
if (t >= keyframes_.back()->Time()) |
return keyframes_.back()->Value(); |
- return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t); |
+ size_t i = 0; |
+ double progress = GetProgress(&keyframes_, &timing_function_, t, &i); |
+ |
+ if (progress >= 1.) |
+ return keyframes_.back()->Value(); |
+ |
+ return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress); |
} |
bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const { |