|
C#用户控件之流动管道
如何绘制一个动态的流动管道(FlowPipe)?
分两步绘制
主要技能:
- /// <summary>
- /// 画渐变色矩形的方法
- /// </summary>
- /// <param name="g">画布</param>
- /// <param name="brush">画刷</param>
- /// <param name="pen">笔</param>
- /// <param name="rectangle">矩形</param>
- private void PaintRectangle(Graphics g, Brush brush, Pen pen, Rectangle rectangle)
- {
- //填充矩形
- g.FillRectangle(brush, rectangle);
- switch (this.pipeStyle)
- {
- case PipeStyle.Horizontal:
- g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X + rectangle.Width, rectangle.Y);
- g.DrawLine(pen, rectangle.X, rectangle.Y + rectangle.Height - 1, rectangle.X + rectangle.Width, rectangle.Height);
- break;
- case PipeStyle.Vertical:
- g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + rectangle.Height);
- g.DrawLine(pen, rectangle.X + rectangle.Width - 1, rectangle.Y, rectangle.X + rectangle.Width - 1, rectangle.Height);
- break;
- default:
- break;
- }
- }
复制代码- /// <summary>
- /// 画渐变色半圆的方法
- /// </summary>
- /// <param name="g">画布</param>
- /// <param name="colorBlend"></param>
- /// <param name="p"></param>
- /// <param name="rect"></param>
- /// <param name="startAngle"></param>
- /// <param name="sweepAngle"></param>
- private void PaintEllipse(Graphics g, ColorBlend colorBlend, Pen p, Rectangle rect, float startAngle, float sweepAngle)
- {
- //第一步:创建GPI路径
- GraphicsPath path = new GraphicsPath();
- path.AddEllipse(rect);
- //第二步:渐变色填充
- PathGradientBrush brush = new PathGradientBrush(path);
- brush.CenterPoint = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
- brush.InterpolationColors = colorBlend;
- //第三步:绘制管道
- g.FillPie(brush, rect, startAngle, sweepAngle);
- //第四步:绘制边线
- g.DrawArc(p, rect, startAngle, sweepAngle);
- }
复制代码- //画虚线,关键用笔和路径来画
- Pen pen = new Pen(this.flowColor, this.flowWidth);
- pen.DashStyle = DashStyle.Custom;
- pen.DashPattern = new float[]
- {
- flowLength,flowLengthGap
- };
- pen.DashOffset = this.startOffset;
- g.DrawPath(pen, path);
- //流动条路径
- GraphicsPath path = new GraphicsPath();
- //虚线路径—左边、中间、右边
- switch (this.pipeTurnLeft)
- {
- case PipeTurn.Up:
- path.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) -1, this.Height, this.Height), 181.0f, -91.0f);
- break;
- case PipeTurn.Down:
- path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
- break;
- default:
- path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
- break;
- }
复制代码
- 关键理解:绘制的椭圆、线(Rectangle)理解了就好画了
path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
- 可以流动的关键要素
- //流动条流动速度(刷新速度)
- this.myTimer = new Timer();
- myTimer.Interval = 50;
- this.myTimer.Tick += MyTimer_Tick; ;
- }
- #region 定时循环
- private void MyTimer_Tick(object sender, EventArgs e)
- {
- this.startOffset = this.startOffset - this.moveSpeed;
- if (this.startOffset > this.flowLength + this.flowLengthGap || this.startOffset < (this.flowLength + this.flowLengthGap) * (-1))
- { this.startOffset = 0; }
- this.Invalidate();
- }
- #endregion
复制代码 1.定义属性
- 管道的(两端转向、样式、边沿颜色、中间颜色、激活)
- 流动条的(速度、长度、宽度、间隙、颜色)
- //属性示例:按照示例添加以上各种属性
- private float moveSpeed = 0.3f;
- [Browsable(true)]
- [Category("布局_G")]
- [Description("流动条速度,负数为反向")] //属性说明
- public float MoveSpeed
- {
- get { return moveSpeed; }
- set
- {
- this.moveSpeed = value;
- this.Invalidate(); //重绘
- }
- }
复制代码 2.画布重绘
- 【管道分为左、中、右三部分。先画管道(矩形):左、中、右;再画流动条(虚线):左、中、右】
- //矩形画刷
- LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height), pipeColorEdge, pipeColorEdge);
- linearGradientBrush.InterpolationColors = colorBlend;
- //绘制左部分
- switch (this.pipeTurnLeft)
- {
- case PipeTurn.Up:
- this.PaintEllipse(g, colorBlend, p, new Rectangle(0, this.Height * (-1)-1, this.Height * 2, this.Height * 2), 90.0f, 90.0f);
- break;
- case PipeTurn.Down:
- this.PaintEllipse(g, colorBlend, p, new Rectangle(0, 0, this.Height * 2, this.Height * 2), 180.0f, 90.0f);
- break;
- default:
- this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(-1, 0, this.Height+1, this.Height));
- break;
- }
- //绘制右部分
- switch (this.pipeTurnRight)
- {
- case PipeTurn.Up:
- this.PaintEllipse(g, colorBlend, p, new Rectangle(this.Width - this.Height * 2, this.Height * (-1)-1, this.Height * 2, this.Height * 2), 0.0f, 90.0f);
- break;
- case PipeTurn.Down:
- this.PaintEllipse(g, colorBlend, p, new Rectangle(this.Width - this.Height * 2, 0, this.Height * 2, this.Height * 2), 270.0f, 90.0f);
- break;
- default:
- this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(this.Width - this.Height, 0, this.Height, this.Height));
- break;
- }
- //绘制中间
- if (this.Width > this.Height * 2)
- {
- this.PaintRectangle(g, linearGradientBrush, p, new Rectangle(this.Height - 1, 0, this.Width - this.Height * 2 + 2, this.Height));
- }
复制代码- //流动条路径
- GraphicsPath path = new GraphicsPath();
- //虚线路径—左边
- switch (this.pipeTurnLeft)
- {
- case PipeTurn.Up:
- path.AddArc(new Rectangle(this.Height / 2, this.Height / 2 * (-1) -1, this.Height, this.Height), 181.0f, -91.0f);
- break;
- case PipeTurn.Down:
- path.AddArc(new Rectangle(this.Height / 2, this.Height / 2, this.Height, this.Height), 180.0f, 90.0f);
- break;
- default:
- path.AddLine(-1, this.Height / 2, this.Height+1, this.Height / 2);
- break;
- }
- //虚线路径—中间
- if (this.Width > this.Height * 2)
- {
- path.AddLine(this.Height, this.Height / 2, this.Width - this.Height -1, this.Height / 2);
- }
- //虚线路径—右边
- switch (this.pipeTurnRight)
- {
- case PipeTurn.Up:
- path.AddArc(new Rectangle(this.Width - 1 - this.Height * 3 / 2, -this.Height / 2-1 , this.Height, this.Height), 88f, -91.0f);
- break;
- case PipeTurn.Down:
- path.AddArc(new Rectangle(this.Width - 1 - this.Height * 3 / 2, this.Height / 2, this.Height, this.Height), 270.0f, 90.0f);
- break;
- default:
- path.AddLine(this.Width - this.Height, this.Height / 2, this.Width , this.Height / 2);
- break;
- }
- //画虚线,关键用笔和路径来
- Pen pen = new Pen(this.flowColor, this.flowWidth);
- pen.DashStyle = DashStyle.Custom;
- pen.DashPattern = new float[]
- {
- flowLength,flowLengthGap
- };
- pen.DashOffset = this.startOffset;
- g.DrawPath(pen, path);
复制代码 格式都是一样的,掌握关键代码,肝就对了。
End
来源:https://www.cnblogs.com/guoenshuo/p/18391637
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|