SurLoading.cs 6.1 KB
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Asa.Face
{
    /// <summary>
    /// 加载时的环形动画
    /// </summary>
    public partial class SurLoading : BaseCtl
    {
        private int _index = -1;
        private PointF _center;           //大圆中心
        private int _circleRadius = 30;   //大圆半径
        private int _ringDiam = 10;       //小圆直径
        private int _count = 12;          //小圆个数
        private RectangleF[] _ringRect;   //小圆大小
        private System.Threading.Thread tRing;


        /// <summary>
        /// 加载时的环形动画
        /// </summary>
        public SurLoading()
        {
            InitializeComponent();
        }


        //==========属性==========
        /// <summary>
        /// 是否在转动
        /// </summary>
        [Browsable(false)]
        public bool IsRun { get; set; }

        /// <summary>
        /// 转动的速度
        /// </summary>
        [Browsable(true), Category(""), Description("转动的速度"), DefaultValue(200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int Speed { set; get; } = 200;

        /// <summary>
        /// 小圈圈的个数,3-100个
        /// </summary>
        [Browsable(true), Category(""), Description("小圈圈的个数,3-100个"), DefaultValue(12)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int RingCount
        {
            set
            {
                _count = value;
                if (_count < 3)
                    _count = 3;
                else if (_count > 100)
                    _count = 100;
                CalcSize();
                Refresh();
            }
            get
            {
                return _count;
            }
        }

        /// <summary>
        /// 小圈圈的半径
        /// </summary>
        [Browsable(true), Category(""), Description("小圈圈的半径"), DefaultValue(10)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int RingDiameter
        {
            set
            {
                _ringDiam = value;
                if (_ringDiam < 2)
                    _ringDiam = 2;
                CalcSize();
                Refresh();
            }
            get
            {
                return _ringDiam;
            }
        }

        /// <summary>
        /// 半径
        /// </summary>
        [Browsable(true), Category(""), Description("大圆形的半径"), DefaultValue(30)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int CircleRadius
        {
            set
            {
                _circleRadius = value;
                CalcSize();
                Refresh();
            }
            get
            {
                return _circleRadius;
            }
        }

        /// <summary>
        /// 开始转动
        /// </summary>
        [Browsable(false)]
        public void Start()
        {
            _index = 0;
            tRing = new System.Threading.Thread(new System.Threading.ThreadStart(Process));
            tRing.Start();
            IsRun = true;
        }

        /// <summary>
        /// 停止转动
        /// </summary>
        [Browsable(false)]
        public void Stop()
        {
            IsRun = false;
            _index = -1;
            if (tRing != null)
            {
                tRing.Abort();
                tRing = null;
            }
            Refresh();
        }


        //==========私有==========
        /// <summary>
        /// 计算大小
        /// </summary>
        protected override void CalcSize()
        {
            base.CalcSize();

            _center = new PointF(Width / 2f, Height / 2f);
            //_radius = Math.Min(_center.X, _center.Y) / 2f;
            _ringRect = new RectangleF[_count];
            float angle = 360f / _count;

            for (int i = 0; i < _ringRect.Length; i++)
            {
                double radian = (i * angle) * Math.PI / 180;
                float x = Convert.ToSingle(Math.Cos(radian) * _circleRadius);
                float y = Convert.ToSingle(Math.Sin(radian) * _circleRadius);
                PointF pt = new PointF(_center.X + x, _center.Y + y);
                _ringRect[i] = new RectangleF(pt.X - _ringDiam / 2f, pt.Y - _ringDiam / 2f, _ringDiam, _ringDiam);
            }

        }

        private void FlatLoadingRing_Paint(object sender, PaintEventArgs e)
        {
            BufferedGraphicsContext current = BufferedGraphicsManager.Current;
            BufferedGraphics bg = current.Allocate(e.Graphics, e.ClipRectangle);
            Graphics g = bg.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.Clear(Common.BACK_COLOR);  //背景

            if (Inside)
            {
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderInsidePen, BorderRect);
            }
            else
            {
                if (BorderWidth > 0)
                    g.DrawRectangle(BorderOutsidePen, BorderRect);
            }

            for (int i = 0; i < _ringRect.Length; i++)
            {
                if (i == _index)
                    g.FillEllipse(Common.BLUE_BRUSH, _ringRect[i]);
                else
                    g.DrawEllipse(Common.FORE_PEN, _ringRect[i]);
            }

            bg.Render();
            bg.Dispose();
        }

        private void Process()
        {
            while (true)
            {
                Invoke(new Action(() => { Refresh(); }));

                _index++;
                if (_index == _ringRect.Length) _index = 0;
                System.Threading.Thread.Sleep(Speed);
            }
        }


    }
}