AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Panel geschmeidig ein- und ausblenden?

Ein Thema von Glados · begonnen am 16. Sep 2017 · letzter Beitrag vom 22. Sep 2017
Antwort Antwort
Seite 2 von 6     12 34     Letzte »    
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Panel geschmeidig ein- und ausblenden?

  Alt 16. Sep 2017, 19:10
Es gibt übrigens auch noch die API Funktion AnimateWindow... Damit geht so etwas auch und sieht meistens auch besser aus als eigene Funktionen:
https://msdn.microsoft.com/de-de/lib...%3Dvs.85).aspx
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#12

AW: Panel geschmeidig ein- und ausblenden?

  Alt 16. Sep 2017, 19:38
Das ist nicht genau das was ich suche.
Manuell ist in meinem Fall definitiv besser. AnimateWindow macht nicht das was ich möchte.

Zacherl Lösung ist wirklich sehr gut und sieht gut aus. Nur verstehe ich nicht die Logik wie man es umkehrt.

Verstanden habe ich es zwar nicht, aber so läuft es fast. Er fährt von 20 (START) bis 200 (END). Umgekehrt funktioniert es nicht.

Delphi-Quellcode:
const
 Duration = 3000;
 POS_START = 20;
 POS_END = 200;

 if Button1.Left = POS_START then
  begin
   while (D < Duration) do
    begin
     Button1.Left := POS_START + Round(POS_END * CalculateEasingCurve(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;
  end
 else
  begin
   while (D < Duration) do
    begin
     Button1.Left := POS_END - Round(POS_END * CalculateEasingCurve(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;
  end;
Vorzeitige Lösung
Delphi-Quellcode:
     if Panel1.Width = POS_START then
      begin
       iNegative := 1;
       iTmp := POS_START
      end
     else
      begin
       iNegative := -1;
       iTmp := POS_START + POS_END;
      end;

     while (D < Duration) do
      begin
       Panel1.Width := iTmp + (Round(POS_END * CalculateEasingCurve(D, Duration)) * iNegative);
       Application.ProcessMessages;
       D := GetTickCount - C;
      end;

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

n/a Beiträge
 
#13

AW: Panel geschmeidig ein- und ausblenden?

  Alt 16. Sep 2017, 22:23
Ich muss leider noch einmal nerven. Irgendwas stimmt hier leider noch nicht.
Es hat irgendwas mit der markierten Zeile zu tun
Delphi-Quellcode:
 if Control.Height >= iMaxHeight then
  begin
   iNegative := -1;
   iTmp := iMinHeight + iMaxHeight; // DIESE ZEILE
  end
 else // if Control.Height <= iMinHeight then
  begin
   iNegative := 1;
   iTmp := iMinHeight
  end;

 while (D < 3000) do
  begin
   Control.Height := iTmp + (Round(iMaxHeight * Easing(D, 3000)) * iNegative);
   Application.ProcessMessages;
   D := GetTickCount - C;
  end;
Das ist bei mir jetzt eine Prozedur. Control ist ein TWinControl. Wenn ich dort als Control ein Formular TForm (aktuell 350 Height) übergebe mit Minimum 220 (iMinHeight) und Maximum 350 (iMaxHeight), dann wird das Formular erst einmal komplett lang gezogen (Min + Max). Bei anderen Controls funktioniert das ohne Probleme und ohne dieses initiale Langziehen.

Meine Grundfrage wäre also... wie sieht das da unten umgekehrt aus?
Delphi-Quellcode:
   while (D < Duration) do
    begin
     Button1.Left := POS_START + Round(POS_END * CalculateEasingCurve(D, DURATION));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;

Geändert von Glados (16. Sep 2017 um 23:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: Panel geschmeidig ein- und ausblenden?

  Alt 16. Sep 2017, 23:59
Müsste es vielleicht so sein?
 iTmp := iMaxHeight Es würde dann die maximale Höhe eingestellt (wenn ich das richtig interpretiere).
Sonst startest Du mit der maximalen+minimalen Höhe.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#15

AW: Panel geschmeidig ein- und ausblenden?

  Alt 17. Sep 2017, 00:09
Ich habe dir hier mal ein Beispiel gebastelt. Einfach in einen Button packen (Form sollte initial ~500 hoch sein) und die Caption beobachten.

Delphi-Quellcode:
function QuintEasing(TimePassed, Duration: DWord): Single;
var
 P: Double;
begin
 P := TimePassed / (Duration / 2);
 if (P < 1) then
  begin
   Result := 1 / 2 * P * P * P * P * P;
  end
 else
  begin
   P := P - 2;
   Result := 1 / 2 * (P * P * P * P * P + 2);
  end;
end;


Button
var
 C, D: Cardinal;
const
 Duration = 3000;
 POS_START = 200; // Größe eingeklappt
 POS_END = 500; // Größe ausgeklappt
begin
 C := GetTickCount;
 D := 0;
 if Height >= POS_END then
  begin
   // EDIT
   // Mit diesem Spagetti-Code funktioniert es auch. Aber das ist sicherlich alles mehr als falsch
   // POS_END := POS_END - POS_START - (POS_END - Height);
   // POS_START := Height;

   while (D < Duration) do
    begin
     Height := POS_START - Round(POS_END * QuintEasing(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;

   Caption := '1. ' + Height.ToString;

   // Formular wird beim ersten Klick erst einmalig 700px hoch eingestellt (falsch) und fährt dann auf 200px runter (richtig)
  end
 else
  begin
   // POS_START := Height;
   // POS_END := POS_END - POS_START;
   // Diese beiden Zeilen reparieren dieses If-Statement. Oben verstehe ich die umgekehrte Logik aber nicht und finde keine Lösung.

   while (D < Duration) do
    begin
     Height := POS_START + Round(POS_END * QuintEasing(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;

   Caption := '2. ' + Height.ToString;

   // Ein anschließender Klick hier stellt das Formular 700px hoch ein (falsch)
  end;
Edit: siehe Kommentar bei Height >= POS_END

Geändert von Glados (17. Sep 2017 um 00:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: Panel geschmeidig ein- und ausblenden?

  Alt 17. Sep 2017, 00:37
Die Funktion ermittelt nicht, welche Höhe beim Start vorliegt, sondern entscheidet nur, ob von groß nach klein oder von klein nach groß animiert wird.

Fixen kannst Du das ggf. so:
Delphi-Quellcode:
    while (D < Duration) do
    begin
      H := POS_START + POS_END - Round(POS_END * QuintEasing(D, Duration));
      if (H < Height) then
        Height := H;
      Application.ProcessMessages;
      D := GetTickCount - C;
    end;
So entsteht allerdings am Anfang eine Verzögerung, da ja die getimeten Berechnungen trotzdem erfolgen.
Um das zu Verhindern müsstest Du die Berechnungsdauer (Duration) verkürzen oder besser in die Berechnung die Starthöhe einbeziehen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#17

AW: Panel geschmeidig ein- und ausblenden?

  Alt 17. Sep 2017, 00:41
Was denkst du denn über meine Änderung oben? Ich poste es hier unten noch einmal sauber neu:

Delphi-Quellcode:
Button
var
 C, D: Cardinal;
const
 Duration = 3000;
 POS_START = 200; // Größe eingeklappt
 POS_END = 500; // Größe ausgeklappt
begin
 C := GetTickCount;
 D := 0;
 if Height >= POS_END then
  begin
   // > ÄNDERUNG
   POS_END := POS_END - POS_START - (POS_END - Height);
   POS_START := Height;
   // < ÄNDERUNG

   while (D < Duration) do
    begin
     Height := POS_START - Round(POS_END * QuintEasing(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;

   Caption := '1. ' + Height.ToString;
  end
 else
  begin
   // > ÄNDERUNG
   POS_START := Height;
   POS_END := POS_END - POS_START;
   // < ÄNDERUNG

   while (D < Duration) do
    begin
     Height := POS_START + Round(POS_END * QuintEasing(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;

   Caption := '2. ' + Height.ToString;
  end;
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli
Online

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#18

AW: Panel geschmeidig ein- und ausblenden?

  Alt 17. Sep 2017, 01:04
Hast Du versucht, das zu compilieren?
Das geht so nicht, da man Pos_End nichts zuweisen kann, da das eine Konstante ist.

Ich hatte vorhin schonmal versucht, die Starthöhe zu berücksichtigen.
Das ist mir aber nicht gelungen.

Vielleicht Zacherl man noch einen Tipp geben.
Ich denke aber, dass eine Kurvenfunktion dafür die bessere Lösung wäre.
(Ich bin aber mathematisch leider eine Niete und tue mich schwer mit so etwas.)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#19

AW: Panel geschmeidig ein- und ausblenden?

  Alt 17. Sep 2017, 01:17
Zitat:
Hast Du versucht, das zu compilieren?
Das geht so nicht, da man Pos_End nichts zuweisen kann, da das eine Konstante ist.
Habe daraus eine Variable gemacht.

Es funktioniert nun einwandfrei, egal bei welcher Starthöhe. Es geht wird immer auf Minimum und Maximum gesetzt. Dafür sieht das auch etwas anders aus jetzt
Delphi-Quellcode:
 if Height >= iMaxHeight then
  begin
   iNegative := -1;

   // > ÄNDERUNG
   iTmp := iMinHeight;
   iMaxHeight := iMaxHeight - iTmp - (iMaxHeight - Height);
   iTmp := Height;
  end
 else // if Height <= iMinHeight then
  begin
   iNegative := 1;

   // > ÄNDERUNG
   iTmp := Height;
   iMaxHeight := iMaxHeight - iTmp;
  end;

 while (D < 3000) do
  begin
   iTmpRes := iTmp + (Round(iMaxHeight * QuintEasing(D, 3000)) * iNegative);
  
   // mache was mit iTmpRes
  end;
Funktioniert so bestens.

Zitat:
(Ich bin aber mathematisch leider eine Niete und tue mich schwer mit so etwas.)
geht mir genau so. Ich habe an diesen 4 Zeilen stunden lang gesessen und bestimmt 50x kompiliert und getestet
Berechnet habe ich da nix, da ich nicht weiß wie. Ich habe einfach alle Variablen genommen, zusammengemixt und geguckt wann das Resultat bei allen Szenarien richtig ist.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#20

AW: Panel geschmeidig ein- und ausblenden?

  Alt 18. Sep 2017, 02:18
Tatsächlich enthält mein Beispielcode einen kleinen Flüchtigkeitsfehler < statt <= in der Schleifenbedingung. Habe die Kurvenfunktionen mal etwas intuitiver gestaltet:
Delphi-Quellcode:
function EaseInQuart(T, B, C, D: Integer): Integer;
var
  T2: Single;
begin
  T2 := T / D;
  Result := Round(C * T2 * T2 * T2 * T2) + B;
end;

function 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;

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

function 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;

function 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;

function 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;

procedure TForm1.Button3Click(Sender: TObject);
const
  DURATION = 1000;
  POS_START = 8;
  POS_END = 520;
var
  C, D: Cardinal;
begin
  // Über einen Zeitraum von 1 Sekunde von Position 8 nach Position 320 verschieben
  C := GetTickCount;
  D := 0;
  while (D <= DURATION) do
  begin
    Button1.Left := EaseOutElastic(D, POS_START, POS_END - POS_START, DURATION);
    Application.ProcessMessages;
    D := GetTickCount - C;
  end;
  Button1.Left := POS_END;
end;

procedure TForm1.Button4Click(Sender: TObject);
const
  DURATION = 1000;
  POS_START = 520;
  POS_END = 8;
var
  C, D: Cardinal;
begin
  // Über einen Zeitraum von 1 Sekunde von Position 320 nach Position 8 verschieben
  C := GetTickCount;
  D := 0;
  while (D <= DURATION) do
  begin
    Button1.Left := EaseOutElastic(D, POS_START, POS_END - POS_START, DURATION);
    Application.ProcessMessages;
    D := GetTickCount - C;
  end;
  Button1.Left := POS_END;
end;
Erklärung der Parameter:
Delphi-Quellcode:
T = Vergangene Zeit
B = Startwert
C = Änderung
D = Dauer der Animation
Als Bonus gibt es noch die EaseOutBounce und die EaseOutElastic Kurven, welche ich persönlich ganz schick finde.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (18. Sep 2017 um 02:38 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 6     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz