I'm trying to make a button which glows when the mouse is pointed over it. There has to be a timer in the background to control a smooth fading in-and-out of these colors. It doesn't jump from one color to the next, it gradually fades to the next color.
Now my problem is that when it fades back to its regular color, it doesn't lock into its final color. In fact, it keeps jumping from light to dark.
This is a custom button of mine, which I'm not going to post the code of, but this code can be placed onto anything with a mouse enter/exit event and a color property.
It works by setting a variable FMenuDestColor
. ExtractColor
gets RGB values based on a color. The timer compares each RGB channel between the current color and the destination color. Then the timer modifies the current color to fade to the next. These calculations are done in a function called CalcColorFade
- run 3 times for each channel.
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;
Point the mouse over it, and it will fade to the next color. But take the mouse off of it, and it kinda doesn't lock into position at its original color - it shakes back and forth between light and dark.
I'm assuming there must be a cleaner approach to accomplish what I'm doing, and I'm open to those suggestions too.
The timer's interval is at 70 and the constant of 1.2, when changed to 1.1, it works just fine. So something about changing it to 1.2 that messed this up.
Why not just switch to HSB/HSV mode?
Then you can set your Hue (0-359), and control saturation, brightness and alpha.
Each of the latter three give you options for a rolling glow effect.
Problem was solved by adjusting the other constant RGB_SENS
to 7
.
So it seems the higher I go with RGB_MULT
, the higher I have to take RGB_SENS
.
What happens is it first gets the current color of the control, then gets the destination color, splits each of those colors into RGB channels, then for each of those channels, it does this function to get the "new" RGB value...
function DoCalc(const Curr, Dest: Byte): Byte;
const
RGB_MULT = 1.2; //How much color change per step
RGB_SENS = 10; //Distance from dest +/- until "locked" into dest
begin
if Curr <> Dest then begin
if (Curr >= Dest - RGB_SENS) and (Curr <= Dest + RGB_SENS) then begin
Result:= Dest; //Lock color into destination (sensitivity)
end else begin
if Curr > Dest then begin //Needs to go down
Result:= EnsureRange(Trunc(Curr / RGB_MULT), 0, 255);
end else begin //Needs to go up
Result:= EnsureRange(Trunc(Curr * RGB_MULT), 0, 255);
end;
end;
end else begin
Result:= Dest; //Just return the dest color, no change
end;
end;
Before, RGB_MULT
used to be set at 1.1
, which worked fine. But when I increased it to 1.2
, that's when my problem started. At that time, RGB_SENS
was set to 5
. RGB_SENS
determines how far from the Destination color until the color should "Lock" into place. Evidently, 1.2
caused it to never land in this range. After expanding RGB_SENS
to 7
(and now 10
), it works fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With