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/keyframed_animation_curve.h"
7 using WebKit::WebTransformationMatrix
;
13 template <class Keyframe
>
14 void insertKeyframe(scoped_ptr
<Keyframe
> keyframe
, ScopedPtrVector
<Keyframe
>& keyframes
)
16 // Usually, the keyframes will be added in order, so this loop would be unnecessary and
17 // we should skip it if possible.
18 if (!keyframes
.isEmpty() && keyframe
->time() < keyframes
.last()->time()) {
19 for (size_t i
= 0; i
< keyframes
.size(); ++i
) {
20 if (keyframe
->time() < keyframes
[i
]->time()) {
21 keyframes
.insert(i
, keyframe
.Pass());
27 keyframes
.append(keyframe
.Pass());
30 scoped_ptr
<TimingFunction
> cloneTimingFunction(const TimingFunction
* timingFunction
)
32 DCHECK(timingFunction
);
33 scoped_ptr
<AnimationCurve
> curve(timingFunction
->clone());
34 return scoped_ptr
<TimingFunction
>(static_cast<TimingFunction
*>(curve
.release()));
39 Keyframe::Keyframe(double time
, scoped_ptr
<TimingFunction
> timingFunction
)
41 , m_timingFunction(timingFunction
.Pass())
49 double Keyframe::time() const
54 const TimingFunction
* Keyframe::timingFunction() const
56 return m_timingFunction
.get();
59 scoped_ptr
<FloatKeyframe
> FloatKeyframe::create(double time
, float value
, scoped_ptr
<TimingFunction
> timingFunction
)
61 return make_scoped_ptr(new FloatKeyframe(time
, value
, timingFunction
.Pass()));
64 FloatKeyframe::FloatKeyframe(double time
, float value
, scoped_ptr
<TimingFunction
> timingFunction
)
65 : Keyframe(time
, timingFunction
.Pass())
70 FloatKeyframe::~FloatKeyframe()
74 float FloatKeyframe::value() const
79 scoped_ptr
<FloatKeyframe
> FloatKeyframe::clone() const
81 scoped_ptr
<TimingFunction
> func
;
83 func
= cloneTimingFunction(timingFunction());
84 return FloatKeyframe::create(time(), value(), func
.Pass());
87 scoped_ptr
<TransformKeyframe
> TransformKeyframe::create(double time
, const WebKit::WebTransformOperations
& value
, scoped_ptr
<TimingFunction
> timingFunction
)
89 return make_scoped_ptr(new TransformKeyframe(time
, value
, timingFunction
.Pass()));
92 TransformKeyframe::TransformKeyframe(double time
, const WebKit::WebTransformOperations
& value
, scoped_ptr
<TimingFunction
> timingFunction
)
93 : Keyframe(time
, timingFunction
.Pass())
98 TransformKeyframe::~TransformKeyframe()
102 const WebKit::WebTransformOperations
& TransformKeyframe::value() const
107 scoped_ptr
<TransformKeyframe
> TransformKeyframe::clone() const
109 scoped_ptr
<TimingFunction
> func
;
110 if (timingFunction())
111 func
= cloneTimingFunction(timingFunction());
112 return TransformKeyframe::create(time(), value(), func
.Pass());
115 scoped_ptr
<KeyframedFloatAnimationCurve
> KeyframedFloatAnimationCurve::create()
117 return make_scoped_ptr(new KeyframedFloatAnimationCurve
);
120 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve()
124 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve()
128 void KeyframedFloatAnimationCurve::addKeyframe(scoped_ptr
<FloatKeyframe
> keyframe
)
130 insertKeyframe(keyframe
.Pass(), m_keyframes
);
133 double KeyframedFloatAnimationCurve::duration() const
135 return m_keyframes
.last()->time() - m_keyframes
.first()->time();
138 scoped_ptr
<AnimationCurve
> KeyframedFloatAnimationCurve::clone() const
140 scoped_ptr
<KeyframedFloatAnimationCurve
> toReturn(KeyframedFloatAnimationCurve::create());
141 for (size_t i
= 0; i
< m_keyframes
.size(); ++i
)
142 toReturn
->addKeyframe(m_keyframes
[i
]->clone());
143 return toReturn
.PassAs
<AnimationCurve
>();
146 float KeyframedFloatAnimationCurve::getValue(double t
) const
148 if (t
<= m_keyframes
.first()->time())
149 return m_keyframes
.first()->value();
151 if (t
>= m_keyframes
.last()->time())
152 return m_keyframes
.last()->value();
155 for (; i
< m_keyframes
.size() - 1; ++i
) {
156 if (t
< m_keyframes
[i
+1]->time())
160 float progress
= static_cast<float>((t
- m_keyframes
[i
]->time()) / (m_keyframes
[i
+1]->time() - m_keyframes
[i
]->time()));
162 if (m_keyframes
[i
]->timingFunction())
163 progress
= m_keyframes
[i
]->timingFunction()->getValue(progress
);
165 return m_keyframes
[i
]->value() + (m_keyframes
[i
+1]->value() - m_keyframes
[i
]->value()) * progress
;
168 scoped_ptr
<KeyframedTransformAnimationCurve
> KeyframedTransformAnimationCurve::create()
170 return make_scoped_ptr(new KeyframedTransformAnimationCurve
);
173 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve()
177 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve()
181 void KeyframedTransformAnimationCurve::addKeyframe(scoped_ptr
<TransformKeyframe
> keyframe
)
183 insertKeyframe(keyframe
.Pass(), m_keyframes
);
186 double KeyframedTransformAnimationCurve::duration() const
188 return m_keyframes
.last()->time() - m_keyframes
.first()->time();
191 scoped_ptr
<AnimationCurve
> KeyframedTransformAnimationCurve::clone() const
193 scoped_ptr
<KeyframedTransformAnimationCurve
> toReturn(KeyframedTransformAnimationCurve::create());
194 for (size_t i
= 0; i
< m_keyframes
.size(); ++i
)
195 toReturn
->addKeyframe(m_keyframes
[i
]->clone());
196 return toReturn
.PassAs
<AnimationCurve
>();
199 WebTransformationMatrix
KeyframedTransformAnimationCurve::getValue(double t
) const
201 if (t
<= m_keyframes
.first()->time())
202 return m_keyframes
.first()->value().apply();
204 if (t
>= m_keyframes
.last()->time())
205 return m_keyframes
.last()->value().apply();
208 for (; i
< m_keyframes
.size() - 1; ++i
) {
209 if (t
< m_keyframes
[i
+1]->time())
213 double progress
= (t
- m_keyframes
[i
]->time()) / (m_keyframes
[i
+1]->time() - m_keyframes
[i
]->time());
215 if (m_keyframes
[i
]->timingFunction())
216 progress
= m_keyframes
[i
]->timingFunction()->getValue(progress
);
218 return m_keyframes
[i
+1]->value().blend(m_keyframes
[i
]->value(), progress
);