double KeyframeAnimation::timeToNextService() { double t = AnimationBase::timeToNextService(); if (t != 0 || preActive()) return t; // A return value of 0 means we need service. But if we only have accelerated animations we // only need service at the end of the transition HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties(); bool acceleratedPropertiesOnly = true; for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(*it) || !isAccelerated()) { acceleratedPropertiesOnly = false; break; } } if (acceleratedPropertiesOnly) { bool isLooping; getTimeToNextEvent(t, isLooping); } return t; }
double KeyframeAnimation::timeToNextService() { double t = AnimationBase::timeToNextService(); #if USE(ACCELERATED_COMPOSITING) if (t != 0 || preActive()) return t; // A return value of 0 means we need service. But if we only have accelerated animations we // only need service at the end of the transition HashSet<int>::const_iterator endProperties = m_keyframes.endProperties(); bool acceleratedPropertiesOnly = true; for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { if (!animationOfPropertyIsAccelerated(*it) || isFallbackAnimating()) { acceleratedPropertiesOnly = false; break; } } if (acceleratedPropertiesOnly) { bool isLooping; getTimeToNextEvent(t, isLooping); } #endif return t; }
double AnimationBase::progress(double scale, double offset, const TimingFunction* timingFunction) const { if (preActive()) return 0; double dur = m_animation->duration(); if (m_animation->iterationCount() > 0) dur *= m_animation->iterationCount(); if (postActive() || !m_animation->duration()) return 1.0; double elapsedTime = getElapsedTime(); if (m_animation->iterationCount() > 0 && elapsedTime >= dur) { const int integralIterationCount = static_cast<int>(m_animation->iterationCount()); const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount; return (integralIterationCount % 2 || iterationCountHasFractional) ? 1.0 : 0.0; } const double fractionalTime = this->fractionalTime(scale, elapsedTime, offset); if (!timingFunction) timingFunction = m_animation->timingFunction(); return timingFunction->evaluate(fractionalTime, accuracyForDuration(m_animation->duration())); }
double ImplicitAnimation::timeToNextService() { double t = AnimationBase::timeToNextService(); if (t != 0 || preActive()) return t; // A return value of 0 means we need service. But if this is an accelerated animation we // only need service at the end of the transition. if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(m_animatingProperty) && isAccelerated()) { bool isLooping; getTimeToNextEvent(t, isLooping); } return t; }
double AnimationBase::progress(double scale, double offset, const TimingFunction* timingFunction) const { if (preActive()) return 0; if (postActive()) return 1; double elapsedTime = getElapsedTime(); double duration = m_animation->duration(); if (m_animation->iterationCount() > 0) duration *= m_animation->iterationCount(); if (fillingForwards()) elapsedTime = duration; double fractionalTime = this->fractionalTime(scale, elapsedTime, offset); if (m_animation->iterationCount() > 0 && elapsedTime >= duration) { if (WTF::isIntegral(fractionalTime)) return fractionalTime; } if (!timingFunction) timingFunction = m_animation->timingFunction().get(); switch (timingFunction->type()) { case TimingFunction::CubicBezierFunction: { const CubicBezierTimingFunction* function = static_cast<const CubicBezierTimingFunction*>(timingFunction); return solveCubicBezierFunction(function->x1(), function->y1(), function->x2(), function->y2(), fractionalTime, m_animation->duration()); } case TimingFunction::StepsFunction: { const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction); return solveStepsFunction(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart(), fractionalTime); } case TimingFunction::LinearFunction: return fractionalTime; } ASSERT_NOT_REACHED(); return 0; }
double AnimationBase::progress(double scale, double offset, const TimingFunction* tf) const { if (preActive()) return 0; double elapsedTime = getElapsedTime(); double dur = m_animation->duration(); if (m_animation->iterationCount() > 0) dur *= m_animation->iterationCount(); if (postActive() || !m_animation->duration()) return 1.0; if (m_animation->iterationCount() > 0 && elapsedTime >= dur) { const int integralIterationCount = static_cast<int>(m_animation->iterationCount()); const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount; return (integralIterationCount % 2 || iterationCountHasFractional) ? 1.0 : 0.0; } const double fractionalTime = this->fractionalTime(scale, elapsedTime, offset); if (!tf) tf = m_animation->timingFunction().get(); switch (tf->type()) { case TimingFunction::CubicBezierFunction: { const CubicBezierTimingFunction* function = static_cast<const CubicBezierTimingFunction*>(tf); return solveCubicBezierFunction(function->x1(), function->y1(), function->x2(), function->y2(), fractionalTime, m_animation->duration()); } case TimingFunction::StepsFunction: { const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(tf); return solveStepsFunction(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart(), fractionalTime); } case TimingFunction::LinearFunction: return fractionalTime; } ASSERT_NOT_REACHED(); return 0; }
double KeyframeAnimation::timeToNextService() { double t = AnimationBase::timeToNextService(); if (t != 0 || preActive()) return t; // A return value of 0 means we need service. But if we only have accelerated animations we // only need service at the end of the transition bool acceleratedPropertiesOnly = true; for (auto propertyID : m_keyframes.properties()) { if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(propertyID) || !isAccelerated()) { acceleratedPropertiesOnly = false; break; } } if (acceleratedPropertiesOnly) { bool isLooping; getTimeToNextEvent(t, isLooping); } return t; }