Question

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?

Was it helpful?

Solution

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;

    ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top