void CompositeAnimationPrivate::styleAvailable()
{
    if (m_numStyleAvailableWaiters == 0)
        return;

    // We have to go through animations in the order in which they appear in
    // the style, because order matters for additivity.
    Vector<RefPtr<KeyframeAnimation> > animations(m_keyframeAnimations.size());
    copyValuesToVector(m_keyframeAnimations, animations);

    if (animations.size() > 1)
        std::stable_sort(animations.begin(), animations.end(), compareAnimationIndices);

    for (size_t i = 0; i < animations.size(); ++i) {
        KeyframeAnimation* anim = animations[i].get();
        if (anim && anim->waitingForStyleAvailable())
            anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
    }

    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation* anim = it->second.get();
        if (anim && anim->waitingForStyleAvailable())
            anim->updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
    }
}
double CompositeAnimation::timeToNextService() const
{
    // Returns the time at which next service is required. -1 means no service is required. 0 means 
    // service is required now, and > 0 means service is required that many seconds in the future.
    double minT = -1;
    
    if (!m_transitions.isEmpty()) {
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* transition = it->second.get();
            double t = transition ? transition->timeToNextService() : -1;
            if (t < minT || minT == -1)
                minT = t;
            if (minT == 0)
                return 0;
        }
    }
    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* animation = it->second.get();
            double t = animation ? animation->timeToNextService() : -1;
            if (t < minT || minT == -1)
                minT = t;
            if (minT == 0)
                return 0;
        }
    }

    return minT;
}
unsigned CompositeAnimation::numberOfActiveAnimations() const
{
    unsigned count = 0;
    
    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* anim = it->value.get();
            if (anim->running())
                ++count;
        }
    }

    if (!m_transitions.isEmpty()) {
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* anim = it->value.get();
            if (anim->running())
                ++count;
        }
    }
    
    return count;
}
void CompositeAnimation::resumeAnimations()
{
    if (!m_suspended)
        return;

    m_suspended = false;

    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* anim = it->value.get();
            if (anim && anim->playStatePlaying())
                anim->updatePlayState(AnimPlayStatePlaying);
        }
    }

    if (!m_transitions.isEmpty()) {
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* anim = it->value.get();
            if (anim && anim->hasStyle())
                anim->updatePlayState(AnimPlayStatePlaying);
        }
    }
}
Beispiel #5
0
/*!
 @brief returns the two keyframes for a given time. 
 @param keyframes - a map with all keyframes of type KeyframeAnimation
 @param time - the time fraction between 0 and 1. 
 @param k0, reference to the first keyframe
 @param k2, reference to the second keyframe
 @return the number of keyframes. 1 if the time is equal to a keyframe, otherwise 2.
 */
int getKeyframes( KeyframeAnimation& keyframes, const double time, Keyframe& k0, Keyframe& k1)
{
    int num_keyframes = 0;
    
    // get a keyframe iterator
    KeyframeAnimation::iterator k_itr = keyframes.lower_bound(time);
    
    Keyframe k0_temp, k1_temp;
    
    // Obtain the first keyframe
    k1 = (*k_itr).second; num_keyframes++;
    
    
    // Check whether we are not at the beginning of this map
    if(k_itr != keyframes.begin())
    {
        k_itr--;  // decrement
        k0 = (*k_itr).second; // obtain the second keyframe
        num_keyframes++;
    }
  
    // write the first keyframe into k0 if we only have one
    if(num_keyframes == 1)
    {
        k0 = k1;
    }
  
    return num_keyframes;
    
}
void CompositeAnimationPrivate::setAnimationStartTime(double t)
{
    // Set start time on all animations waiting for it
    AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
        KeyframeAnimation* anim = it->second.get();
        if (anim && anim->waitingForStartTime())
            anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
    }
}
Beispiel #7
0
void CompositeAnimation::setAnimationStartTime(double t)
{
    // set start time on all animations waiting for it
    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        if (anim && anim->waitingForStartTime())
            anim->updateStateMachine(AnimationBase::STATE_INPUT_START_TIME_SET, t);
    }
}
Beispiel #8
0
Animation *	GameObject::FrameInterpolateAnimation(int32 startFrame, int32 endFrame, float32 time, int32 track)
{
	KeyframeData * data = new KeyframeData();
	data->AddKeyframe(startFrame, 0.0f);
	data->AddKeyframe(endFrame, time);
	KeyframeAnimation * animation = new KeyframeAnimation(this, &localDrawState.frame, data, time);
	SafeRelease(data);
	animation->Start(track);
	return animation;
}
// "animating" means that something is running that requires the timer to keep firing
void CompositeAnimationPrivate::setAnimating(bool animating)
{
    CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
        ImplicitAnimation* transition = it->second.get();
        transition->setAnimating(animating);
    }

    AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
        KeyframeAnimation* anim = it->second.get();
        anim->setAnimating(animating);
    }
}
Beispiel #10
0
// "animating" means that something is running that requires the timer to keep firing
// (e.g. a transition)
void CompositeAnimation::setAnimating(bool inAnimating)
{
    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation*  transition = it->second;
        transition->setAnimating(inAnimating);
    }

    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        anim->setAnimating(inAnimating);
    }
}
Beispiel #11
0
bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const
{
    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        if (anim && anim->isAnimatingProperty(property, isRunningNow))
            return true;
    }
    
    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation* anim = it->second;
        if (anim && anim->isAnimatingProperty(property, isRunningNow))
            return true;
    }
    return false;
}
// "animating" means that something is running that requires the timer to keep firing
void CompositeAnimation::setAnimating(bool animating)
{
    if (!m_transitions.isEmpty()) {
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* transition = it->second.get();
            transition->setAnimating(animating);
        }
    }
    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* anim = it->second.get();
            anim->setAnimating(animating);
        }
    }
}
void CompositeAnimationPrivate::clearRenderer()
{
    // Clear the renderers from all running animations, in case we are in the middle of
    // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
    CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
        ImplicitAnimation* transition = it->second.get();
        transition->clearRenderer();
    }

    AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
        KeyframeAnimation* anim = it->second.get();
        anim->clearRenderer();
    }
    

}
Beispiel #14
0
bool CompositeAnimation::animating()
{
    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation*  transition = it->second;
        if (transition && transition->animating() && transition->running())
            return true;
    }
    
    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        if (anim && !anim->paused() && anim->animating() && anim->active())
            return true;
    }

    return false;
}
Beispiel #15
0
void CompositeAnimation::resumeAnimations()
{
    if (!m_suspended)
        return;
    
    m_suspended = false;
    
    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        if (anim && anim->playStatePlaying())
            anim->updatePlayState(true);
    }
    
    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation* anim = it->second;
        if (anim && anim->hasStyle())
            anim->updatePlayState(true);
    }
}
Beispiel #16
0
RenderStyle* CompositeAnimation::animate(RenderObject* renderer, const RenderStyle* currentStyle, RenderStyle* targetStyle)
{
    RenderStyle* resultStyle = 0;
    
    // We don't do any transitions if we don't have a currentStyle (on startup)
    updateTransitions(renderer, currentStyle, targetStyle);
    
    if (currentStyle) {
        // Now that we have transition objects ready, let them know about the new goal state.  We want them
        // to fill in a RenderStyle*& only if needed.
        CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
            ImplicitAnimation*  anim = it->second;
            if (anim) {
                anim->animate(this, renderer, currentStyle, targetStyle, resultStyle);
            }
        }
    }

    updateKeyframeAnimations(renderer, currentStyle, targetStyle);

    // Now that we have animation objects ready, let them know about the new goal state.  We want them
    // to fill in a RenderStyle*& only if needed.
    if (targetStyle->hasAnimations()) {
        for (size_t i = 0; i < targetStyle->animations()->size(); ++i) {
            const Animation* anim = (*targetStyle->animations())[i].get();

            if (anim->isValidAnimation()) {
                AtomicString name(anim->name());
                KeyframeAnimation* keyframeAnim = m_keyframeAnimations.get(name.impl());
                if (keyframeAnim)
                    keyframeAnim->animate(this, renderer, currentStyle, targetStyle, resultStyle);
            }
        }
    }
    
    cleanupFinishedAnimations(renderer);

    return resultStyle ? resultStyle : targetStyle;
}
bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const
{
    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* anim = it->second.get();
            if (anim && anim->isAnimatingProperty(property, isRunningNow))
                return true;
        }
    }

    if (!m_transitions.isEmpty()) {
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* anim = it->second.get();
            if (anim && anim->isAnimatingProperty(property, isRunningNow))
                return true;
        }
    }
    return false;
}
Beispiel #18
0
void CompositeAnimation::clearRenderer()
{
    if (!m_transitions.isEmpty()) {
        // Clear the renderers from all running animations, in case we are in the middle of
        // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
        CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
        for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
            ImplicitAnimation* transition = it->value.get();
            animationController()->animationWillBeRemoved(transition);
            transition->clear();
        }
    }
    if (!m_keyframeAnimations.isEmpty()) {
        m_keyframeAnimations.checkConsistency();
        AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
            KeyframeAnimation* anim = it->value.get();
            animationController()->animationWillBeRemoved(anim);
            anim->clear();
        }
    }
}
Beispiel #19
0
void CompositeAnimation::cleanupFinishedAnimations(RenderObject* renderer)
{
    if (suspended())
        return;
    
    // Make a list of transitions to be deleted
    Vector<int> finishedTransitions;
    CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();

    for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
        ImplicitAnimation* anim = it->second;
        if (!anim)
            continue;
        if (anim->postActive() && !anim->waitingForEndEvent())
            finishedTransitions.append(anim->animatingProperty());
    }
    
    // Delete them
    for (Vector<int>::iterator it = finishedTransitions.begin(); it != finishedTransitions.end(); ++it) {
        ImplicitAnimation* anim = m_transitions.get(*it);
        if (anim) {
            anim->reset(renderer);
            delete anim;
        }
        m_transitions.remove(*it);
    }

    // Make a list of animations to be deleted
    Vector<AtomicStringImpl*> finishedAnimations;
    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();

    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* anim = it->second;
        if (!anim)
            continue;
        if (anim->postActive() && !anim->waitingForEndEvent())
            finishedAnimations.append(anim->name().impl());
    }
    
    // delete them
    for (Vector<AtomicStringImpl*>::iterator it = finishedAnimations.begin(); it != finishedAnimations.end(); ++it) {
        KeyframeAnimation* kfanim = m_keyframeAnimations.get(*it);
        if (kfanim) {
            kfanim->reset(renderer);
            delete kfanim;
        }
        m_keyframeAnimations.remove(*it);
    }
}
void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
{
    // Nothing to do if we don't have any animations, and didn't have any before
    if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
        return;

    m_keyframeAnimations.checkConsistency();

    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    
    if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
        // The current and target animations are the same so we just need to toss any 
        // animation which is finished (postActive).
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
            if (it->second->postActive())
                it->second->setIndex(-1);
        }
    } else {
        // Mark all existing animations as no longer active.
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
            it->second->setIndex(-1);
            
        // Toss the animation order map.
        m_keyframeAnimationOrderMap.clear();
        
        // Now mark any still active animations as active and add any new animations.
        if (targetStyle->animations()) {
            int numAnims = targetStyle->animations()->size();
            for (int i = 0; i < numAnims; ++i) {
                const Animation* anim = targetStyle->animations()->animation(i);
                AtomicString animationName(anim->name());

                if (!anim->isValidAnimation())
                    continue;
                
                // See if there is a current animation for this name.
                RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
                
                if (keyframeAnim) {
                    // If this animation is postActive, skip it so it gets removed at the end of this function.
                    if (keyframeAnim->postActive())
                        continue;
                    
                    // This one is still active.

                    // Animations match, but play states may differ. Update if needed.
                    keyframeAnim->updatePlayState(anim->playState() == AnimPlayStatePlaying);
                                
                    // Set the saved animation to this new one, just in case the play state has changed.
                    keyframeAnim->setAnimation(anim);
                    keyframeAnim->setIndex(i);
                } else if ((anim->duration() || anim->delay()) && anim->iterationCount()) {
                    keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, this, targetStyle);
                    m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
                }
                
                // Add this to the animation order map.
                if (keyframeAnim)
                    m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
            }
        }
    }
    
    // Make a list of animations to be removed.
    Vector<AtomicStringImpl*> animsToBeRemoved;
    kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* keyframeAnim = it->second.get();
        if (keyframeAnim->index() < 0)
            animsToBeRemoved.append(keyframeAnim->name().impl());
    }
    
    // Now remove the animations from the list.
    for (size_t j = 0; j < animsToBeRemoved.size(); ++j)
        m_keyframeAnimations.remove(animsToBeRemoved[j]);
}
Beispiel #21
0
void CompositeAnimation::updateKeyframeAnimations(RenderElement* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
{
    // Nothing to do if we don't have any animations, and didn't have any before
    if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
        return;

    m_keyframeAnimations.checkConsistency();

    AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
    
    if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
        // The current and target animations are the same so we just need to toss any 
        // animation which is finished (postActive).
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
            if (it->value->postActive())
                it->value->setIndex(-1);
        }
    } else {
        // Mark all existing animations as no longer active.
        for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
            it->value->setIndex(-1);
            
        // Toss the animation order map.
        m_keyframeAnimationOrderMap.clear();

        DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
        
        // Now mark any still active animations as active and add any new animations.
        if (targetStyle->animations()) {
            int numAnims = targetStyle->animations()->size();
            for (int i = 0; i < numAnims; ++i) {
                const Animation& animation = targetStyle->animations()->animation(i);
                AtomicString animationName(animation.name());

                if (!animation.isValidAnimation())
                    continue;
                
                // See if there is a current animation for this name.
                RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
                
                if (keyframeAnim) {
                    // If this animation is postActive, skip it so it gets removed at the end of this function.
                    if (keyframeAnim->postActive())
                        continue;
                    
                    // This one is still active.

                    // Animations match, but play states may differ. Update if needed.
                    keyframeAnim->updatePlayState(animation.playState());
                                
                    // Set the saved animation to this new one, just in case the play state has changed.
                    keyframeAnim->setAnimation(animation);
                    keyframeAnim->setIndex(i);
                } else if ((animation.duration() || animation.delay()) && animation.iterationCount() && animationName != none) {
                    keyframeAnim = KeyframeAnimation::create(animation, renderer, i, this, targetStyle);
                    LOG(Animations, "Creating KeyframeAnimation %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), animation.name().utf8().data(), animation.duration(), animation.delay(), animation.iterationCount());
                    if (m_suspended) {
                        keyframeAnim->updatePlayState(AnimPlayStatePaused);
                        LOG(Animations, "  (created in suspended/paused state)");
                    }
#if !LOG_DISABLED
                    for (auto it = keyframeAnim->keyframes().beginProperties(), end = keyframeAnim->keyframes().endProperties(); it != end; ++it)
                        LOG(Animations, "  property %s", getPropertyName(*it));
#endif
                    m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
                }
                
                // Add this to the animation order map.
                if (keyframeAnim)
                    m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
            }
        }
    }
    
    // Make a list of animations to be removed.
    Vector<AtomicStringImpl*> animsToBeRemoved;
    kfend = m_keyframeAnimations.end();
    for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
        KeyframeAnimation* keyframeAnim = it->value.get();
        if (keyframeAnim->index() < 0) {
            animsToBeRemoved.append(keyframeAnim->name().impl());
            animationController()->animationWillBeRemoved(keyframeAnim);
            keyframeAnim->clear();
            LOG(Animations, "Removing KeyframeAnimation %p", keyframeAnim);
        }
    }
    
    // Now remove the animations from the list.
    for (size_t j = 0; j < animsToBeRemoved.size(); ++j)
        m_keyframeAnimations.remove(animsToBeRemoved[j]);
}
Beispiel #22
0
void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, const RenderStyle* currentStyle, RenderStyle* targetStyle)
{
    // Nothing to do if we don't have any animations, and didn't have any before
    if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
        return;
    
    // Nothing to do if the current and target animations are the same
    if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations()))
        return;
        
    int numAnims = 0;
    bool animsChanged = false;
    
    // see if the lists match
    if (targetStyle->animations()) {
        for (size_t i = 0; i < targetStyle->animations()->size(); ++i) {
            const Animation* anim = (*targetStyle->animations())[i].get();
            
            if (!anim->isValidAnimation())
                animsChanged = true;
            else {
                AtomicString name(anim->name());
                KeyframeAnimation* kfAnim = m_keyframeAnimations.get(name.impl());
                if (!kfAnim || !kfAnim->animationsMatch(anim))
                    animsChanged = true;
                else
                    if (anim) {
                        // animations match, but play states may differ. update if needed
                        kfAnim->updatePlayState(anim->playState() == AnimPlayStatePlaying);
                        
                        // set the saved animation to this new one, just in case the play state has changed
                        kfAnim->setAnimation(anim);
                    }
            }
            ++numAnims;
        }
    }
    
    if (!animsChanged && m_keyframeAnimations.size() != numAnims)
        animsChanged = true;

    if (!animsChanged)
        return;

    // animations have changed, update the list
    resetAnimations(renderer);

    if (!targetStyle->animations())
        return;

    // add all the new animations
    int index = 0;
    for (size_t i = 0; i < targetStyle->animations()->size(); ++i) {
        const Animation* anim = (*targetStyle->animations())[i].get();

        if (!anim->isValidAnimation())
            continue;
            
        // don't bother adding the animation if it has no keyframes or won't animate
        if ((anim->duration() || anim->delay()) && anim->iterationCount() &&
                                            anim->keyframeList().get() && !anim->keyframeList()->isEmpty()) {
            KeyframeAnimation* kfanim = new KeyframeAnimation(const_cast<Animation*>(anim), renderer, index++, this);
            m_keyframeAnimations.set(kfanim->name().impl(), kfanim);
        }
    }
}