Exemplo n.º 1
0
void AnimationBase::fireAnimationEventsIfNeeded()
{
    if (!m_compAnim)
        return;

    // If we are waiting for the delay time to expire and it has, go to the next state
    if (m_animState != AnimationStateStartWaitTimer && m_animState != AnimationStateLooping && m_animState != AnimationStateEnding)
        return;

    // We have to make sure to keep a ref to the this pointer, because it could get destroyed
    // during an animation callback that might get called. Since the owner is a CompositeAnimation
    // and it ref counts this object, we will keep a ref to that instead. That way the AnimationBase
    // can still access the resources of its CompositeAnimation as needed.
    Ref<AnimationBase> protect(*this);
    Ref<CompositeAnimation> protectCompositeAnimation(*m_compAnim);
    
    // Check for start timeout
    if (m_animState == AnimationStateStartWaitTimer) {
        if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
            updateStateMachine(AnimationStateInputStartTimerFired, 0);
        return;
    }
    
    double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
    // FIXME: we need to ensure that elapsedDuration is never < 0. If it is, this suggests that
    // we had a recalcStyle() outside of beginAnimationUpdate()/endAnimationUpdate().
    // Also check in getTimeToNextEvent().
    elapsedDuration = max(elapsedDuration, 0.0);
    
    // Check for end timeout
    if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
        // We may still be in AnimationStateLooping if we've managed to skip a
        // whole iteration, in which case we should jump to the end state.
        LOG(Animations, "%p AnimationState %s -> Ending", this, nameForState(m_animState));
        m_animState = AnimationStateEnding;

        // Fire an end event
        updateStateMachine(AnimationStateInputEndTimerFired, m_totalDuration);
    } else {
        // Check for iteration timeout
        if (m_nextIterationDuration < 0) {
            // Hasn't been set yet, set it
            double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
            m_nextIterationDuration = elapsedDuration + durationLeft;
        }
        
        if (elapsedDuration >= m_nextIterationDuration) {
            // Set to the next iteration
            double previous = m_nextIterationDuration;
            double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
            m_nextIterationDuration = elapsedDuration + durationLeft;
            
            // Send the event
            updateStateMachine(AnimationStateInputLoopTimerFired, previous);
        }
    }
}
void AnimationBase::fireAnimationEventsIfNeeded()
{
    if (!m_compositeAnimation)
        return;

    // If we are waiting for the delay time to expire and it has, go to the next state
    if (m_animationState != AnimationState::StartWaitTimer && m_animationState != AnimationState::Looping && m_animationState != AnimationState::Ending)
        return;

    // We have to make sure to keep a ref to the this pointer, because it could get destroyed
    // during an animation callback that might get called. Since the owner is a CompositeAnimation
    // and it ref counts this object, we will keep a ref to that instead. That way the AnimationBase
    // can still access the resources of its CompositeAnimation as needed.
    Ref<AnimationBase> protect(*this);
    Ref<CompositeAnimation> protectCompositeAnimation(*m_compositeAnimation);
    
    // Check for start timeout
    if (m_animationState == AnimationState::StartWaitTimer) {
#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
        if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger()) {
            if (m_object) {
                float offset = m_compositeAnimation->animationController().scrollPosition();
                ScrollAnimationTrigger& scrollTrigger = downcast<ScrollAnimationTrigger>(*m_animation->trigger().get());
                if (offset > scrollTrigger.startValue().value())
                    updateStateMachine(AnimationStateInput::StartTimerFired, 0);
            }

            return;
        }
#endif
        if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
            updateStateMachine(AnimationStateInput::StartTimerFired, 0);
        return;
    }

    double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
    // If we are a triggered animation that depends on scroll, our elapsed
    // time is determined by the scroll position.
    if (m_animation->trigger() && m_animation->trigger()->isScrollAnimationTrigger())
        elapsedDuration = getElapsedTime();
#endif

    // FIXME: we need to ensure that elapsedDuration is never < 0. If it is, this suggests that
    // we had a recalcStyle() outside of beginAnimationUpdate()/endAnimationUpdate().
    // Also check in getTimeToNextEvent().
    elapsedDuration = std::max(elapsedDuration, 0.0);
    
    // Check for end timeout
    if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
        // We may still be in AnimationState::Looping if we've managed to skip a
        // whole iteration, in which case we should jump to the end state.
        LOG(Animations, "%p AnimationState %s -> Ending", this, nameForState(m_animationState));
        m_animationState = AnimationState::Ending;

        // Fire an end event
        updateStateMachine(AnimationStateInput::EndTimerFired, m_totalDuration);
    } else {
        // Check for iteration timeout
        if (m_nextIterationDuration < 0) {
            // Hasn't been set yet, set it
            double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
            m_nextIterationDuration = elapsedDuration + durationLeft;
        }
        
        if (elapsedDuration >= m_nextIterationDuration) {
            // Set to the next iteration
            double previous = m_nextIterationDuration;
            double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
            m_nextIterationDuration = elapsedDuration + durationLeft;
            
            // Send the event
            updateStateMachine(AnimationStateInput::LoopTimerFired, previous);
        }
    }
}