diff options
Diffstat (limited to 'cc/CCKeyframedAnimationCurve.cpp')
-rw-r--r-- | cc/CCKeyframedAnimationCurve.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/cc/CCKeyframedAnimationCurve.cpp b/cc/CCKeyframedAnimationCurve.cpp new file mode 100644 index 0000000..d056b64 --- /dev/null +++ b/cc/CCKeyframedAnimationCurve.cpp @@ -0,0 +1,221 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "CCKeyframedAnimationCurve.h" + +#include <wtf/OwnPtr.h> + +using WebKit::WebTransformationMatrix; + +namespace WebCore { + +namespace { + +template <class Keyframe> +void insertKeyframe(PassOwnPtr<Keyframe> popKeyframe, Vector<OwnPtr<Keyframe> >& keyframes) +{ + OwnPtr<Keyframe> keyframe = popKeyframe; + + // Usually, the keyframes will be added in order, so this loop would be unnecessary and + // we should skip it if possible. + if (!keyframes.isEmpty() && keyframe->time() < keyframes.last()->time()) { + for (size_t i = 0; i < keyframes.size(); ++i) { + if (keyframe->time() < keyframes[i]->time()) { + keyframes.insert(i, keyframe.release()); + return; + } + } + } + + keyframes.append(keyframe.release()); +} + +PassOwnPtr<CCTimingFunction> cloneTimingFunction(const CCTimingFunction* timingFunction) +{ + ASSERT(timingFunction); + OwnPtr<CCAnimationCurve> curve(timingFunction->clone()); + return adoptPtr(static_cast<CCTimingFunction*>(curve.leakPtr())); +} + +} // namespace + +CCKeyframe::CCKeyframe(double time, PassOwnPtr<CCTimingFunction> timingFunction) + : m_time(time) + , m_timingFunction(timingFunction) +{ +} + +CCKeyframe::~CCKeyframe() +{ +} + +double CCKeyframe::time() const +{ + return m_time; +} + +const CCTimingFunction* CCKeyframe::timingFunction() const +{ + return m_timingFunction.get(); +} + +PassOwnPtr<CCFloatKeyframe> CCFloatKeyframe::create(double time, float value, PassOwnPtr<CCTimingFunction> timingFunction) +{ + return adoptPtr(new CCFloatKeyframe(time, value, timingFunction)); +} + +CCFloatKeyframe::CCFloatKeyframe(double time, float value, PassOwnPtr<CCTimingFunction> timingFunction) + : CCKeyframe(time, timingFunction) + , m_value(value) +{ +} + +CCFloatKeyframe::~CCFloatKeyframe() +{ +} + +float CCFloatKeyframe::value() const +{ + return m_value; +} + +PassOwnPtr<CCFloatKeyframe> CCFloatKeyframe::clone() const +{ + return CCFloatKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr); +} + +PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::create(double time, const WebKit::WebTransformOperations& value, PassOwnPtr<CCTimingFunction> timingFunction) +{ + return adoptPtr(new CCTransformKeyframe(time, value, timingFunction)); +} + +CCTransformKeyframe::CCTransformKeyframe(double time, const WebKit::WebTransformOperations& value, PassOwnPtr<CCTimingFunction> timingFunction) + : CCKeyframe(time, timingFunction) + , m_value(value) +{ +} + +CCTransformKeyframe::~CCTransformKeyframe() +{ +} + +const WebKit::WebTransformOperations& CCTransformKeyframe::value() const +{ + return m_value; +} + +PassOwnPtr<CCTransformKeyframe> CCTransformKeyframe::clone() const +{ + return CCTransformKeyframe::create(time(), value(), timingFunction() ? cloneTimingFunction(timingFunction()) : nullptr); +} + +PassOwnPtr<CCKeyframedFloatAnimationCurve> CCKeyframedFloatAnimationCurve::create() +{ + return adoptPtr(new CCKeyframedFloatAnimationCurve); +} + +CCKeyframedFloatAnimationCurve::CCKeyframedFloatAnimationCurve() +{ +} + +CCKeyframedFloatAnimationCurve::~CCKeyframedFloatAnimationCurve() +{ +} + +void CCKeyframedFloatAnimationCurve::addKeyframe(PassOwnPtr<CCFloatKeyframe> keyframe) +{ + insertKeyframe(keyframe, m_keyframes); +} + +double CCKeyframedFloatAnimationCurve::duration() const +{ + return m_keyframes.last()->time() - m_keyframes.first()->time(); +} + +PassOwnPtr<CCAnimationCurve> CCKeyframedFloatAnimationCurve::clone() const +{ + OwnPtr<CCKeyframedFloatAnimationCurve> toReturn(CCKeyframedFloatAnimationCurve::create()); + for (size_t i = 0; i < m_keyframes.size(); ++i) + toReturn->addKeyframe(m_keyframes[i]->clone()); + return toReturn.release(); +} + +float CCKeyframedFloatAnimationCurve::getValue(double t) const +{ + if (t <= m_keyframes.first()->time()) + return m_keyframes.first()->value(); + + if (t >= m_keyframes.last()->time()) + return m_keyframes.last()->value(); + + size_t i = 0; + for (; i < m_keyframes.size() - 1; ++i) { + if (t < m_keyframes[i+1]->time()) + break; + } + + float progress = static_cast<float>((t - m_keyframes[i]->time()) / (m_keyframes[i+1]->time() - m_keyframes[i]->time())); + + if (m_keyframes[i]->timingFunction()) + progress = m_keyframes[i]->timingFunction()->getValue(progress); + + return m_keyframes[i]->value() + (m_keyframes[i+1]->value() - m_keyframes[i]->value()) * progress; +} + +PassOwnPtr<CCKeyframedTransformAnimationCurve> CCKeyframedTransformAnimationCurve::create() +{ + return adoptPtr(new CCKeyframedTransformAnimationCurve); +} + +CCKeyframedTransformAnimationCurve::CCKeyframedTransformAnimationCurve() +{ +} + +CCKeyframedTransformAnimationCurve::~CCKeyframedTransformAnimationCurve() +{ +} + +void CCKeyframedTransformAnimationCurve::addKeyframe(PassOwnPtr<CCTransformKeyframe> keyframe) +{ + insertKeyframe(keyframe, m_keyframes); +} + +double CCKeyframedTransformAnimationCurve::duration() const +{ + return m_keyframes.last()->time() - m_keyframes.first()->time(); +} + +PassOwnPtr<CCAnimationCurve> CCKeyframedTransformAnimationCurve::clone() const +{ + OwnPtr<CCKeyframedTransformAnimationCurve> toReturn(CCKeyframedTransformAnimationCurve::create()); + for (size_t i = 0; i < m_keyframes.size(); ++i) + toReturn->addKeyframe(m_keyframes[i]->clone()); + return toReturn.release(); +} + +WebTransformationMatrix CCKeyframedTransformAnimationCurve::getValue(double t) const +{ + if (t <= m_keyframes.first()->time()) + return m_keyframes.first()->value().apply(); + + if (t >= m_keyframes.last()->time()) + return m_keyframes.last()->value().apply(); + + size_t i = 0; + for (; i < m_keyframes.size() - 1; ++i) { + if (t < m_keyframes[i+1]->time()) + break; + } + + double progress = (t - m_keyframes[i]->time()) / (m_keyframes[i+1]->time() - m_keyframes[i]->time()); + + if (m_keyframes[i]->timingFunction()) + progress = m_keyframes[i]->timingFunction()->getValue(progress); + + return m_keyframes[i+1]->value().blend(m_keyframes[i]->value(), progress); +} + +} // namespace WebCore |