C#实现聚光灯效果

根据项目要求,需要做一个聚光灯的功能!实现某一部分区域是看的见的,其他区域是被遮挡的!高亮区域的大小可变,位置可变!

做个记录,思路是这样的,添加一个窗体作为聚光灯窗体,将该窗体最大化,背景色设置为黑色,设置其透明度为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();
        }
    }

 

你可能感兴趣的:(C#)