static inline float applyTimingFunction(const TimingFunction* timingFunction, float progress, double duration) { if (!timingFunction) return progress; if (timingFunction->isCubicBezierTimingFunction()) { const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction); return solveCubicBezierFunction(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2(), progress, duration); } if (timingFunction->isStepsTimingFunction()) { const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(timingFunction); return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), double(progress)); } return progress; }
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; }