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
3 // found in the LICENSE file.
5 #include "cc/animation/keyframed_animation_curve.h"
11 template <class Keyframe
>
12 void InsertKeyframe(scoped_ptr
<Keyframe
> keyframe
,
13 ScopedPtrVector
<Keyframe
>& keyframes
) {
14 // Usually, the keyframes will be added in order, so this loop would be
15 // unnecessary and we should skip it if possible.
16 if (!keyframes
.empty() && keyframe
->Time() < keyframes
.back()->Time()) {
17 for (size_t i
= 0; i
< keyframes
.size(); ++i
) {
18 if (keyframe
->Time() < keyframes
[i
]->Time()) {
19 keyframes
.insert(keyframes
.begin() + i
, keyframe
.Pass());
25 keyframes
.push_back(keyframe
.Pass());
28 scoped_ptr
<TimingFunction
> CloneTimingFunction(
29 const TimingFunction
* timing_function
) {
30 DCHECK(timing_function
);
31 scoped_ptr
<AnimationCurve
> curve(timing_function
->Clone());
32 return scoped_ptr
<TimingFunction
>(
33 static_cast<TimingFunction
*>(curve
.release()));
38 Keyframe::Keyframe(double time
, scoped_ptr
<TimingFunction
> timing_function
)
40 timing_function_(timing_function
.Pass()) {}
42 Keyframe::~Keyframe() {}
44 double Keyframe::Time() const {
48 scoped_ptr
<FloatKeyframe
> FloatKeyframe::Create(
51 scoped_ptr
<TimingFunction
> timing_function
) {
52 return make_scoped_ptr(
53 new FloatKeyframe(time
, value
, timing_function
.Pass()));
56 FloatKeyframe::FloatKeyframe(double time
,
58 scoped_ptr
<TimingFunction
> timing_function
)
59 : Keyframe(time
, timing_function
.Pass()),
62 FloatKeyframe::~FloatKeyframe() {}
64 float FloatKeyframe::Value() const {
68 scoped_ptr
<FloatKeyframe
> FloatKeyframe::Clone() const {
69 scoped_ptr
<TimingFunction
> func
;
70 if (timing_function())
71 func
= CloneTimingFunction(timing_function());
72 return FloatKeyframe::Create(Time(), Value(), func
.Pass());
75 scoped_ptr
<TransformKeyframe
> TransformKeyframe::Create(
77 const TransformOperations
& value
,
78 scoped_ptr
<TimingFunction
> timing_function
) {
79 return make_scoped_ptr(
80 new TransformKeyframe(time
, value
, timing_function
.Pass()));
83 TransformKeyframe::TransformKeyframe(double time
,
84 const TransformOperations
& value
,
85 scoped_ptr
<TimingFunction
> timing_function
)
86 : Keyframe(time
, timing_function
.Pass()),
89 TransformKeyframe::~TransformKeyframe() {}
91 const TransformOperations
& TransformKeyframe::Value() const {
95 scoped_ptr
<TransformKeyframe
> TransformKeyframe::Clone() const {
96 scoped_ptr
<TimingFunction
> func
;
97 if (timing_function())
98 func
= CloneTimingFunction(timing_function());
99 return TransformKeyframe::Create(Time(), Value(), func
.Pass());
102 scoped_ptr
<KeyframedFloatAnimationCurve
> KeyframedFloatAnimationCurve::
104 return make_scoped_ptr(new KeyframedFloatAnimationCurve
);
107 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
109 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
111 void KeyframedFloatAnimationCurve::AddKeyframe(
112 scoped_ptr
<FloatKeyframe
> keyframe
) {
113 InsertKeyframe(keyframe
.Pass(), keyframes_
);
116 double KeyframedFloatAnimationCurve::Duration() const {
117 return keyframes_
.back()->Time() - keyframes_
.front()->Time();
120 scoped_ptr
<AnimationCurve
> KeyframedFloatAnimationCurve::Clone() const {
121 scoped_ptr
<KeyframedFloatAnimationCurve
> to_return(
122 KeyframedFloatAnimationCurve::Create());
123 for (size_t i
= 0; i
< keyframes_
.size(); ++i
)
124 to_return
->AddKeyframe(keyframes_
[i
]->Clone());
125 return to_return
.PassAs
<AnimationCurve
>();
128 float KeyframedFloatAnimationCurve::GetValue(double t
) const {
129 if (t
<= keyframes_
.front()->Time())
130 return keyframes_
.front()->Value();
132 if (t
>= keyframes_
.back()->Time())
133 return keyframes_
.back()->Value();
136 for (; i
< keyframes_
.size() - 1; ++i
) {
137 if (t
< keyframes_
[i
+1]->Time())
142 static_cast<float>((t
- keyframes_
[i
]->Time()) /
143 (keyframes_
[i
+1]->Time() - keyframes_
[i
]->Time()));
145 if (keyframes_
[i
]->timing_function())
146 progress
= keyframes_
[i
]->timing_function()->GetValue(progress
);
148 return keyframes_
[i
]->Value() +
149 (keyframes_
[i
+1]->Value() - keyframes_
[i
]->Value()) * progress
;
152 scoped_ptr
<KeyframedTransformAnimationCurve
> KeyframedTransformAnimationCurve::
154 return make_scoped_ptr(new KeyframedTransformAnimationCurve
);
157 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
159 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
161 void KeyframedTransformAnimationCurve::AddKeyframe(
162 scoped_ptr
<TransformKeyframe
> keyframe
) {
163 InsertKeyframe(keyframe
.Pass(), keyframes_
);
166 double KeyframedTransformAnimationCurve::Duration() const {
167 return keyframes_
.back()->Time() - keyframes_
.front()->Time();
170 scoped_ptr
<AnimationCurve
> KeyframedTransformAnimationCurve::Clone() const {
171 scoped_ptr
<KeyframedTransformAnimationCurve
> to_return(
172 KeyframedTransformAnimationCurve::Create());
173 for (size_t i
= 0; i
< keyframes_
.size(); ++i
)
174 to_return
->AddKeyframe(keyframes_
[i
]->Clone());
175 return to_return
.PassAs
<AnimationCurve
>();
178 gfx::Transform
KeyframedTransformAnimationCurve::GetValue(double t
) const {
179 if (t
<= keyframes_
.front()->Time())
180 return keyframes_
.front()->Value().Apply();
182 if (t
>= keyframes_
.back()->Time())
183 return keyframes_
.back()->Value().Apply();
186 for (; i
< keyframes_
.size() - 1; ++i
) {
187 if (t
< keyframes_
[i
+1]->Time())
191 double progress
= (t
- keyframes_
[i
]->Time()) /
192 (keyframes_
[i
+1]->Time() - keyframes_
[i
]->Time());
194 if (keyframes_
[i
]->timing_function())
195 progress
= keyframes_
[i
]->timing_function()->GetValue(progress
);
197 return keyframes_
[i
+1]->Value().Blend(keyframes_
[i
]->Value(), progress
);