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 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 } } }
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; }
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()); 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); CSSPropertyAnimation::blendProperties(this, propertyID, animatedStyle.get(), fromStyle, toStyle, progress); } }
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 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(); } }