Chromium Code Reviews| Index: Source/core/animation/css/CSSAnimations.cpp |
| diff --git a/Source/core/animation/css/CSSAnimations.cpp b/Source/core/animation/css/CSSAnimations.cpp |
| index aba27b809af4359204da7a4a461c298d1c498adf..e048bc921989935a1e0292379b52f7ea4b30e46a 100644 |
| --- a/Source/core/animation/css/CSSAnimations.cpp |
| +++ b/Source/core/animation/css/CSSAnimations.cpp |
| @@ -43,6 +43,7 @@ |
| #include "core/animation/css/CSSPropertyEquality.h" |
| #include "core/css/CSSKeyframeRule.h" |
| #include "core/css/CSSPropertyMetadata.h" |
| +#include "core/css/RenderStyleCSSValueMapping.h" |
| #include "core/css/resolver/CSSToStyleMap.h" |
| #include "core/css/resolver/StyleResolver.h" |
| #include "core/dom/Element.h" |
| @@ -86,7 +87,7 @@ CSSPropertyID propertyForAnimation(CSSPropertyID property) |
| } |
| static void resolveKeyframes(StyleResolver* resolver, const Element* animatingElement, Element& element, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction, |
| - AnimatableValueKeyframeVector& keyframes) |
| + StringKeyframeVector& keyframes) |
| { |
| // When the animating element is null, use its parent for scoping purposes. |
| const Element* elementForScoping = animatingElement ? animatingElement : &element; |
| @@ -101,7 +102,7 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl |
| for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| const StyleRuleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name); |
| - RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKeyframe::create(); |
| + RefPtrWillBeRawPtr<StringKeyframe> keyframe = StringKeyframe::create(); |
| const Vector<double>& offsets = styleKeyframe->keys(); |
| ASSERT(!offsets.isEmpty()); |
| keyframe->setOffset(offsets[0]); |
| @@ -123,13 +124,15 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl |
| } |
| keyframe->setEasing(timingFunction.release()); |
| } else if (CSSPropertyMetadata::isAnimatableProperty(property)) { |
| - keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, *keyframeStyle).get()); |
| + keyframe->setPropertyValue(property, properties.propertyAt(j).value()); |
| + if (property == CSSPropertyOpacity || property == CSSPropertyTransform) |
| + keyframe->setPropertyAnimatableValue(property, CSSAnimatableValueFactory::create(property, *keyframeStyle)); |
| } |
| } |
| keyframes.append(keyframe); |
| // The last keyframe specified at a given offset is used. |
| for (size_t j = 1; j < offsets.size(); ++j) { |
| - keyframes.append(toAnimatableValueKeyframe(keyframe->cloneWithOffset(offsets[j]).get())); |
| + keyframes.append(toStringKeyframe(keyframe->cloneWithOffset(offsets[j]).get())); |
| } |
| } |
| @@ -154,16 +157,16 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl |
| keyframes.shrink(targetIndex + 1); |
| // Add 0% and 100% keyframes if absent. |
| - RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = keyframes.isEmpty() ? nullptr : keyframes[0]; |
| + RefPtrWillBeRawPtr<StringKeyframe> startKeyframe = keyframes.isEmpty() ? nullptr : keyframes[0]; |
| if (!startKeyframe || keyframes[0]->offset() != 0) { |
| - startKeyframe = AnimatableValueKeyframe::create(); |
| + startKeyframe = StringKeyframe::create(); |
| startKeyframe->setOffset(0); |
| startKeyframe->setEasing(defaultTimingFunction); |
| keyframes.prepend(startKeyframe); |
| } |
| - RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframes.size() - 1]; |
| + RefPtrWillBeRawPtr<StringKeyframe> endKeyframe = keyframes[keyframes.size() - 1]; |
| if (endKeyframe->offset() != 1) { |
| - endKeyframe = AnimatableValueKeyframe::create(); |
| + endKeyframe = StringKeyframe::create(); |
| endKeyframe->setOffset(1); |
| endKeyframe->setEasing(defaultTimingFunction); |
| keyframes.append(endKeyframe); |
| @@ -172,7 +175,8 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl |
| ASSERT(!keyframes.first()->offset()); |
| ASSERT(keyframes.last()->offset() == 1); |
| - // Snapshot current property values for 0% and 100% if missing. |
| + // Explicitly create neutral keyframes for 0% and 100% if missing. |
| + // FIXME: Remove this once neutral keyframes are implemented in StringKeyframes. |
| PropertySet allProperties; |
| for (const auto& keyframe : keyframes) { |
| for (CSSPropertyID property : keyframe->properties()) |
| @@ -188,12 +192,22 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl |
| bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains(property); |
| if (!startNeedsValue && !endNeedsValue) |
| continue; |
| - RefPtrWillBeRawPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style); |
| - if (startNeedsValue) |
| - startKeyframe->setPropertyValue(property, snapshotValue.get()); |
| - if (endNeedsValue) |
| - endKeyframe->setPropertyValue(property, snapshotValue.get()); |
| - if (property == CSSPropertyOpacity || property == CSSPropertyTransform) |
| + |
| + bool isCompositableProperty = property == CSSPropertyOpacity || property == CSSPropertyTransform; |
| + |
| + if (startNeedsValue) { |
| + startKeyframe->setPropertyValue(property, nullptr); |
| + if (isCompositableProperty) |
| + startKeyframe->setPropertyAnimatableValue(property, CSSAnimatableValueFactory::create(property, style)); |
| + } |
| + |
| + if (endNeedsValue) { |
| + endKeyframe->setPropertyValue(property, nullptr); |
| + if (isCompositableProperty) |
| + endKeyframe->setPropertyAnimatableValue(property, CSSAnimatableValueFactory::create(property, style)); |
| + } |
| + |
| + if (isCompositableProperty) |
| UseCounter::count(elementForScoping->document(), UseCounter::SyntheticKeyframesInCompositedCSSAnimation); |
| } |
| } |
| @@ -265,15 +279,25 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E |
| AnimationPlayer* player = existing->value.get(); |
| + if (!activeAnimations || !activeAnimations->isAnimationStyleChange()) { |
|
Timothy Loh
2015/01/20 05:29:32
We refer to this so many times now, can we just pu
shend
2015/01/20 23:13:03
Done.
|
| + if (player->source()->isAnimation()) { |
|
Timothy Loh
2015/01/20 05:29:32
Is this check is because players for CSS animation
shend
2015/01/20 23:13:03
:)
|
| + Animation* animation = toAnimation(player->source()); |
|
Timothy Loh
2015/01/20 05:29:32
Just store the effect here?
shend
2015/01/20 23:13:03
Done.
|
| + if (animation->effect() && animation->effect()->isKeyframeEffectModel()) { |
| + toKeyframeEffectModelBase(animation->effect())->setDeferredInterpolationsOutdated(true); |
| + } |
| + } |
| + } |
| + |
| // FIXME: Should handle changes in the timing function. |
| if (timing != player->source()->specifiedTiming()) { |
| ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange()); |
| - AnimatableValueKeyframeVector resolvedKeyframes; |
| + StringKeyframeVector resolvedKeyframes; |
| resolveKeyframes(resolver, animatingElement, element, style, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes); |
| - update->updateAnimationTiming(player, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), |
| - timing, isPaused, player->currentTimeInternal()), timing); |
| + auto effect = StringKeyframeEffectModel::create(resolvedKeyframes); |
| + effect->forceConversionsToAnimatableValues(&element); // FIXME: remove this once LegacyStyleInterpolation is removed from StringKeyframe |
| + update->updateAnimationTiming(player, InertAnimation::create(effect, timing, isPaused, player->currentTimeInternal()), timing); |
| } |
| if (isPaused != player->paused()) { |
| @@ -285,11 +309,13 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E |
| } |
| } |
| - AnimatableValueKeyframeVector resolvedKeyframes; |
| + StringKeyframeVector resolvedKeyframes; |
| resolveKeyframes(resolver, animatingElement, element, style, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes); |
| if (!resolvedKeyframes.isEmpty()) { |
| ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange()); |
| - update->startAnimation(animationName, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused, 0)); |
| + auto effect = StringKeyframeEffectModel::create(resolvedKeyframes); |
| + effect->forceConversionsToAnimatableValues(&element); // FIXME: remove this once LegacyStyleInterpolation is removed from StringKeyframe |
| + update->startAnimation(animationName, InertAnimation::create(effect, timing, isPaused, 0)); |
| } |
| } |
| } |