blob: ea1b401644eec152a772f01225dcce8e357afea4 [file] [log] [blame]
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef KeyframeAnimationEffect_h
#define KeyframeAnimationEffect_h
#include "core/animation/AnimatableValue.h"
#include "core/animation/AnimationEffect.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
typedef HashSet<CSSPropertyID> PropertySet;
// Represents the keyframes set through the API.
class Keyframe : public RefCounted<Keyframe> {
public:
static PassRefPtr<Keyframe> create()
{
return adoptRef(new Keyframe);
}
static bool compareOffsets(const RefPtr<Keyframe>& a, const RefPtr<Keyframe>& b)
{
return a->offset() < b->offset();
}
void setOffset(double offset) { m_offset = offset; }
double offset() const { return m_offset; }
void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; }
AnimationEffect::CompositeOperation composite() const { return m_composite; }
void setPropertyValue(CSSPropertyID, const AnimatableValue*);
void clearPropertyValue(CSSPropertyID);
const AnimatableValue* propertyValue(CSSPropertyID) const;
PropertySet properties() const;
PassRefPtr<Keyframe> cloneWithOffset(double offset) const;
private:
Keyframe();
double m_offset;
AnimationEffect::CompositeOperation m_composite;
typedef HashMap<CSSPropertyID, RefPtr<AnimatableValue> > PropertyValueMap;
PropertyValueMap m_propertyValues;
};
class KeyframeAnimationEffect : public AnimationEffect {
public:
typedef Vector<RefPtr<Keyframe> > KeyframeVector;
// FIXME: Implement accumulation.
static PassRefPtr<KeyframeAnimationEffect> create(const KeyframeVector& keyframes)
{
return adoptRef(new KeyframeAnimationEffect(keyframes));
}
// AnimationEffect implementation.
virtual PassOwnPtr<CompositableValueMap> sample(int iteration, double fraction) const OVERRIDE;
// FIXME: Implement setFrames()
const KeyframeVector& getFrames() const { return m_keyframes; }
private:
class PropertySpecificKeyframe {
public:
PropertySpecificKeyframe(double offset, const AnimatableValue*, CompositeOperation);
double offset() const { return m_offset; }
const CompositableValue* value() const { return m_value.get(); }
PassOwnPtr<PropertySpecificKeyframe> cloneWithOffset(double offset) const;
private:
// Used by cloneWithOffset().
PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue>);
double m_offset;
RefPtr<CompositableValue> m_value;
};
class PropertySpecificKeyframeGroup {
public:
void appendKeyframe(PassOwnPtr<PropertySpecificKeyframe>);
void removeRedundantKeyframes();
void addSyntheticKeyframeIfRequired();
PassRefPtr<CompositableValue> sample(int iteration, double offset) const;
private:
typedef Vector<OwnPtr<PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
PropertySpecificKeyframeVector m_keyframes;
};
KeyframeAnimationEffect(const KeyframeVector& keyframes);
KeyframeVector normalizedKeyframes() const;
// Lazily computes the groups of property-specific keyframes.
void ensureKeyframeGroups();
KeyframeVector m_keyframes;
// The spec describes filtering the normalized keyframes at sampling time
// to get the 'property-specific keyframes'. For efficiency, we cache the
// property-specific lists.
typedef HashMap<CSSPropertyID, OwnPtr<PropertySpecificKeyframeGroup> > KeyframeGroupMap;
OwnPtr<KeyframeGroupMap> m_keyframeGroups;
};
} // namespace WebCore
#endif // KeyframeAnimationEffect_h