根据项目要求,需要做一个聚光灯的功能!实现某一部分区域是看的见的,其他区域是被遮挡的!高亮区域的大小可变,位置可变!
做个记录,思路是这样的,添加一个窗体作为聚光灯窗体,将该窗体最大化,背景色设置为黑色,设置其透明度为0.5(这个随意,达到效果就行),这样可以起到半透明变暗的效果!然后我们再设置下窗体的透明色(不要设置为黑色,如果设置为黑色,窗体就全透明了,并且鼠标可以穿透过去),比如Color.FromArgb(255, 255, 254)!最后再将我们需要高亮的区域用透明色填充就可以了!其他的就是一些事件处理的代码了!
关键代码如下:
public partial class LampForm : Form
{
public LampForm()
{
InitializeComponent();
}
private Rectangle inRect = new Rectangle();
private Rectangle outRect = new Rectangle();
private int inDia = 100;
private int outDia = 120;
private Point inCenter = new Point();
private Point outCenter = new Point();
private bool moveFlag = false;
private Point startP = new Point();
private Point endP = new Point();
private void LampForm_Load(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 0, 0);
this.Opacity = 0.5;
this.WindowState = FormWindowState.Maximized;
this.TransparencyKey = Color.FromArgb(255, 255, 254);
inRect = new Rectangle(20, 20, 200, 200);
outRect = new Rectangle(0, 0, 240, 240);
inCenter = new Point(120, 120);
outCenter = new Point(120, 120);
pictureBox1.Size = pictureBox1.Image.Size;
pictureBox1.Location = new Point(this.Width - pictureBox1.Image.Width, this.Height - pictureBox1.Image.Height);
}
Graphics g = null;
protected override void OnPaint(PaintEventArgs e)
{
g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
if (moveFlag == true)
{
int tempOutDia = (int)Math.Sqrt(Math.Abs(endP.X - inCenter.X) * Math.Abs(endP.X - inCenter.X) + Math.Abs(endP.Y - inCenter.Y) * Math.Abs(endP.Y - inCenter.Y));
int tempIndia = tempOutDia - 20;
Rectangle tempinRect = new Rectangle(inCenter.X - tempIndia, inCenter.Y - tempIndia, tempIndia * 2, tempIndia * 2);
Rectangle tempoutRect = new Rectangle(outCenter.X - tempOutDia, outCenter.Y - tempOutDia, tempOutDia * 2, tempOutDia * 2);
g.FillEllipse(new SolidBrush(Color.Yellow), tempoutRect);
g.FillEllipse(new SolidBrush(Color.FromArgb(255, 255, 254)), tempinRect);
}
else
{
inRect = new Rectangle(inCenter.X - inDia, inCenter.Y - inDia, inDia * 2, inDia * 2);
outRect = new Rectangle(outCenter.X - outDia, outCenter.Y - outDia, outDia * 2, outDia * 2);
g.FillEllipse(new SolidBrush(Color.Yellow), outRect);
g.FillEllipse(new SolidBrush(Color.FromArgb(255, 255, 254)), inRect);
}
}
private void LampForm_MouseClick(object sender, MouseEventArgs e)
{
if (moveFlag == false)
{
inCenter = new Point(e.X, e.Y);
outCenter = new Point(e.X, e.Y);
this.Invalidate();
}
}
private void LampForm_MouseMove(object sender, MouseEventArgs e)
{
//判断点是否在黄色区域内
Point temp = new Point(e.X, e.Y);
if (IsPointInCircle(temp, inCenter, inDia) == false && IsPointInCircle(temp, outCenter, outDia) == true)
this.Cursor = Cursors.Cross;
else
this.Cursor = Cursors.Arrow;
if (moveFlag == true)
endP = new Point(e.X, e.Y);
this.Invalidate();
}
private void LampForm_MouseDown(object sender, MouseEventArgs e)
{
//判断点是否在黄色区域内
Point temp = new Point(e.X, e.Y);
if (IsPointInCircle(temp, inCenter, inDia) == false && IsPointInCircle(temp, outCenter, outDia) == true)
{
moveFlag = true;
startP = temp;
}
}
private void LampForm_MouseUp(object sender, MouseEventArgs e)
{
if (moveFlag == true)
{
outDia = (int)Math.Sqrt(Math.Abs(endP.X - inCenter.X) * Math.Abs(endP.X - inCenter.X) + Math.Abs(endP.Y - inCenter.Y) * Math.Abs(endP.Y - inCenter.Y));
inDia = outDia - 20;
}
moveFlag = false;
}
private bool IsPointInCircle(Point p, Point center, int dia)
{
//到圆心的距离 是否大于半径。半径是R
//如O(x,y)点圆心,任意一点P(x1,y1) (x-x1)*(x-x1)+(y-y1)*(y-y1)>R*R 那么在圆外 反之在圆内
int x = center.X;
int y = center.Y;
int r = dia;
int x1 = p.X;
int y1 = p.Y;
if (!((x - x1) * (x - x1) + (y - y1) * (y - y1) > r * r))
{
return true; //当前点在圆内
}
else
{
return false; //当前点在圆外
}
}
private void pictureBox1_Click(object sender, EventArgs e)
{
this.Close();
}
}