void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { // If we get this far and the animation is done, it means we are cleaning up a just finished animation. // So just return. Everything is already all cleaned up. if (postActive()) return; // Reset to start the transition if we are new if (isNew()) reset(targetStyle); // Run a cycle of animation. // We know we will need a new render style, so make one if needed if (!animatedStyle) animatedStyle = RenderStyle::clone(targetStyle); bool needsAnim = CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); // FIXME: we also need to detect cases where we have to software animate for other reasons, // such as a child using inheriting the transform. https://bugs.webkit.org/show_bug.cgi?id=23902 if (needsAnim) setAnimating(); else { #if USE(ACCELERATED_COMPOSITING) // If we are running an accelerated animation, set a flag in the style which causes the style // to compare as different to any other style. This ensures that changes to the property // that is animating are correctly detected during the animation (e.g. when a transition // gets interrupted). animatedStyle->setIsRunningAcceleratedAnimation(); #endif } // Fire the start timeout if needed fireAnimationEventsIfNeeded(); }
void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { // Fire the start timeout if needed fireAnimationEventsIfNeeded(); // If we have not yet started, we will not have a valid start time, so just start the animation if needed. if (isNew() && m_animation->playState() == AnimPlayStatePlaying) updateStateMachine(AnimationStateInputStartAnimation, -1); // If we get this far and the animation is done, it means we are cleaning up a just finished animation. // If so, we need to send back the targetStyle. if (postActive()) { if (!animatedStyle) animatedStyle = const_cast<RenderStyle*>(targetStyle); return; } // If we are waiting for the start timer, we don't want to change the style yet. // Special case 1 - if the delay time is 0, then we do want to set the first frame of the // animation right away. This avoids a flash when the animation starts. // Special case 2 - if there is a backwards fill mode, then we want to continue // through to the style blend so that we get the fromStyle. if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards()) return; // FIXME: we need to be more efficient about determining which keyframes we are animating between. // We should cache the last pair or something. // Get the from/to styles and progress between const RenderStyle* fromStyle = 0; const RenderStyle* toStyle = 0; double progress; getKeyframeAnimationInterval(fromStyle, toStyle, progress); // If either style is 0 we have an invalid case, just stop the animation. if (!fromStyle || !toStyle) { updateStateMachine(AnimationStateInputEndAnimation, -1); return; } // Run a cycle of animation. // We know we will need a new render style, so make one if needed. if (!animatedStyle) animatedStyle = RenderStyle::clone(targetStyle); HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { bool needsAnim = blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress); if (needsAnim) setAnimating(); else { #if USE(ACCELERATED_COMPOSITING) // If we are running an accelerated animation, set a flag in the style // to indicate it. This can be used to make sure we get an updated // style for hit testing, etc. animatedStyle->setIsRunningAcceleratedAnimation(); #endif } } }
double AnimationBase::timeToNextService() { // 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. if (paused() || isNew() || m_animationState == AnimationState::FillingForwards) return -1; if (m_animationState == AnimationState::StartWaitTimer) { #if ENABLE(CSS_ANIMATIONS_LEVEL_2) if (m_animation->trigger()->isScrollAnimationTrigger()) { if (m_object) { float currentScrollOffset = m_object->view().frameView().scrollOffsetForFixedPosition().height().toFloat(); ScrollAnimationTrigger& scrollTrigger = downcast<ScrollAnimationTrigger>(*m_animation->trigger().get()); if (currentScrollOffset >= scrollTrigger.startValue().value() && (!scrollTrigger.hasEndValue() || currentScrollOffset <= scrollTrigger.endValue().value())) return 0; } return -1; } #endif double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime); return std::max(timeFromNow, 0.0); } fireAnimationEventsIfNeeded(); // In all other cases, we need service right away. return 0; }
bool KeyframeAnimation::animate(CompositeAnimation* compositeAnimation, RenderElement*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { // Fire the start timeout if needed fireAnimationEventsIfNeeded(); // If we have not yet started, we will not have a valid start time, so just start the animation if needed. if (isNew() && m_animation->playState() == AnimPlayStatePlaying && !compositeAnimation->isSuspended()) updateStateMachine(AnimationStateInput::StartAnimation, -1); // If we get this far and the animation is done, it means we are cleaning up a just finished animation. // If so, we need to send back the targetStyle. if (postActive()) { if (!animatedStyle) animatedStyle = const_cast<RenderStyle*>(targetStyle); return false; } // If we are waiting for the start timer, we don't want to change the style yet. // Special case 1 - if the delay time is 0, then we do want to set the first frame of the // animation right away. This avoids a flash when the animation starts. // Special case 2 - if there is a backwards fill mode, then we want to continue // through to the style blend so that we get the fromStyle. if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards()) return false; // If we have no keyframes, don't animate. if (!m_keyframes.size()) { updateStateMachine(AnimationStateInput::EndAnimation, -1); return false; } AnimationState oldState = state(); // Run a cycle of animation. // We know we will need a new render style, so make one if needed. if (!animatedStyle) animatedStyle = RenderStyle::clone(targetStyle); // FIXME: we need to be more efficient about determining which keyframes we are animating between. // We should cache the last pair or something. for (auto propertyID : m_keyframes.properties()) { // Get the from/to styles and progress between const RenderStyle* fromStyle = nullptr; const RenderStyle* toStyle = nullptr; double progress = 0; fetchIntervalEndpointsForProperty(propertyID, fromStyle, toStyle, progress); bool needsAnim = CSSPropertyAnimation::blendProperties(this, propertyID, animatedStyle.get(), fromStyle, toStyle, progress); if (!needsAnim) // If we are running an accelerated animation, set a flag in the style // to indicate it. This can be used to make sure we get an updated // style for hit testing, etc. // FIXME: still need this? animatedStyle->setIsRunningAcceleratedAnimation(); } return state() != oldState; }
double AnimationBase::timeToNextService() { // 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. if (paused() || isNew() || m_animState == AnimationStateFillingForwards) return -1; if (m_animState == AnimationStateStartWaitTimer) { double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime); return max(timeFromNow, 0.0); } fireAnimationEventsIfNeeded(); // In all other cases, we need service right away. return 0; }
void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { // If we get this far and the animation is done, it means we are cleaning up a just finished animation. // So just return. Everything is already all cleaned up. if (postActive()) return; // Reset to start the transition if we are new if (isNew()) reset(targetStyle); // Run a cycle of animation. // We know we will need a new render style, so make one if needed if (!animatedStyle) animatedStyle = RenderStyle::clone(targetStyle); if (blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0))) setAnimating(); // Fire the start timeout if needed fireAnimationEventsIfNeeded(); }