如何操纵颜色以提供实时发光效果?

Jer*_*dge 6 delphi math colors delphi-7

我正在尝试制作一个按钮,当鼠标指向它时会发光.背景中必须有一个计时器来控制这些颜色的平滑淡入和淡出.它不会从一种颜色跳到另一种颜色,它逐渐淡化为下一种颜色.

现在我的问题是,当它淡化回常规颜色时,它不会锁定到它的最终颜色.事实上,它一直从光明到黑暗.

这是我的一个自定义按钮,我不打算发布代码,但是这个代码可以放在鼠标输入/退出事件和颜色属性的任何东西上.

它通过设置变量来工作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;
Run Code Online (Sandbox Code Playgroud)

将鼠标指向它,它将淡入下一个颜色.但是把鼠标从它上面移开,它有点不会锁定在其原始颜色的位置 - 它在光明与黑暗之间来回摇晃.

我假设必须有一个更清洁的方法来完成我正在做的事情,我也对这些建议持开放态度.

计时器的间隔为70,常数为1.2,当改为1.1时,它的工作正常.所以有关将它改为1.2的事情搞砸了.

Jer*_*dge 1

通过将另一个常数调整为 解决了RGB_SENS问题7

所以看来我走得越高RGB_MULT,我就必须走得越高RGB_SENS

发生的情况是,它首先获取控件的当前颜色,然后获取目标颜色,将每个颜色分割为 RGB 通道,然后对于每个通道,它执行此函数来获取“新”RGB 值...

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;
Run Code Online (Sandbox Code Playgroud)

以前,RGB_MULT曾经设置为1.1,效果很好。但是当我将其增加到 时1.2,我的问题就开始了。当时,RGB_SENS被设定为5RGB_SENS确定距离目标颜色多远,直到颜色应“锁定”到位。显然,1.2导致它永远无法落在这个范围内。扩展RGB_SENS7(现在10)后,它工作正常。