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;
}
Example #3
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;
}