using JinYuan.ControlLib.UCHelper; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace JinYuan.ControlLib { public partial class Wave : Control { /// /// Occurs when [on painted]. /// public event PaintEventHandler OnPainted; /// /// The m wave color /// private Color m_waveColor = Color.FromArgb(255, 77, 59); /// /// Gets or sets the color of the wave. /// /// The color of the wave. [Description("波纹颜色"), Category("自定义")] public Color WaveColor { get { return m_waveColor; } set { m_waveColor = value; this.Invalidate(); } } /// /// The m wave width /// private int m_waveWidth = 200; /// /// 为方便计算,强制使用10的倍数 /// /// The width of the wave. [Description("波纹宽度(为方便计算,强制使用10的倍数)"), Category("自定义")] public int WaveWidth { get { return m_waveWidth; } set { m_waveWidth = value; m_waveWidth = m_waveWidth / 10 * 10; intLeftX = value * -1; this.Invalidate(); } } /// /// The m wave height /// private int m_waveHeight = 30; /// /// 波高 /// /// The height of the wave. [Description("波高"), Category("自定义")] public int WaveHeight { get { return m_waveHeight; } set { m_waveHeight = value; this.Invalidate(); } } /// /// The m wave sleep /// private int m_waveSleep = 50; /// /// 波运行速度(运行时间间隔,毫秒) /// /// The wave sleep. [Description("波运行速度(运行时间间隔,毫秒)"), Category("自定义")] public int WaveSleep { get { return m_waveSleep; } set { if (value <= 0) return; m_waveSleep = value; if (timer != null) { timer.Enabled = false; timer.Interval = value; timer.Enabled = true; } } } private int m_bubbleSpeed = 0; /// /// 气泡速度(0表示不启用) /// /// The wave sleep. [Description("气泡速度(0表示不启用)"), Category("自定义")] public int BubbleSpeed { get { return m_bubbleSpeed; } set { m_bubbleSpeed = value; this.Invalidate(); } } private int m_bubbleIntervalTime = 500; /// /// 气泡生成间隔时间(毫秒,不准确,根据波运行速度判断) /// /// The wave sleep. [Description("气泡生成间隔时间(毫秒,不准确,根据波运行速度判断)"), Category("自定义")] public int BubbleIntervalTime { get { return m_bubbleIntervalTime; } set { m_bubbleIntervalTime = value; this.Invalidate(); } } /// /// 上次生成气泡的时间 /// private int lastBubbleTime = 0; /// /// 气泡列表 /// private List m_lstBubble = new List(); /// /// The timer /// Timer timer = new Timer(); /// /// The int left x /// int intLeftX = -200; /// /// Initializes a new instance of the class. /// public Wave() { this.Size = new Size(600, 100); ////设置控件样式,去除缓冲 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); timer.Interval = m_waveSleep; timer.Tick += timer_Tick; this.VisibleChanged += UCWave_VisibleChanged; } #region 减少闪烁 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } #endregion /// /// Handles the VisibleChanged event of the UCWave control. /// /// The source of the event. /// The instance containing the event data. void UCWave_VisibleChanged(object sender, EventArgs e) { timer.Enabled = this.Visible; } /// /// Handles the Tick event of the timer control. /// /// The source of the event. /// The instance containing the event data. void timer_Tick(object sender, EventArgs e) { intLeftX -= 10; if (intLeftX == m_waveWidth * -2) intLeftX = m_waveWidth * -1; if (m_bubbleSpeed > 0) { lastBubbleTime += m_waveSleep; if (lastBubbleTime >= m_bubbleIntervalTime) { lastBubbleTime = 0; var r = new Random(DateTime.Now.Millisecond); var b_x = r.Next(0, this.Width); var b = new Bubble(); b.Key = Guid.NewGuid().ToString(); b.BubblePoint = new Point(b_x, 0); b.BubbleWidth = 5; m_lstBubble.Add(b); } } else { m_lstBubble.Clear(); } this.Invalidate(); } /// /// Handles the event. /// /// The instance containing the event data. protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); var g = e.Graphics; g.SetGDIHigh(); List lst1 = new List(); List lst2 = new List(); int m_intX = intLeftX; while (true) { lst1.Add(new Point(m_intX, 1)); lst1.Add(new Point(m_intX + m_waveWidth / 2, m_waveHeight)); lst2.Add(new Point(m_intX + m_waveWidth / 2, 1)); lst2.Add(new Point(m_intX + m_waveWidth / 2 + m_waveWidth / 2, m_waveHeight)); m_intX += m_waveWidth; if (m_intX > this.Width + m_waveWidth) break; } GraphicsPath path1 = new GraphicsPath(); path1.AddCurve(lst1.ToArray(), 0.5F); path1.AddLine(this.Width + 1, -1, this.Width + 1, this.Height); path1.AddLine(this.Width + 1, this.Height, -1, this.Height); path1.AddLine(-1, this.Height, -1, -1); GraphicsPath path2 = new GraphicsPath(); path2.AddCurve(lst2.ToArray(), 0.5F); path2.AddLine(this.Width + 1, -1, this.Width + 1, this.Height); path2.AddLine(this.Width + 1, this.Height, -1, this.Height); path2.AddLine(-1, this.Height, -1, -1); g.FillPath(new SolidBrush(Color.FromArgb(220, m_waveColor.R, m_waveColor.G, m_waveColor.B)), path1); g.FillPath(new SolidBrush(Color.FromArgb(220, m_waveColor.R, m_waveColor.G, m_waveColor.B)), path2); //气泡 foreach (var item in m_lstBubble) { GraphicsPath gp = new GraphicsPath(); Rectangle rec = new Rectangle(item.BubblePoint.X - item.BubbleWidth / 2, this.Height - (item.BubblePoint.Y - item.BubbleWidth / 2), item.BubbleWidth / 3 * 2, item.BubbleWidth / 3 * 2); gp.AddEllipse(rec); Color[] surroundColor = new Color[] { Color.FromArgb(50, Color.White) }; PathGradientBrush pb = new PathGradientBrush(gp); pb.CenterColor = Color.FromArgb(150, Color.White); pb.SurroundColors = surroundColor; g.FillPath(pb, gp); item.BubblePoint = new Point(item.BubblePoint.X, item.BubblePoint.Y + m_bubbleSpeed); item.BubbleWidth += 1; } if (OnPainted != null) { OnPainted(this, e); } } internal class Bubble { internal string Key { get; set; } /// /// 坐标 /// internal Point BubblePoint { get; set; } /// /// 宽度 /// internal int BubbleWidth { get; set; } } } }