当前位置: 首页 > article >正文

C#/WinForm 自定义控件绘制章鱼

1.创建OctopusControl类,继承Control类

2.定义定时器刷新,这里我们使用System.Timers.Timer定时器,逻辑处理与UI线程分开以便减少对UI线程的负载,如下:

_timer_Elapsed事件主要用定时生成数据供UI现场绘制图像,如下:

3.重写OnPaint方法,供UI线程绘制图像,最好用DrawRectangles绘制,如下:

 

到此基本完成,但是绘制动画图像我们一般需要开启双缓冲,防止动画闪烁,增加动画流畅,如下: 

 

 全部代码:

 public class OctopusControl : Control
    {
        private readonly System.Timers.Timer _timer;
        public OctopusControl()
        {
            SetStyle(
          ControlStyles.ResizeRedraw
          | ControlStyles.DoubleBuffer
          | ControlStyles.UserPaint
          | ControlStyles.AllPaintingInWmPaint
          | ControlStyles.SupportsTransparentBackColor,
          true
          );

            this.BackColor = Color.Black;
            _timer = new System.Timers.Timer();
            _timer.Interval = 50;
            _timer.Elapsed += _timer_Elapsed;
        }
        public void Start()
        {
            _timer.Start();
        }
        public void Stop() { _timer.Stop(); }
        private double t = 0d;
        RectangleF[] doubles=new RectangleF[200*200];
        private volatile bool _isRun = false;
        private void _timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            if (_isRun) return;
            _isRun = true;
            t += Math.PI / 120;
            int j = 0;
            for (int y = 100; y < 300; y++)
            {
                for (int x = 100; x < 300; x++)
                {
                    var k = x / 8f - 25;
                    var e2 = y / 8f - 25;
                    var d = 5 * Math.Cos(Mag(k, e2) / 3);
                    var newX = (x + (d * k + k * 2 * Math.Atan(9 * Math.Cos(e2 * 2 - t / 2))) * Math.Sin(d * 2.5d - t)) / 2 + 100;
                    var newY = d * 13 + d * 3 * (3 + Math.Cos(d * 3 - t)) + d * e2 + 200;
                    doubles[j++] = new RectangleF((float)newX, (float)newY, 0.1f, 0.1f);
                }
            }
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.Smooth();
            Draw(g);
            g.Smooth(false);
        }
        private void Draw(Graphics g)
        {
            if (!_isRun) return;

            Stopwatch stopwatch = Stopwatch.StartNew();

            g.DrawRectangles(Pens.Green, doubles);
            stopwatch.Stop();
            g.DrawString($"{stopwatch.ElapsedMilliseconds}ms", this.Font, Brushes.Green, 10, 10);

            _isRun = false;
        }
        private double Mag(double x1, double y1) => Dist(0, 0, x1, y1);
        private double Dist(double x1, double y1, double x2, double y2) => Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }
    }


http://www.kler.cn/news/354014.html

相关文章:

  • 【2022工业3D异常检测文献】Patch+FPFH: 结合3D手工点云描述符和颜色特征的异常检测方法
  • xlsx xlsx-style-vite 实现前端根据element 表格导出excel且定制化样式 背景 列宽等
  • 【网络安全】-vulnhub靶场-noob
  • 顺序表的查找
  • 如何将闲置平板变为电脑显示器?GameViewer远程助你低成本实现0门槛副屏串流!
  • 基于Redis实现的延迟队列
  • MATLAB基础应用精讲-【数模应用】HLM模型
  • 20240803 芯动科技 笔试
  • 10秒钟用Midjourney画出国风味的变形金刚
  • 重塑输电线路运维管理,巡检管理系统守护电网稳定运行
  • JAVA地狱级笑话
  • linuxC读取bin文件
  • 大数据面试题整理——MapReduce
  • 传染病防控宣传系统的设计与实现小程序springboot+论文源码调试讲解
  • Java | Leetcode Java题解之第482题秘钥格式化
  • react-JSX
  • 《沈阳工业大学学报》
  • Spring Boot动态数据源切换功能详解
  • 群晖前面加了雷池社区版,安装失败,然后无法识别出用户真实访问IP
  • React中的函数组件与类组件