Einzelnen Beitrag anzeigen

Glados
(Gast)

n/a Beiträge
 
#24

AW: Panel geschmeidig ein- und ausblenden?

  Alt 20. Sep 2017, 11:03
Hier die zwei Units. ich packe das in Delphi-Tags, damit jeder Zugriff hat. Es sind circa 200 Zeilen Code.
Delphi-Quellcode:
// Ein Aufruf, Um ButtonY auf FormX horizontal von Position 20 zu 200 und umgekehrt zu animieren, könnte so aussehen
TUtilsEasingAnimations.AnimateControl(FormX.ButtonY, 20, 200, TAnimationDirection.adHorizontal, TAnimationType.adChangeLeftTop);

// Wenn man den Button in der Breite von 20 zu 200 und umgekehrt animieren möchte so
TUtilsEasingAnimations.AnimateControl(FormX.ButtonY, 20, 200, TAnimationDirection.adHorizontal, TAnimationType.adChangeWidthHeight);
Selbes gilt für adVertical statt adHorizontal.

Speziell AnimateControl hat Optimierungsbedarf. Für mich aber funktioniert es. Kritik gerne willkommen.

### 99% von diesem Code wurde von Zacherl erstellt ###

Core Unit
Delphi-Quellcode:
unit Utils.Easing.Core;

interface

uses Math;

type
 TUtilsEasingCore = class
 public
  class function EaseInQuart(T, B, C, D: Integer): Integer; static;
  class function EaseOutQuart(T, B, C, D: Integer): Integer; static;
  class function EaseInQuint(T, B, C, D: Integer): Integer; static;
  class function EaseOutQuint(T, B, C, D: Integer): Integer; static;
  class function EaseOutBounce(T, B, C, D: Integer): Integer; static;
  class function EaseOutElastic(T, B, C, D: Integer): Integer; static;
 end;

implementation

// Quart easing
// ==============================================================================================================================================
class function TUtilsEasingCore.EaseInQuart(T, B, C, D: Integer): Integer;
var
 T2: Single;
begin
 T2 := T / D;
 Result := Round(C * T2 * T2 * T2 * T2) + B;
end;

class function TUtilsEasingCore.EaseOutQuart(T, B, C, D: Integer): Integer;
var
 T2: Single;
begin
 T2 := T / D - 1;
 Result := Round(-C * (T2 * T2 * T2 * T2 - 1)) + B;
end;
// ==============================================================================================================================================

// Quint easing
// ==============================================================================================================================================
class function TUtilsEasingCore.EaseInQuint(T, B, C, D: Integer): Integer;
var
 T2: Single;
begin
 T2 := T / D;
 Result := Round(C * T2 * T2 * T2 * T2 * T2) + B;
end;

class function TUtilsEasingCore.EaseOutQuint(T, B, C, D: Integer): Integer;
var
 T2: Single;
begin
 T2 := T / D - 1;
 Result := Round(C * (T2 * T2 * T2 * T2 * T2 + 1)) + B;
end;
// ==============================================================================================================================================

// Bounce/elastic easing
// ==============================================================================================================================================
class function TUtilsEasingCore.EaseOutBounce(T, B, C, D: Integer): Integer;
var
 T2: Single;
begin
 T2 := T / D;
 if (T2 < (1.0 / 2.75)) then
  begin
   Result := Round(C * (7.5625 * T2 * T2)) + B;
  end
 else if (T2 < (2.0 / 2.75)) then
  begin
   T2 := T2 - (1.5 / 2.75);
   Result := Round(C * (7.5625 * T2 * T2 + 0.75)) + B;
  end
 else if (T2 < (2.5 / 2.75)) then
  begin
   T2 := T2 - (2.25 / 2.75);
   Result := Round(C * (7.5625 * T2 * T2 + 0.9375)) + B;
  end
 else
  begin
   T2 := T2 - (2.625 / 2.75);
   Result := Round(C * (7.5625 * T2 * T2 + 0.984375)) + B;
  end;
end;

class function TUtilsEasingCore.EaseOutElastic(T, B, C, D: Integer): Integer;
var
 S, P, A, T2: Double;
begin
 if (T = 0) then
  begin
   Exit(B);
  end;
 T2 := T / D;
 if (T2 = 1) then
  begin
   Exit(B + C);
  end;
 P := D * 0.3;
 A := C;
 if (A < Abs(C)) then
  begin
   S := P / 4;
  end
 else
  begin
   S := P / (2 * PI) * ArcSin(C / A);
  end;
 Result := Round(A * Power(2, -10 * T2) * Sin((T2 * D - S) * (2 * PI) / P)) + C + B;
end;
// ==============================================================================================================================================

end.
Unit, welche für die Animation zuständig ist
Delphi-Quellcode:
unit Utils.Easing.Animations;

interface

uses Winapi.Windows, Vcl.Controls, Vcl.Forms, SysUtils;

type
 TAnimationDirection = (adHorizontal, adVertical);
 TAnimationType = (adChangeWidthHeight, adChangeLeftTop);

type
 TUtilsEasingAnimations = class
 private const
  AnimateDuration = 300;
 public
  class procedure AnimateControl(Control: TWinControl; iStart, iEnd: Integer; aAnimationDirection: TAnimationDirection; aAnimationType: TAnimationType); static;
 end;

implementation

uses Utils.Easing.Core;

// Main animation controller
// ==============================================================================================================================================
// Example call:
// TUtilsEasingAnimations.AnimateControl(FormX.ButtonY, 20, 200, TAnimationDirection.adHorizontal, TAnimationType.adChangeLeftTop);
class procedure TUtilsEasingAnimations.AnimateControl(Control: TWinControl; iStart, iEnd: Integer; aAnimationDirection: TAnimationDirection; aAnimationType: TAnimationType);
var
 C, D: Cardinal;
 iTmpControlDimension, iTmp, iStartTmp, iEndTmp: Integer;
 procedure setControlDimension(iDimension: Integer);
 begin
  if aAnimationDirection = TAnimationDirection.adHorizontal then
   begin
    if aAnimationType = TAnimationType.adChangeWidthHeight then
     Control.Width := iDimension
    else if aAnimationType = TAnimationType.adChangeLeftTop then
     Control.Left := iDimension
   end
  else if aAnimationDirection = TAnimationDirection.adVertical then
   begin
    if aAnimationType = TAnimationType.adChangeWidthHeight then
     Control.Height := iDimension
    else if aAnimationType = TAnimationType.adChangeLeftTop then
     Control.Top := iDimension;
   end;
 end;

begin
 // Prepare needed data
 // ==============================================================================================================================================
 C := GetTickCount;
 D := 0;
 iTmpControlDimension := 0;

 if aAnimationDirection = TAnimationDirection.adHorizontal then
  begin
   if aAnimationType = TAnimationType.adChangeWidthHeight then
    iTmpControlDimension := Control.Width
   else if aAnimationType = TAnimationType.adChangeLeftTop then
    iTmpControlDimension := Control.Left;
  end
 else if aAnimationDirection = TAnimationDirection.adVertical then
  begin
   if aAnimationType = TAnimationType.adChangeWidthHeight then
    iTmpControlDimension := Control.Height
   else if aAnimationType = TAnimationType.adChangeLeftTop then
    iTmpControlDimension := Control.Top;
  end;

 if iTmpControlDimension = 0 then
  Exit;

 iStartTmp := iTmpControlDimension;
 iEndTmp := iEnd;
 if iStartTmp >= iEndTmp then
  begin
   iTmp := iStart;
   iStart := iEnd;
   iEnd := iTmp;
  end;
 // ============================================================================================================================================== end;

 // Display the animation
 // ==============================================================================================================================================
 while (D <= TUtilsEasingAnimations.AnimateDuration) do
  begin
   setControlDimension(TUtilsEasingCore.EaseOutQuint(D, iStart, iEnd - iStart, TUtilsEasingAnimations.AnimateDuration));

   Application.ProcessMessages;
   D := GetTickCount - C;
  end;
 setControlDimension(iEnd);
 // ==============================================================================================================================================
end;
// ==============================================================================================================================================

end.

Geändert von Glados (20. Sep 2017 um 11:07 Uhr)
  Mit Zitat antworten Zitat