Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing EaseIn, EaseOut functions in Delphi

I am trying to implement fluid movement of tabs in TChromeTabs. I can see the easing formulas here, but I am no mathematician and have no idea how to translate this into code. My attempts so far have got me nowhere.

Are there Delphi implementations of the Easing functions available?

like image 318
norgepaul Avatar asked Dec 19 '12 12:12

norgepaul


1 Answers

I found several useful examples online and used the algorithms to write my own Delphi Easing functions. Here they are:

...

type
  TChromeTabsEaseType = (
    ttlinearTween,
    tteaseInQuad,
    tteaseOutQuad,
    tteaseInOutQuad,
    tteaseInCubic,
    tteaseOutCubic,
    tteaseInOutCubic,
    tteaseInQuart,
    tteaseOutQuart,
    tteaseInOutQuart,
    tteaseInQuint,
    tteaseOutQuint,
    tteaseInOutQuint,
    tteaseInSine,
    tteaseOutSine,
    tteaseInOutSine,
    tteaseInExpo,
    tteaseOutExpo,
    tteaseInOutExpo,
    tteaseInCirc,
    tteaseOutCirc,
    tteaseInOutCirc
  );

    function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: Real; EaseType: TChromeTabsEaseType): Real; overload;
    function CalculateEase(StartPos, EndPos, PositionPct: Real; EaseType: TChromeTabsEaseType): Real; overload;

implementation

    function CalculateEase(CurrentTime, StartValue, ChangeInValue, Duration: Real; EaseType: TChromeTabsEaseType): Real;
    begin
      case EaseType of
        ttLinearTween:
          begin
            Result := ChangeInValue * CurrentTime / Duration + StartValue;
          end;

        ttEaseInQuad:
          begin
            CurrentTime := CurrentTime / Duration;

              Result := ChangeInValue * CurrentTime * CurrentTime + StartValue;
          end;

        ttEaseOutQuad:
          begin
            CurrentTime := CurrentTime / Duration;

              Result := -ChangeInValue * CurrentTime * (CurrentTime-2) + StartValue;
          end;

        ttEaseInOutQuad:
          begin
            CurrentTime := CurrentTime / (Duration / 2);

            if CurrentTime < 1 then
              Result := ChangeInValue / 2 * CurrentTime * CurrentTime + StartValue
            else
            begin
              CurrentTime := CurrentTime - 1;
              Result := -ChangeInValue / 2 * (CurrentTime * (CurrentTime - 2) - 1) + StartValue;
            end;
          end;

        ttEaseInCubic:
          begin
            CurrentTime := CurrentTime / Duration;

            Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime + StartValue;
          end;

        ttEaseOutCubic:
          begin
            CurrentTime := (CurrentTime / Duration) - 1;

            Result := ChangeInValue * ( CurrentTime * CurrentTime * CurrentTime + 1) + StartValue;
          end;

        ttEaseInOutCubic:
          begin
            CurrentTime := CurrentTime / (Duration/2);

            if CurrentTime < 1 then
              Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime + StartValue
            else
            begin
              CurrentTime := CurrentTime - 2;

              Result := ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime + 2) + StartValue;
            end;
          end;

        ttEaseInQuart:
          begin
            CurrentTime := CurrentTime / Duration;

            Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue;
          end;

        ttEaseOutQuart:
          begin
            CurrentTime := (CurrentTime / Duration) - 1;

            Result := -ChangeInValue * (CurrentTime * CurrentTime * CurrentTime * CurrentTime - 1) + StartValue;
          end;

        ttEaseInOutQuart:
          begin
              CurrentTime := CurrentTime / (Duration / 2);

            if CurrentTime < 1 then
              Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue
            else
            begin
              CurrentTime := CurrentTime - 2;

              Result := -ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime * CurrentTime - 2) + StartValue;
            end;
          end;

        ttEaseInQuint:
          begin
            CurrentTime := CurrentTime / Duration;

            Result := ChangeInValue * CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue;
          end;

        ttEaseOutQuint:
          begin
            CurrentTime := (CurrentTime / Duration) - 1;

              Result := ChangeInValue * (CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + 1) + StartValue;
          end;

        ttEaseInOutQuint:
          begin
            CurrentTime := CurrentTime / (Duration / 2);
            if CurrentTime < 1 then
              Result := ChangeInValue / 2 * CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + StartValue
            else
            begin
              CurrentTime := CurrentTime - 2;

              Result := ChangeInValue / 2 * (CurrentTime * CurrentTime * CurrentTime * CurrentTime * CurrentTime + 2) + StartValue;
            end;
          end;

        ttEaseInSine:
          begin
              Result := -ChangeInValue * Cos(CurrentTime / Duration * (PI / 2)) + ChangeInValue + StartValue;
          end;

        ttEaseOutSine:
          begin
              Result := ChangeInValue * Sin(CurrentTime / Duration * (PI / 2)) + StartValue;
          end;

        ttEaseInOutSine:
          begin
            Result := -ChangeInValue / 2 * (Cos(PI * CurrentTime / Duration) - 1) + StartValue;
          end;

        ttEaseInExpo:
          begin
            Result := ChangeInValue * Power(2, 10 * (CurrentTime/Duration - 1) ) + StartValue;
          end;

        ttEaseOutExpo:
          begin
            Result := ChangeInValue * (-Power(2, -10 * CurrentTime / Duration ) + 1 ) + StartValue;
          end;

        ttEaseInOutExpo:
          begin
            CurrentTime := CurrentTime / (Duration/2);

            if CurrentTime < 1 then
              Result := ChangeInValue / 2 * Power(2, 10 * (CurrentTime - 1) ) + StartValue
            else
             begin
               CurrentTime := CurrentTime - 1;

                 Result := ChangeInValue / 2 * (-Power(2, -10 * CurrentTime) + 2 ) + StartValue;
             end;
          end;

        ttEaseInCirc:
          begin
            CurrentTime := CurrentTime / Duration;

              Result := -ChangeInValue * (Sqrt(1 - CurrentTime * CurrentTime) - 1) + StartValue;
          end;

        ttEaseOutCirc:
          begin
            CurrentTime := (CurrentTime / Duration) - 1;

            Result := ChangeInValue * Sqrt(1 - CurrentTime * CurrentTime) + StartValue;
          end;

        ttEaseInOutCirc:
          begin
            CurrentTime := CurrentTime / (Duration / 2);

            if CurrentTime < 1 then
              Result := -ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) - 1) + StartValue
            else
            begin
                CurrentTime := CurrentTime - 2;

                Result := ChangeInValue / 2 * (Sqrt(1 - CurrentTime * CurrentTime) + 1) + StartValue;
            end;
          end;
      end;
    end;

    function CalculateEase(StartPos, EndPos, PositionPct: Real; EaseType: TChromeTabsEaseType): Real;
    var
      t, b, c, d: Real;
    begin
      c := EndPos - StartPos;
      d := 100;
      t := PositionPct;
      b := StartPos;

      Result := CalculateEase(t, b, c, d, EaseType);
    end;

    ...
like image 84
norgepaul Avatar answered Sep 30 '22 22:09

norgepaul