using namespace WebCore;
-class ReplaceCompositableValue FINAL : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<ReplaceCompositableValue> create(const AnimatableValue* value)
- {
- return adoptRef(new ReplaceCompositableValue(value));
- }
- virtual bool dependsOnUnderlyingValue() const OVERRIDE
- {
- return false;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const OVERRIDE
- {
- return PassRefPtr<AnimatableValue>(m_value);
- }
-private:
- ReplaceCompositableValue(const AnimatableValue* value)
- : m_value(const_cast<AnimatableValue*>(value))
- {
- }
- RefPtr<AnimatableValue> m_value;
-};
-
class AddCompositableValue FINAL : public AnimationEffect::CompositableValue {
public:
static PassRefPtr<AddCompositableValue> create(const AnimatableValue* value)
bool m_dependsOnUnderlyingValue;
};
+const double accuracyForKeyframeEasing = 0.0000001;
+
} // namespace
Keyframe::Keyframe(const Keyframe& copyFrom)
: m_offset(copyFrom.m_offset)
, m_composite(copyFrom.m_composite)
+ , m_easing(copyFrom.m_easing)
{
for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
setPropertyValue(iter->key, iter->value.get());
for (PropertySet::const_iterator propertyIter = keyframeProperties.begin(); propertyIter != keyframeProperties.end(); ++propertyIter) {
CSSPropertyID property = *propertyIter;
KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(property);
- if (groupIter == m_keyframeGroups->end()) {
- KeyframeGroupMap::AddResult result = m_keyframeGroups->add(property, adoptPtr(new PropertySpecificKeyframeGroup));
- ASSERT(result.isNewEntry);
- groupIter = result.iterator;
- }
- groupIter->value->appendKeyframe(adoptPtr(
- new PropertySpecificKeyframe(keyframe->offset(), keyframe->propertyValue(property), keyframe->composite())));
+ PropertySpecificKeyframeGroup* group;
+ if (groupIter == m_keyframeGroups->end())
+ group = m_keyframeGroups->add(property, adoptPtr(new PropertySpecificKeyframeGroup)).storedValue->value.get();
+ else
+ group = groupIter->value.get();
+
+ group->appendKeyframe(adoptPtr(
+ new PropertySpecificKeyframe(keyframe->offset(), keyframe->easing(), keyframe->propertyValue(property), keyframe->composite())));
}
}
}
-KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, const AnimatableValue* value, CompositeOperation composite)
+KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, CompositeOperation composite)
: m_offset(offset)
+ , m_easing(easing)
, m_value(composite == AnimationEffect::CompositeReplace ?
- static_cast<PassRefPtr<CompositableValue> >(ReplaceCompositableValue::create(value)) :
+ AnimatableValue::takeConstRef(value) :
static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create(value)))
{
}
-KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue> value)
+KeyframeEffectModel::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, PassRefPtr<CompositableValue> value)
: m_offset(offset)
+ , m_easing(easing)
, m_value(value)
{
ASSERT(!isNull(m_offset));
PassOwnPtr<KeyframeEffectModel::PropertySpecificKeyframe> KeyframeEffectModel::PropertySpecificKeyframe::cloneWithOffset(double offset) const
{
- return adoptPtr(new PropertySpecificKeyframe(offset, PassRefPtr<CompositableValue>(m_value)));
+ return adoptPtr(new PropertySpecificKeyframe(offset, m_easing, PassRefPtr<CompositableValue>(m_value)));
}
if (!offset)
appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
else
- m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, AnimatableValue::neutralValue(), CompositeAdd)));
+ m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, 0, AnimatableValue::neutralValue(), CompositeAdd)));
}
PassRefPtr<AnimationEffect::CompositableValue> KeyframeEffectModel::PropertySpecificKeyframeGroup::sample(int iteration, double offset) const
return const_cast<CompositableValue*>((*before)->value());
if ((*after)->offset() == offset)
return const_cast<CompositableValue*>((*after)->value());
- return BlendedCompositableValue::create((*before)->value(), (*after)->value(),
- (offset - (*before)->offset()) / ((*after)->offset() - (*before)->offset()));
+
+ double fraction = (offset - (*before)->offset()) / ((*after)->offset() - (*before)->offset());
+ if (const TimingFunction* timingFunction = (*before)->easing())
+ fraction = timingFunction->evaluate(fraction, accuracyForKeyframeEasing);
+ return BlendedCompositableValue::create((*before)->value(), (*after)->value(), fraction);
}
} // namespace