Delphi-PRAXiS
Seite 1 von 6  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Panel geschmeidig ein- und ausblenden? (https://www.delphipraxis.net/193860-panel-geschmeidig-ein-und-ausblenden.html)

Glados 16. Sep 2017 14:10

Panel geschmeidig ein- und ausblenden?
 
Ich nutze schon längere einen seltsamen, von mir geschriebenen Code, der ein Panel seitlich einblendet.

Beispiel:
Normal: [ CONTENT ]
Mit Panel: [ PANEL | CONTENT ]

Das Panel fährt von links rein und wird aktuell einfach von 0px an in der Größe verändert, bis es eine Maximalbreite erreicht hat.
Wie würdet ihr das Panel auf Knopfdruck geschmeidig "reinfahren" lassen? Ich rede nicht von Fade-Effekten sondern von Slide-Effekten (nennt man das so?).

stahli 16. Sep 2017 14:33

AW: Panel geschmeidig ein- und ausblenden?
 
Was ist denn seltsam an Deinem Code und was funktioniert nicht wie gewünscht?

Armin hatte hier mal einen netten Effekt umgesetzt: http://www.delphipraxis.net/156662-t...-fluessig.html

Grundsätzlich könntest Du eine Zielbreite festlegen und in einem Timer schrittweise dorthin erhöhen/reduzieren.

Dabei habe ich mal den Wert immer um die hälfte der Restdifferenz erhöht/verringert.

Z.B. bei aktuellem Wert 0 auf 100 etwa so:
50
75
88
94
97
99
100

Das sah dann ganz flüssig und dynamisch aus.

Glados 16. Sep 2017 14:35

AW: Panel geschmeidig ein- und ausblenden?
 
Zitat:

Was ist denn seltsam an Deinem Code und was funktioniert nicht wie gewünscht?
Es funktioniert wie gewünscht nur er ist nicht schön. Ehrlich gesagt sogar richtig hässlich, weswegen ich ihn nicht zeigen möchte. Stell dir einfach vor du gehst durch 10 Türen, obwohl du nur durch eine musst :thumb:

Ich probiere deinen Ansatz mal aus.

Zacherl 16. Sep 2017 14:41

AW: Panel geschmeidig ein- und ausblenden?
 
Stichwort: Easing.

Das sind Algorithmen, die dir eine bestimmte Kurve in Abhängigkeit von der Zeit generieren (bzw. den entsprechenden Multiplikator zu deinem Grundwert). Konkrete Implementierungen findest du auch recht einfach per Google bzw. hatte ich hier auch mal einige Easing-Curves umgesetzt.

Glados 16. Sep 2017 14:47

AW: Panel geschmeidig ein- und ausblenden?
 
Easing ist ja schön. Aber dafür direkt eine ganze Komponente bzw. gefühlt 20 Units, ich weiß nicht.
stahlis Idee kann ich übrigens nicht umsetzen. Mathematisch wüsste ich nicht einmal wie (ja, ich bin ein Mathe-Trottel).

Habe das als totaler Mathe-Noob mal so gemacht.
Delphi-Quellcode:
 iTargetWidth := 200;
 iRest := 0;

 repeat
  iRest := iRest + (iTargetWidth - Panel1.Width) div 2;
   Panel1.Width := iRest;
   Sleep(25);
 until Panel1.Width = iTargetWidth - 1;

Zacherl 16. Sep 2017 15:42

AW: Panel geschmeidig ein- und ausblenden?
 
Zitat:

Zitat von Glados (Beitrag 1381355)
Easing ist ja schön. Aber dafür direkt eine ganze Komponente bzw. gefühlt 20 Units, ich weiß nicht.

Bei dem Projekt handelt es sich nicht um eine Komponente, sondern um ein komplettes GUI Framework. Die Unit sollte nur ein Anstoß für dich sein, bzw. eine Quelle aus der du dir die mathematischen Berechnungen rauskopieren kannst.

Besonders
Delphi-Quellcode:
TDXInQuartEasingCurve
und
Delphi-Quellcode:
TDXOutQuartEasingCurve
sollten für dich interessant sein. Die Umsetzung ist denkbar einfach:
Delphi-Quellcode:
{ TDXInQuartEasingCurve }

function TDXInQuartEasingCurve.CalculateEasingCurve(TimePassed, Duration: DWord): Single;
var
  P: Double;
begin
  P := TimePassed / Duration;
  Result := P * P * P * P;
end;

{ TDXOutQuartEasingCurve }

function TDXOutQuartEasingCurve.CalculateEasingCurve(TimePassed, Duration: DWord): Single;
var
  P: Double;
begin
  P := TimePassed / (Duration - 1);
  Result := - (P * P * P * P) - 1;
end;

Glados 16. Sep 2017 15:52

AW: Panel geschmeidig ein- und ausblenden?
 
Was genau ist denn das Resultat? Was macht man damit und woher bekommt man TimePassed? Duration wird ja vermutlich die Zeit sein, die man selber angeben kann.

stahli 16. Sep 2017 15:55

AW: Panel geschmeidig ein- und ausblenden?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal schnell meinen Schnipsel (auch als Anregung) rausgesucht.
Vielleicht kannst Du Dir davon etwas ableiten.
Ich habe ein aktuelles und ein Ziel-Rect. Das aktuelle Rects wird so lange verändert, bis die Zielpositionen erreicht sind.


Delphi-Quellcode:
    if (DropRect.IsEmpty) then
    begin
      if (not DropRectReal.IsEmpty) then
      begin
        X := DropRectReal.Left + (DropRectReal.Width div 2);
        Y := DropRectReal.Top + (DropRectReal.Height div 2);
        L := Max((X - DropRectReal.Left) div 4, 1);
        T := Max((Y - DropRectReal.Top) div 4, 1);
        R := Min((X - DropRectReal.Right) div 4, -1);
        B := Min((Y - DropRectReal.Bottom) div 4, -1);
        DropRectReal := TRect.Create(DropRectReal.Left + L, DropRectReal.Top + T,
          DropRectReal.Right + R, DropRectReal.Bottom + B);
      end;
    end
    else
    begin
      if (DropRectReal.IsEmpty) then
      begin
        X := DropRect.Left + (DropRect.Width div 2);
        Y := DropRect.Top + (DropRect.Height div 2);
        DropRectReal := TRect.Create(X, Y, X, Y);
      end;
      L := (DropRect.Left - DropRectReal.Left) div 4;
      T := (DropRect.Top - DropRectReal.Top) div 4;
      R := (DropRect.Right - DropRectReal.Right) div 4;
      B := (DropRect.Bottom - DropRectReal.Bottom) div 4;
      DropRectReal := TRect.Create(DropRectReal.Left + L, DropRectReal.Top + T,
        DropRectReal.Right + R, DropRectReal.Bottom + B);
    end;

    if (DropRectReal.Left <> DropRect.Left) or (DropRectReal.Top <> DropRect.Top) or
      (DropRectReal.Width <> DropRect.Width) or (DropRectReal.Height <> DropRect.Height) then
    begin
      NächstenSchrittVeranlassen;
    end;

Aber wenn Dein Ergebnis funktioniert, kannst Du Deinen Code letztlich auch einfach so als Jugendsünde drin lassen. Stört ja keinen. :-)
Wenn es gut und stabil (ohne Abstürze) läuft, ist es doch i.O.

Zacherl 16. Sep 2017 16:14

AW: Panel geschmeidig ein- und ausblenden?
 
Zitat:

Zitat von Glados (Beitrag 1381359)
Was genau ist denn das Resultat? Was macht man damit und woher bekommt man TimePassed? Duration wird ja vermutlich die Zeit sein, die man selber angeben kann.

Delphi-Quellcode:
const
  DURATION = 1000; // 1 Sek für Gesamtanimation
  POS_START =   8;
  POS_END  = 300;
var
  C, D: Cardinal;
begin
  C := GetTickCount;
  D := 0;
  while (D < DURATION) do
  begin
    Button1.Left := POS_START +
      Round(POS_END * TDXInOutQuintEasingCurve.CalculateEasingCurve(D, DURATION));
    Application.ProcessMessages;
    D := GetTickCount - C;
  end;
end;

Glados 16. Sep 2017 17:38

AW: Panel geschmeidig ein- und ausblenden?
 
Ich glaube ich bin zu dumm dafür das umzukehren
Delphi-Quellcode:
   while (D < Duration) do
    begin
     Button1.Left := Button1.Left - Round(POS_START * CalculateEasingCurveOut(D, Duration));
     Application.ProcessMessages;
     D := GetTickCount - C;
    end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:41 Uhr.
Seite 1 von 6  1 23     Letzte »    

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