using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
namespace WindowsFormsApplication12
{
class Loading : Control
{
const double k3 = 1.7320508075688772935274463415059;//根号3
const int w = 12;//边框条形宽
const int a1 = 40;
const int a2 = 40;
int a3 = 26;
int h3 = 0;
const double b = 0.8f;
int ox = 0;
int oy = 0;
int ix = 0;
int iy = 0;
Color LineColor,inColor;
bool isShowLine = false;
//int cx = 0;
//int cy = 0;
/// <summary>
/// 数据加载动画控件
/// </summary>
/// <param name="parent">父窗口</param>
/// <param name="startPoint">开始位置</param>
/// <param name="LineColor">外边框颜色</param>
/// <param name="inColor">内沙子颜色</param>
/// <param name="inColor">是否显示沙漏线</param>
public Loading(Control parent, Point startPoint, Color LineColor, Color inColor, bool isShowLine)
{
this.Parent = parent;
this.Location = startPoint;
this.Size = new Size(115, 115);
this.LineColor = LineColor;
this.inColor = inColor;
this.isShowLine = isShowLine;
//防止闪屏
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true);
//cx = mul(w, k3 / 2.0);
//cy = w / 2;
ox = mul(a1, 1.0 / 2.0 * b);
oy = mul(a1, k3 / 2.0 * b);
ix = mul(a2, 1.0 / 2.0 * b);
iy = mul(a2, k3 / 2.0 * b);
a3 = a2 - 3 * (a2 / 2 - ix);
h3 = mul(a3, k3 / 2.0);
//Thread t = new Thread(new ThreadStart(thread));
//t.Start();
}
/// <summary>
/// 数据加载动画控件(使用默认的版本)
/// </summary>
/// <param name="parent">父窗口</param>
/// <param name="startPoint">开始位置</param>
/// <param name="inColor">是否显示沙漏线</param>
public Loading(Control parent, Point startPoint, bool isShowLine)
{
this.Parent = parent;
this.Location = startPoint;
this.Size = new Size(115, 115);
this.LineColor = Color.BlueViolet;
this.inColor = Color.FromArgb(46, 161, 239);
this.isShowLine = isShowLine;
//防止闪屏
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true);
//cx = mul(w, k3 / 2.0);
//cy = w / 2;
ox = mul(a1, 1.0 / 2.0 * b);
oy = mul(a1, k3 / 2.0 * b);
ix = mul(a2, 1.0 / 2.0 * b);
iy = mul(a2, k3 / 2.0 * b);
a3 = a2 - 3 * (a2 / 2 - ix);
h3 = mul(a3, k3 / 2.0);
//Thread t = new Thread(new ThreadStart(thread));
//t.Start();
}
object locker = new object();
bool isLoading = false;
public void start()
{
lock (locker)
{
if (isLoading) return;
isLoading = true;
an = 0;
process = 0f;
up = true;
Thread t = new Thread(new ThreadStart(thread));
t.Start();
}
}
public void stop()
{
lock (locker)
{
isLoading = false;
}
}
float an = 0;
float process = 0f;
bool up = true;
private void thread()
{
while (true && isLoading)
{
process += 0.1f;
this.Invoke(new Action(() => { ro(); }), null);
Thread.Sleep(100);
if (process >= 1.0f)
{
float end = 180f;
if (an >= 180f)
end = 360f;
while (an <= end && isLoading)
{
an += 30f;
this.Invoke(new Action(() => { ro(); }), null);
Thread.Sleep(100);
}
if (end >= 360f)
an = 0f;
an = 180f;
process = 0f;
up = false;
}
}
}
Point RoatePoint = new Point();
Bitmap bm = null;
private void ro()
{
if (bm != null)
bm.Dispose();
bm = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(bm);
g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿
int mx = 0;
int my = 0;
GraphicsPath path_out = getPathOut(20, 20, ref mx, ref my);
Brush brush_out = new SolidBrush(Color.BlueViolet);
GraphicsPath path_int = getPathInt(mx + 3, my);
Brush brush_int = new SolidBrush(Color.White);
Matrix m = new Matrix();
m.RotateAt(an, new Point(mx + 3, my));
path_out.Transform(m);
path_int.Transform(m);
g.FillPath(brush_out, path_out);
g.FillPath(brush_int, path_int);
GraphicsPath path_Triangle1 = getTriangle(new Point(mx + 3, my), up, 1f - process);
Brush brush_Triangle = new SolidBrush(Color.FromArgb(46, 161, 239));
path_Triangle1.Transform(m);
g.FillPath(brush_Triangle, path_Triangle1);
GraphicsPath path_Triangle2 = getTriangle(new Point(mx + 3, my), !up, 1f);
path_Triangle2.Transform(m);
g.FillPath(brush_Triangle, path_Triangle2);
GraphicsPath path_Triangle3 = getTriangle(new Point(mx + 3, my), !up, 1f - process);
SolidBrush white_brush = new SolidBrush(Color.White);
path_Triangle3.Transform(m);
g.FillPath(white_brush, path_Triangle3);
if ((an == 0f || an == 180f) && isShowLine)
{
Pen p = new Pen(brush_Triangle);
g.DrawLine(p, new Point(mx + 3, my), new Point(mx + 3, my + h3 - 2));
p.Dispose();
}
path_out.Dispose();
path_int.Dispose();
path_Triangle1.Dispose();
path_Triangle2.Dispose();
path_Triangle3.Dispose();
brush_out.Dispose();
brush_int.Dispose();
brush_Triangle.Dispose();
white_brush.Dispose();
this.BackgroundImage = bm;
}
private GraphicsPath getPathOut(int x,int y,ref int mx, ref int my)
{
Point pL = new Point(0, 0);
Point pR = new Point(0, 0);
float y2 = 0;
GraphicsPath path = new GraphicsPath();
path.AddArc(new Rectangle(x, y, w, w), 150f, 120f);//120f
PointF p1 = path.GetLastPoint();
PointF p2 = new PointF(p1.X + a1, p1.Y);
path.AddLine(p1, p2);
y2 = p1.Y;
mx = (int)p1.X + a1 / 2;
pR = new Point((int)p2.X, (int)p2.Y + 1);
path.AddArc(new Rectangle(pR, new Size(w,w)), 270f, 120f);
p1 = path.GetLastPoint();
p2 = new PointF(p1.X - ox, p1.Y + oy);
path.AddLine(p1, p2);
y2 = y2 + 2 * (p2.Y - y2);
my = (int)p2.Y;
p1 = new PointF(p2.X + ox, p2.Y + oy);
path.AddLine(p2, p1);
path.AddArc(new Rectangle(pR.X, (int)y2 - w, w, w), 330f, 90f);
p1 = path.GetLastPoint();
p2 = new PointF(p1.X - a1, p1.Y);
path.AddLine(p1, p2);
path.AddArc(new Rectangle(x, (int)y2 - w - 1, w, w), 90f, 120f);
p1 = path.GetLastPoint();
p2 = new PointF(p1.X + ox, p1.Y - oy);
path.AddLine(p1, p2);
return path;
}
private GraphicsPath getPathInt(int mx, int my)
{
GraphicsPath path = new GraphicsPath();
int y = my - iy;
int x = mx - a2 / 2;
Point p1 = new Point(x, y);
x += a2;
Point p2 = new Point(x, y);
path.AddLine(p1, p2);
x -= ix;
y += iy;
p1 = p2;
p2 = new Point(x, y);
path.AddLine(p1, p2);
RoatePoint = p2;
x += ix;
y += iy;
p1 = p2;
p2 = new Point(x, y);
path.AddLine(p1, p2);
x -= a2;
p1 = p2;
p2 = new Point(x, y);
path.AddLine(p1, p2);
x += ix;
y -= iy;
p1 = p2;
p2 = new Point(x, y);
path.AddLine(p1, p2);
RoatePoint.Y = RoatePoint.Y - (RoatePoint.Y - p2.Y) / 2;
return path;
}
private GraphicsPath getTriangle(Point m,bool isUp, float process)
{
int h = (int)((float)h3 * process);
int a = (int)((float)a3 * process);
GraphicsPath path = new GraphicsPath();
Point p1 = new Point(m.X + a / 2, m.Y - h);
Point p2 = new Point(m.X - a / 2, m.Y - h);
if (isUp == false)
{
p1 = PointRotate(m, p1, 180f);
p2 = PointRotate(m, p2, 180f);
}
path.AddLine(m, p1);
path.AddLine(p1, p2);
return path;
}
/// <summary>
/// 对一个坐标点按照一个中心进行旋转
/// </summary>
/// <param name="center">中心点</param>
/// <param name="p1">要旋转的点</param>
/// <param name="angle">旋转角度,笛卡尔直角坐标</param>
/// <returns></returns>
private Point PointRotate(Point center, Point p1, double angle)
{
Point tmp = new Point();
double angleHude = angle * Math.PI / 180;/*角度变成弧度*/
double x1 = (p1.X - center.X) * Math.Cos(angleHude) + (p1.Y - center.Y) * Math.Sin(angleHude) + center.X;
double y1 = -(p1.X - center.X) * Math.Sin(angleHude) + (p1.Y - center.Y) * Math.Cos(angleHude) + center.Y;
tmp.X = (int)x1;
tmp.Y = (int)y1;
return tmp;
}
private int mul(int a, double b)
{
double c = (double)a * b;
return (int)c;
}
}
}
上面是控件的封装,要看完整例子,请下载工程文件(感觉好用要给顶一下哦!)