You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi的VCL框架中实现跟随鼠标的手电筒光标效果?

在Delphi VCL中实现跟随鼠标的手电筒效果

核心思路

手电筒效果的本质是在窗体上叠加一层半透明遮罩,仅在鼠标位置保留一块透明的圆形区域,以此模拟光线照射的视觉效果。

实现步骤

1. 窗体基础设置

将目标窗体的DoubleBuffered属性设置为True,避免重绘时出现闪烁问题。

2. 变量声明与初始化

在窗体类的私有区域添加变量声明:

private
  FMousePos: TPoint;       // 记录鼠标位置
  FLightRadius: Integer;   // 手电筒光圈半径

在窗体的OnCreate事件中完成初始化:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMousePos := Point(0, 0);
  FLightRadius := 100;  // 可根据需求自定义光圈大小
  DoubleBuffered := True;
end;

3. 鼠标位置跟踪

实现窗体的OnMouseMove事件,实时记录鼠标位置并触发重绘:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  FMousePos := Point(X, Y);
  Invalidate;  // 通知窗体重绘
end;

4. 绘制遮罩与光圈

在窗体的OnPaint事件中完成核心绘制逻辑:

procedure TForm1.FormPaint(Sender: TObject);
var
  Bmp: TBitmap;
  Rgn: HRGN;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.SetSize(ClientWidth, ClientHeight);
    
    // 绘制半透明黑色遮罩(前两位为透明度,CC对应80%不透明)
    Bmp.Canvas.Brush.Color := $CC000000;
    Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
    
    // 创建圆形区域作为光圈范围
    Rgn := CreateEllipticRgn(FMousePos.X - FLightRadius, FMousePos.Y - FLightRadius,
                             FMousePos.X + FLightRadius, FMousePos.Y + FLightRadius);
    try
      // 从遮罩中裁剪出圆形透明区域
      CombineRgn(Rgn, Rgn, 0, RGN_DIFF);
      Bmp.Canvas.ClipRgn := Rgn;
      Bmp.Canvas.Brush.Color := clBlack;
      Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height));
    finally
      DeleteObject(Rgn);
    end;
    
    // 将处理后的遮罩绘制到窗体
    Canvas.Draw(0, 0, Bmp);
  finally
    Bmp.Free;
  end;
end;

5. 效果优化

  • 若需要柔化光圈边缘,可以使用GradientFill函数实现渐变遮罩,让光线过渡更自然。
  • 如果窗体包含大量控件,可通过TForm.PaintTo方法先捕获窗体整体内容,再叠加遮罩层,确保所有控件都被覆盖。

内容的提问来源于stack exchange,提问作者Çağatay KAYA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:48:25