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?

有帮助吗?

解决方案

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;

    ...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top