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 } } }
void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) { // If we're in the delay phase and we're not backwards filling, tell the caller // to use the current style. if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards()) return; if (!m_keyframes.size()) return; if (!animatedStyle) animatedStyle = RenderStyle::clone(m_object->style()); HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { int property = *it; // Get the from/to styles and progress between const RenderStyle* fromStyle = 0; const RenderStyle* toStyle = 0; double progress; fetchIntervalEndpointsForProperty(property, fromStyle, toStyle, progress); blendProperties(this, property, animatedStyle.get(), fromStyle, toStyle, progress); } }
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 = 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 ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) { if (!animatedStyle) animatedStyle = RenderStyle::clone(m_toStyle.get()); blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); }
void ImplicitAnimation::blendPropertyValueInStyle(int prop, RenderStyle* currentStyle) { // We should never add a transition with a 0 duration and delay. But if we ever did // it would have a null toStyle. So just in case, let's check that here. (See // <https://bugs.webkit.org/show_bug.cgi?id=24787> if (!m_toStyle) return; blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); }
void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) { // 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 if (!fromStyle || !toStyle) return; if (!animatedStyle) animatedStyle = RenderStyle::clone(m_object->style()); HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress); }
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(); }
void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle) { // If we're in the delay phase and we're not backwards filling, tell the caller // to use the current style. if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards()) return; // 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 if (!fromStyle || !toStyle) return; if (!animatedStyle) animatedStyle = RenderStyle::clone(m_object->style()); HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress); }
void ImplicitAnimation::blendPropertyValueInStyle(int prop, RenderStyle* currentStyle) { blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)); }
void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* renderer, const RenderStyle* currentStyle, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle) { // 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 - 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. if (waitingToStart() && m_animation->delay() > 0) return; // FIXME: we need to be more efficient about determining which keyframes we are animating between. // We should cache the last pair or something. // Find the first key double elapsedTime = (m_startTime > 0) ? ((!paused() ? currentTime() : m_pauseTime) - m_startTime) : 0; if (elapsedTime < 0) elapsedTime = 0; double t = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1; int i = static_cast<int>(t); t -= i; if (m_animation->direction() && (i & 1)) t = 1 - t; const RenderStyle* fromStyle = 0; const RenderStyle* toStyle = 0; double scale = 1; double offset = 0; Vector<KeyframeValue>::const_iterator endKeyframes = m_keyframes.endKeyframes(); for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != endKeyframes; ++it) { if (t < it->key()) { // The first key should always be 0, so we should never succeed on the first key if (!fromStyle) break; scale = 1.0 / (it->key() - offset); toStyle = it->style(); break; } offset = it->key(); fromStyle = it->style(); } // 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); const TimingFunction* timingFunction = 0; if (fromStyle->animations() && fromStyle->animations()->size() > 0) timingFunction = &(fromStyle->animations()->animation(0)->timingFunction()); double prog = progress(scale, offset, timingFunction); HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { if (blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, prog)) setAnimating(); } }