Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Unified Diff: Source/core/animation/css/CSSAnimations.cpp

Issue 814083003: Update animation when changes in animation keyframes are detected. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/animation/css/CSSAnimations.cpp
diff --git a/Source/core/animation/css/CSSAnimations.cpp b/Source/core/animation/css/CSSAnimations.cpp
index 8efea0573bac83ebd72943d9ad76f1d501539ce0..7c937283c4689ff5ad9555b030942d06628a7cb1 100644
--- a/Source/core/animation/css/CSSAnimations.cpp
+++ b/Source/core/animation/css/CSSAnimations.cpp
@@ -88,7 +88,7 @@ static void resolveKeyframes(StyleResolver* resolver, const Element* animatingEl
{
// When the animating element is null, use its parent for scoping purposes.
const Element* elementForScoping = animatingElement ? animatingElement : &element;
- const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elementForScoping, name);
+ const StyleRuleKeyframes* keyframesRule = resolver->findKeyframesRule(elementForScoping, name).get();
if (!keyframesRule)
return;
@@ -206,7 +206,7 @@ CSSAnimations::CSSAnimations()
const AtomicString CSSAnimations::getAnimationNameForInspector(const AnimationPlayer& player)
{
for (const auto& it : m_animations) {
- if (it.value->sequenceNumber() == player.sequenceNumber())
+ if (it.value.player->sequenceNumber() == player.sequenceNumber())
return it.key;
}
return nullAtom;
@@ -235,6 +235,7 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E
const CSSAnimationData* animationData = style.animations();
const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->cssAnimations() : nullptr;
+ const Element* elementForScoping = animatingElement ? animatingElement : &element;
HashSet<AtomicString> inactive;
if (cssAnimations) {
@@ -251,25 +252,29 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E
const bool isPaused = CSSTimingData::getRepeated(animationData->playStateList(), i) == AnimPlayStatePaused;
Timing timing = animationData->convertToTiming(i);
+ Timing specifiedTiming = timing;
RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction;
timing.timingFunction = Timing::defaults().timingFunction;
+ RefPtrWillBeRawPtr<StyleRuleKeyframes> keyframesRule = resolver->findKeyframesRule(elementForScoping, animationName);
+ if (!keyframesRule)
+ continue; // Cancel the animation if there's no style rule for it.
+
if (cssAnimations) {
AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
if (existing != cssAnimations->m_animations.end()) {
inactive.remove(animationName);
- AnimationPlayer* player = existing->value.get();
-
- // FIXME: Should handle changes in the timing function.
- if (timing != player->source()->specifiedTiming()) {
- ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
+ const RunningAnimation& runningAnimation = existing->value;
+ AnimationPlayer* player = runningAnimation.player.get();
+ ASSERT(keyframesRule);
+ if (keyframesRule != runningAnimation.styleRule || keyframesRule->styleChangeCounter() != runningAnimation.styleChangeCounter || runningAnimation.specifiedTiming != specifiedTiming) {
AnimatableValueKeyframeVector resolvedKeyframes;
resolveKeyframes(resolver, animatingElement, element, style, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes);
- update->updateAnimationTiming(player, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes),
- timing, isPaused, player->currentTimeInternal()), timing);
+ update->updateAnimation(animationName, player, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes),
+ timing, isPaused, player->currentTimeInternal()), specifiedTiming, keyframesRule);
}
if (isPaused != player->paused()) {
@@ -285,7 +290,7 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E
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));
+ update->startAnimation(animationName, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused, 0), specifiedTiming, keyframesRule);
}
}
}
@@ -293,7 +298,7 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, const E
ASSERT(inactive.isEmpty() || cssAnimations);
for (const AtomicString& animationName : inactive) {
ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
- update->cancelAnimation(animationName, *cssAnimations->m_animations.get(animationName));
+ update->cancelAnimation(animationName, *cssAnimations->m_animations.get(animationName).player);
}
}
@@ -314,13 +319,13 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
DisableCompositingQueryAsserts disabler;
for (const AtomicString& animationName : update->cancelledAnimationNames()) {
- RefPtrWillBeRawPtr<AnimationPlayer> player = m_animations.take(animationName);
+ RefPtrWillBeRawPtr<AnimationPlayer> player = m_animations.take(animationName).player;
player->cancel();
player->update(TimingUpdateOnDemand);
}
for (const AtomicString& animationName : update->animationsWithPauseToggled()) {
- AnimationPlayer* player = m_animations.get(animationName);
+ AnimationPlayer* player = m_animations.get(animationName).player.get();
if (player->paused())
player->unpause();
else
@@ -329,9 +334,16 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
player->update(TimingUpdateOnDemand);
}
- for (const auto& timingUpdate : update->animationsWithTimingUpdates()) {
- timingUpdate.player->source()->updateSpecifiedTiming(timingUpdate.newTiming);
- timingUpdate.player->update(TimingUpdateOnDemand);
+ for (const auto& entry : update->animationsWithUpdates()) {
+ Animation* animation = toAnimation(entry.player->source());
+
+ animation->setEffect(entry.animation->effect());
+ animation->updateSpecifiedTiming(entry.animation->specifiedTiming());
+
+ auto& runningAnimation = m_animations.find(entry.name)->value;
+ runningAnimation.styleRule = entry.styleRule;
+ runningAnimation.styleChangeCounter = entry.styleChangeCounter;
+ runningAnimation.specifiedTiming = entry.specifiedTiming;
}
for (const auto& entry : update->newAnimations()) {
@@ -343,7 +355,14 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
if (inertAnimation->paused())
player->pause();
player->update(TimingUpdateOnDemand);
- m_animations.set(entry.name, player.get());
+
+ RunningAnimation runningAnimation;
+ runningAnimation.player = player;
+ runningAnimation.specifiedTiming = entry.timing;
+ runningAnimation.styleRule = entry.styleRule;
+ runningAnimation.styleChangeCounter = entry.styleChangeCounter;
+
+ m_animations.set(entry.name, runningAnimation);
}
// Transitions that are run on the compositor only update main-thread state
@@ -533,8 +552,8 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
void CSSAnimations::cancel()
{
for (const auto& entry : m_animations) {
- entry.value->cancel();
- entry.value->update(TimingUpdateOnDemand);
+ entry.value.player->cancel();
+ entry.value.player->update(TimingUpdateOnDemand);
}
for (const auto& entry : m_transitions) {
@@ -561,8 +580,8 @@ void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* u
WillBeHeapVector<RawPtrWillBeMember<InertAnimation>> newAnimations;
for (const auto& newAnimation : update->newAnimations())
newAnimations.append(newAnimation.animation.get());
- for (const auto& updatedAnimation : update->animationsWithTimingUpdates())
- newAnimations.append(updatedAnimation.animation.get()); // Animations with timing updates use a temporary InertAnimation for the current frame.
+ for (const auto& updatedAnimation : update->animationsWithUpdates())
+ newAnimations.append(updatedAnimation.animation.get()); // Animations with updates use a temporary InertAnimation for the current frame.
WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation>> activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newAnimations, &update->suppressedAnimationAnimationPlayers(), Animation::DefaultPriority, timelineCurrentTime));
update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
@@ -748,7 +767,7 @@ void CSSAnimationUpdate::trace(Visitor* visitor)
visitor->trace(m_activeInterpolationsForTransitions);
visitor->trace(m_newAnimations);
visitor->trace(m_suppressedAnimationPlayers);
- visitor->trace(m_animationsWithTimingUpdates);
+ visitor->trace(m_animationsWithUpdates);
#endif
}

Powered by Google App Engine
This is Rietveld 408576698