animation.cpp
cmath
utility
ftxui/component/animation.hpp
ftxui/component/animation.hpp
src/ftxui/component/animation.cpp
chrono
cmath
functional
utility
ftxui
ftxui::animation
ftxui::animation::easing

    #include<cmath>//forsin,pow,sqrt,cos
    #include<utility>//formove

    #include"ftxui/component/animation.hpp"

    //NOLINTBEGIN(*-magic-numbers)
    namespaceftxui::animation{

    namespaceeasing{

    namespace{
    constexprfloatkPi=3.14159265358979323846f;
    constexprfloatkPi2=kPi/2.f;
    }//namespace

    //Easingfunctionhavebeentakenoutof:
    //https://github.com/warrenm/AHEasing/blob/master/AHEasing/easing.c
    //
    //Correspondinglicense:
    //Copyright(c)2011,AuerhausDevelopment,LLC
    //
    //Thisprogramisfreesoftware.Itcomeswithoutanywarranty,to
    //theextentpermittedbyapplicablelaw.Youcanredistributeit
    //and/ormodifyitunderthetermsoftheDoWhatTheFuckYouWant
    //ToPublicLicense,Version2,aspublishedbySamHocevar.See
    //http://sam.zoy.org/wtfpl/COPYINGformoredetails.

    ///@briefModeledaftertheliney=x
    floatLinear(floatp){
    returnp;
    }

    ///@briefModeledaftertheparabolay=x^2
    floatQuadraticIn(floatp){
    returnp*p;
    }

    //@briefModeledaftertheparabolay=-x^2+2x
    floatQuadraticOut(floatp){
    return-(p*(p-2.f));
    }

    //@briefModeledafterthepiecewisequadratic
    //y=(1/2)((2x)^2);[0,0.5)
    //y=-(1/2)((2x-1)*(2x-3)-1);[0.5,1]
    floatQuadraticInOut(floatp){
    returnp<0.5f?2.f*p*p:(-2.f*p*p)+(4.f*p)-1.f;
    }

    //@briefModeledafterthecubicy=x^3
    floatCubicIn(floatp){
    returnp*p*p;
    }

    //@briefModeledafterthecubicy=(x-1)^3+1
    floatCubicOut(floatp){
    constfloatf=(p-1.f);
    returnf*f*f+1.f;
    }

    //@briefModeledafterthepiecewisecubic
    //y=(1/2)((2x)^3);[0,0.5)
    //y=(1/2)((2x-2)^3+2);[0.5,1]
    floatCubicInOut(floatp){
    if(p<0.5f){
    return4.f*p*p*p;
    }
    constfloatf=((2.f*p)-2.f);
    return0.5f*f*f*f+1.f;
    }

    //@briefModeledafterthequarticx^4
    floatQuarticIn(floatp){
    returnp*p*p*p;
    }

    //@briefModeledafterthequarticy=1-(x-1)^4
    floatQuarticOut(floatp){
    constfloatf=(p-1.f);
    returnf*f*f*(1.f-p)+1.f;
    }

    //@briefModeledafterthepiecewisequartic
    //y=(1/2)((2x)^4);[0,0.5)
    //y=-(1/2)((2x-2)^4-2);[0.5,1]
    floatQuarticInOut(floatp){
    if(p<0.5f){
    return8.f*p*p*p*p;
    }
    constfloatf=(p-1.f);
    return-8.f*f*f*f*f+1.f;
    }

    //@briefModeledafterthequinticy=x^5
    floatQuinticIn(floatp){
    returnp*p*p*p*p;
    }

    //@briefModeledafterthequinticy=(x-1)^5+1
    floatQuinticOut(floatp){
    constfloatf=(p-1.f);
    returnf*f*f*f*f+1.f;
    }

    //@briefModeledafterthepiecewisequintic
    //y=(1/2)((2x)^5);[0,0.5)
    //y=(1/2)((2x-2)^5+2);[0.5,1]
    floatQuinticInOut(floatp){
    if(p<0.5f){
    return16.f*p*p*p*p*p;
    }
    constfloatf=((2.f*p)-2.f);
    return0.5f*f*f*f*f*f+1.f;
    }

    //@briefModeledafterquarter-cycleofsinewave
    floatSineIn(floatp){
    returnstd::sin((p-1.f)*kPi2)+1.f;
    }

    //@briefModeledafterquarter-cycleofsinewave(differentphase)
    floatSineOut(floatp){
    returnstd::sin(p*kPi2);
    }

    //@briefModeledafterhalfsinewave
    floatSineInOut(floatp){
    return0.5f*(1.f-std::cos(p*kPi));
    }

    //@briefModeledaftershiftedquadrantIVofunitcircle
    floatCircularIn(floatp){
    return1.f-std::sqrt(1.f-(p*p));
    }

    //@briefModeledaftershiftedquadrantIIofunitcircle
    floatCircularOut(floatp){
    returnstd::sqrt((2.f-p)*p);
    }

    //@briefModeledafterthepiecewisecircularfunction
    //y=(1/2)(1-sqrt(1-4x^2));[0,0.5)
    //y=(1/2)(sqrt(-(2x-3)*(2x-1))+1);[0.5,1]
    floatCircularInOut(floatp){
    if(p<0.5f){
    return0.5f*(1.f-std::sqrt(1.f-4.f*(p*p)));
    }
    return0.5f*(std::sqrt(-((2.f*p)-3.f)*((2.f*p)-1.f))+1.f);
    }

    //@briefModeledaftertheexponentialfunctiony=2^(10(x-1))
    floatExponentialIn(floatp){
    return(p==0.f)?p:std::pow(2.f,10.f*(p-1.f));
    }

    //@briefModeledaftertheexponentialfunctiony=-2^(-10x)+1
    floatExponentialOut(floatp){
    return(p==1.f)?p:1.f-std::pow(2.f,-10.f*p);
    }

    //@briefModeledafterthepiecewiseexponential
    //y=(1/2)2^(10(2x-1));[0,0.5)
    //y=-(1/2)*2^(-10(2x-1)))+1;[0.5,1]
    floatExponentialInOut(floatp){
    if(p==0.f||p==1.f){
    returnp;
    }

    if(p<0.5f){
    return0.5f*std::pow(2.f,(20.f*p)-10.f);
    }
    return-0.5f*std::pow(2.f,(-20.f*p)+10.f)+1.f;
    }

    //@briefModeledafterthedampedsinewavey=sin(13pi/2*x)*pow(2,10*(x-
    //1))
    floatElasticIn(floatp){
    returnstd::sin(13.f*kPi2*p)*std::pow(2.f,10.f*(p-1.f));
    }

    //@briefModeledafterthedampedsinewavey=sin(-13pi/2*(x+1))*pow(2,
    //-10x)+
    //1
    floatElasticOut(floatp){
    returnstd::sin(-13.f*kPi2*(p+1.f))*std::pow(2.f,-10.f*p)+1.f;
    }

    //@briefModeledafterthepiecewiseexponentially-dampedsinewave:
    //y=(1/2)*sin(13pi/2*(2*x))*pow(2,10*((2*x)-1));[0,0.5)
    //y=(1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1))+2);[0.5,1]
    floatElasticInOut(floatp){
    if(p<0.5f){
    return0.5f*std::sin(13.f*kPi2*(2.f*p))*
    std::pow(2.f,10.f*((2.f*p)-1.f));
    }
    return0.5f*(std::sin(-13.f*kPi2*((2.f*p-1.f)+1.f))*
    std::pow(2.f,-10.f*(2.f*p-1.f))+
    2.f);
    }

    //@briefModeledaftertheovershootingcubicy=x^3-x*sin(x*pi)
    floatBackIn(floatp){
    returnp*p*p-p*std::sin(p*kPi);
    }

    //@briefModeledafterovershootingcubicy=1-((1-x)^3-(1-x)*sin((1-x)*pi))
    floatBackOut(floatp){
    constfloatf=(1.f-p);
    return1.f-(f*f*f-f*std::sin(f*kPi));
    }

    //@briefModeledafterthepiecewiseovershootingcubicfunction:
    //y=(1/2)*((2x)^3-(2x)*sin(2*x*pi));[0,0.5)
    //y=(1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1);[0.5,1]
    floatBackInOut(floatp){
    if(p<0.5f){
    constfloatf=2.f*p;
    return0.5f*(f*f*f-f*std::sin(f*kPi));
    }
    constfloatf=(1.f-(2.f*p-1.f));
    return0.5f*(1.f-(f*f*f-f*std::sin(f*kPi)))+0.5f;
    }

    floatBounceIn(floatp){
    return1.f-BounceOut(1.f-p);
    }

    floatBounceOut(floatp){
    if(p<4.f/11.f){
    return(121.f*p*p)/16.f;
    }

    if(p<8.f/11.f){
    return(363.f/40.f*p*p)-(99.f/10.f*p)+17.f/5.f;
    }

    if(p<9.f/10.f){
    return(4356.f/361.f*p*p)-(35442.f/1805.f*p)+16061.f/1805.f;
    }

    return(54.f/5.f*p*p)-(513/25.f*p)+268/25.f;
    }

    floatBounceInOut(floatp){
    if(p<0.5f){
    return0.5f*BounceIn(p*2.f);
    }
    return0.5f*BounceOut(p*2.f-1.f)+0.5f;
    }

    }//namespaceeasing

    Animator::Animator(float*from,
    floatto,
    Durationduration,
    easing::Functioneasing_function,
    Durationdelay)
    :value_(from),
    from_(*from),
    to_(to),
    duration_(duration),
    easing_function_(std::move(easing_function)),
    current_(-delay){
    RequestAnimationFrame();
    }

    voidAnimator::OnAnimation(Params&params){
    current_+=params.duration();

    if(current_>=duration_){
    *value_=to_;
    return;
    }

    if(current_<=Duration()){
    *value_=from_;
    }else{
    *value_=from_+(to_-from_)*easing_function_(current_/duration_);
    }

    RequestAnimationFrame();
    }

    }//namespaceftxui::animation

    //NOLINTEND(*-magic-numbers)