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.
7 #include "CCKeyframedAnimationCurve.h"
9 #include <wtf/OwnPtr.h>
11 using WebKit::WebTransformationMatrix
;
17 template <class Keyframe
>
18 void insertKeyframe(PassOwnPtr
<Keyframe
> popKeyframe
, OwnPtrVector
<Keyframe
>& keyframes
)
20 OwnPtr
<Keyframe
> keyframe
= popKeyframe
;
22 // Usually, the keyframes will be added in order, so this loop would be unnecessary and
23 // we should skip it if possible.
24 if (!keyframes
.isEmpty() && keyframe
->time() < keyframes
.last()->time()) {
25 for (size_t i
= 0; i
< keyframes
.size(); ++i
) {
26 if (keyframe
->time() < keyframes
[i
]->time()) {
27 keyframes
.insert(i
, keyframe
.release());
33 keyframes
.append(keyframe
.release());
36 PassOwnPtr
<CCTimingFunction
> cloneTimingFunction(const CCTimingFunction
* timingFunction
)
38 ASSERT(timingFunction
);
39 OwnPtr
<CCAnimationCurve
> curve(timingFunction
->clone());
40 return adoptPtr(static_cast<CCTimingFunction
*>(curve
.leakPtr()));
45 CCKeyframe::CCKeyframe(double time
, PassOwnPtr
<CCTimingFunction
> timingFunction
)
47 , m_timingFunction(timingFunction
)
51 CCKeyframe::~CCKeyframe()
55 double CCKeyframe::time() const
60 const CCTimingFunction
* CCKeyframe::timingFunction() const
62 return m_timingFunction
.get();
65 PassOwnPtr
<CCFloatKeyframe
> CCFloatKeyframe::create(double time
, float value
, PassOwnPtr
<CCTimingFunction
> timingFunction
)
67 return adoptPtr(new CCFloatKeyframe(time
, value
, timingFunction
));
70 CCFloatKeyframe::CCFloatKeyframe(double time
, float value
, PassOwnPtr
<CCTimingFunction
> timingFunction
)
71 : CCKeyframe(time
, timingFunction
)
76 CCFloatKeyframe::~CCFloatKeyframe()
80 float CCFloatKeyframe::value() const
85 PassOwnPtr
<CCFloatKeyframe
> CCFloatKeyframe::clone() const
87 return CCFloatKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr);
90 PassOwnPtr
<CCTransformKeyframe
> CCTransformKeyframe::create(double time
, const WebKit::WebTransformOperations
& value
, PassOwnPtr
<CCTimingFunction
> timingFunction
)
92 return adoptPtr(new CCTransformKeyframe(time
, value
, timingFunction
));
95 CCTransformKeyframe::CCTransformKeyframe(double time
, const WebKit::WebTransformOperations
& value
, PassOwnPtr
<CCTimingFunction
> timingFunction
)
96 : CCKeyframe(time
, timingFunction
)
101 CCTransformKeyframe::~CCTransformKeyframe()
105 const WebKit::WebTransformOperations
& CCTransformKeyframe::value() const
110 PassOwnPtr
<CCTransformKeyframe
> CCTransformKeyframe::clone() const
112 return CCTransformKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr);
115 PassOwnPtr
<CCKeyframedFloatAnimationCurve
> CCKeyframedFloatAnimationCurve::create()
117 return adoptPtr(new CCKeyframedFloatAnimationCurve
);
120 CCKeyframedFloatAnimationCurve::CCKeyframedFloatAnimationCurve()
124 CCKeyframedFloatAnimationCurve::~CCKeyframedFloatAnimationCurve()
128 void CCKeyframedFloatAnimationCurve::addKeyframe(PassOwnPtr
<CCFloatKeyframe
> keyframe
)
130 insertKeyframe(keyframe
, m_keyframes
);
133 double CCKeyframedFloatAnimationCurve::duration() const
135 return m_keyframes
.last()->time() - m_keyframes
.first()->time();
138 PassOwnPtr
<CCAnimationCurve
> CCKeyframedFloatAnimationCurve::clone() const
140 OwnPtr
<CCKeyframedFloatAnimationCurve
> toReturn(CCKeyframedFloatAnimationCurve::create());
141 for (size_t i
= 0; i
< m_keyframes
.size(); ++i
)
142 toReturn
->addKeyframe(m_keyframes
[i
]->clone());
143 return toReturn
.release();
146 float CCKeyframedFloatAnimationCurve::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 PassOwnPtr
<CCKeyframedTransformAnimationCurve
> CCKeyframedTransformAnimationCurve::create()
170 return adoptPtr(new CCKeyframedTransformAnimationCurve
);
173 CCKeyframedTransformAnimationCurve::CCKeyframedTransformAnimationCurve()
177 CCKeyframedTransformAnimationCurve::~CCKeyframedTransformAnimationCurve()
181 void CCKeyframedTransformAnimationCurve::addKeyframe(PassOwnPtr
<CCTransformKeyframe
> keyframe
)
183 insertKeyframe(keyframe
, m_keyframes
);
186 double CCKeyframedTransformAnimationCurve::duration() const
188 return m_keyframes
.last()->time() - m_keyframes
.first()->time();
191 PassOwnPtr
<CCAnimationCurve
> CCKeyframedTransformAnimationCurve::clone() const
193 OwnPtr
<CCKeyframedTransformAnimationCurve
> toReturn(CCKeyframedTransformAnimationCurve::create());
194 for (size_t i
= 0; i
< m_keyframes
.size(); ++i
)
195 toReturn
->addKeyframe(m_keyframes
[i
]->clone());
196 return toReturn
.release();
199 WebTransformationMatrix
CCKeyframedTransformAnimationCurve::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
);