【发布时间】:2011-12-29 00:37:05
【问题描述】:
我正在尝试制作一个当鼠标指向它时会发光的按钮。背景中必须有一个计时器来控制这些颜色的平滑淡入淡出。它不会从一种颜色跳到另一种颜色,它会逐渐消失到下一种颜色。
现在我的问题是,当它变回正常颜色时,它不会锁定到最终颜色。事实上,它一直在从亮到暗。
这是我的一个自定义按钮,我不打算发布它的代码,但是这个代码可以通过鼠标进入/退出事件和颜色属性放置到任何东西上。
它通过设置变量FMenuDestColor 来工作。 ExtractColor 根据颜色获取 RGB 值。计时器比较当前颜色和目标颜色之间的每个 RGB 通道。然后计时器修改当前颜色以淡入下一个颜色。这些计算在一个名为 CalcColorFade 的函数中完成 - 每个通道运行 3 次。
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;
将鼠标指向它,它会淡出到下一个颜色。但是把鼠标移开,它就不会锁定在原来颜色的位置——它在明暗之间来回摇晃。
我假设必须有一种更简洁的方法来完成我正在做的事情,我也愿意接受这些建议。
定时器的时间间隔是70,常数是1.2,改成1.1就可以了。因此,将其更改为 1.2 的一些事情搞砸了。
【问题讨论】:
-
我认为如果您将处理 R、G 和 B 的相同代码放入一个过程中并单独调用它 3 次,您会发现您的代码更易于阅读:传入 @第一次运行时为 987654325@ 和
R2,第二次运行时为G1和G2,等等 -
@sarnold 好建议,尽管与问题无关,但无论如何我都会这样做。
-
确实如此,这就是我将其作为评论留下的原因——我无法发现您实际上试图解决的问题。只是暗示如果它在那些块中,只修复一次而不是三次会更容易...... :)
-
@sarnold 我采纳了你的建议并做到了 - 更新了有问题的代码,更简洁:D
-
事实上,我正在考虑像这样在自己的线程中运行每个 R/G/B 通道的想法:P 但它必须是更大范围的东西才能需要 3 个线程.
标签: delphi math colors delphi-7