Sto provando a creare un pulsante che si illumina quando viene puntato il mouse su di esso. Ci deve essere un timer in sottofondo per controllare una dissolvenza fluida di questi colori. Non salta da un colore all'altro, gradualmente sfuma al colore successivo.Come manipolare i colori per dare un effetto luminoso in tempo reale?
Ora il mio problema è che quando si dissolve nuovamente al suo colore normale, non si blocca nel colore finale. Infatti, continua a saltare dalla luce al buio.
Questo è un mio pulsante personalizzato, di cui non ho intenzione di pubblicare il codice, ma questo codice può essere inserito in qualsiasi cosa con un evento di input/exit del mouse e una proprietà di colore.
Funziona impostando una variabile FMenuDestColor
. ExtractColor
ottiene i valori RGB in base a un colore. Il timer confronta ogni canale RGB tra il colore corrente e il colore di destinazione. Quindi il timer modifica il colore corrente da sfumare al successivo. Questi calcoli vengono eseguiti in una funzione denominata CalcColorFade
, eseguita 3 volte per ciascun canale.
procedure ExtractColor(const Color: TColor; var R, G, B: Byte);
begin
R:= GetRValue(Color);
G:= GetGValue(Color);
B:= GetBValue(Color);
end;
function CalcColorFade(const C1, C2: Byte): Byte;
const
RGB_MULT = 1.2;
RGB_SENS = 5;
begin
if C1 <> C2 then begin
if (C1 >= C2 - RGB_SENS) and (C1 <= C2 + RGB_SENS) then
Result:= C2
else
if C1 > C2 then
Result:= EnsureRange(Trunc(C1/RGB_MULT), 0, 255)
else
Result:= EnsureRange(Trunc(C1 * RGB_MULT), 0, 255);
end else begin
Result:= C2;
end;
end;
procedure TfrmMain.tmrMenuGlowTimer(Sender: TObject);
var
R1, G1, B1: Byte;
R2, G2, B2: Byte;
R3, G3, B3: Byte;
begin
if MenuButton.Color <> FMenuDestColor then begin
ExtractColor(MenuButton.Color, R1, G1, B1);
ExtractColor(FMenuDestColor, R2, G2, B2);
R3:= CalcColorFade(R1, R2);
G3:= CalcColorFade(G1, G2);
B3:= CalcColorFade(B1, B2);
MenuButton.Color:= RGB(R3, G3, B3);
end;
end;
procedure TfrmMain.MenuButtonMouseEnter(Sender: TObject);
begin
FMenuDestColor:= clBlue;
end;
procedure TfrmMain.MenuButtonMouseLeave(Sender: TObject);
begin
FMenuDestColor:= clNavy;
end;
Puntare il mouse su di esso e si dissolverà al colore successivo. Ma togliti il mouse e non si blocca in posizione con il suo colore originale - si muove avanti e indietro tra la luce e il buio.
Suppongo che ci debba essere un approccio più pulito per realizzare ciò che sto facendo, e sono aperto anche a questi suggerimenti.
L'intervallo del timer è a 70 e la costante di 1,2, se modificata a 1,1, funziona perfettamente. Quindi qualcosa su come cambiarlo in 1.2 che lo ha incasinato.
Penso che troverai il tuo codice più facile da leggere se prendi lo stesso codice di gestione R, G e B e lo consideri in una procedura da solo e lo chiami tre volte: passando in 'R1' e' R2 'alla prima esecuzione,' G1' e 'G2' alla seconda esecuzione, ecc. – sarnold
@sarnold Un buon consiglio che avrei comunque finito, anche se non correlato alla domanda. –
Abbastanza vero, motivo per cui l'ho lasciato come commento: non riesco a individuare il problema che stai provando a risolvere. Dando solo il suggerimento che sarebbe più facile risolverlo solo una volta anziché tre volte se è in quei blocchi ... :) – sarnold