[110] | 1 | Imports System.Diagnostics |
---|
| 2 | Imports System.Drawing |
---|
| 3 | Imports System.Drawing.Imaging |
---|
| 4 | Imports System.Drawing.Drawing2D |
---|
| 5 | |
---|
| 6 | Public Class ProgressAnimation |
---|
| 7 | Private Const Spacing As Integer = 4 |
---|
| 8 | Private Const LeafCount As Integer = 13 |
---|
| 9 | Private Const RelativeOuterRadius As Double = 0.95 |
---|
| 10 | Private Const RelativeInnerRadius As Double = 0.2 |
---|
| 11 | Private Const RelativeInnerAngleSkew As Double = -30 * Math.PI / 180 ' 30 degrees skew |
---|
| 12 | Private Const RelativeLeafSpacing As Double = 0.2 |
---|
| 13 | Private Const UpdateInterval As Integer = 75 ' 75 milliseconds |
---|
| 14 | Private Const Period As Integer = 13000 ' 13 seconds |
---|
| 15 | Private ForegroundColor As Color = Color.MidnightBlue |
---|
| 16 | Private WithEvents UpdateTimer As Timer |
---|
| 17 | Private AnchorTickCount As Integer |
---|
| 18 | |
---|
| 19 | Private Sub ProgressAnimation_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load |
---|
| 20 | DoubleBuffered = True |
---|
| 21 | End Sub |
---|
| 22 | Private Sub ProgressAnimation_VisibleChanged(sender As Object, e As System.EventArgs) Handles Me.VisibleChanged |
---|
| 23 | If Visible Then |
---|
| 24 | UpdateTimer = New Timer |
---|
| 25 | UpdateTimer.Interval = UpdateInterval |
---|
| 26 | UpdateTimer.Start() |
---|
| 27 | AnchorTickCount = Environment.TickCount |
---|
| 28 | Invalidate() |
---|
| 29 | Else |
---|
| 30 | If UpdateTimer IsNot Nothing Then UpdateTimer.Stop() |
---|
| 31 | UpdateTimer = Nothing |
---|
| 32 | End If |
---|
| 33 | End Sub |
---|
| 34 | Private Sub ProgressAnimation_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint |
---|
| 35 | Dim Span As Integer = Math.Min(Width, Height) / 2 - Spacing |
---|
| 36 | If Span <= 0 Then Exit Sub |
---|
| 37 | Dim Origin As SizeF = New SizeF(Width / 2, Height / 2) |
---|
| 38 | Dim OutlinePen As Pen = New Pen(ForegroundColor, 1) |
---|
| 39 | e.Graphics.SmoothingMode = SmoothingMode.AntiAlias |
---|
| 40 | For LeafIndex As Integer = 0 To LeafCount - 1 |
---|
| 41 | Dim Position As Double = ((Environment.TickCount - AnchorTickCount) Mod Period) / Period + 0.55 |
---|
| 42 | Position += 1.0 * LeafIndex / LeafCount |
---|
| 43 | While Position > 1 |
---|
| 44 | Position -= 1 |
---|
| 45 | End While |
---|
| 46 | Debug.Assert(Position >= 0 AndAlso Position <= 1) |
---|
| 47 | Dim FillBrush As Brush = New SolidBrush(Color.FromArgb(31 + 224 * Math.Exp(-1.5 * Position), ForegroundColor)) |
---|
| 48 | Dim AngleA As Double = 2 * Math.PI * LeafIndex / LeafCount |
---|
| 49 | Dim AngleC As Double = 2 * Math.PI * (LeafIndex + 1) / LeafCount |
---|
| 50 | Dim AngleB As Double = AngleA * (RelativeLeafSpacing) + AngleC * (1 - RelativeLeafSpacing) |
---|
| 51 | Dim PointA1 As PointF = New PointF(Math.Sin(AngleA) * Span * RelativeOuterRadius, Math.Cos(AngleA) * Span * RelativeOuterRadius) |
---|
| 52 | Dim PointA2 As PointF = New PointF(Math.Sin(AngleA + RelativeInnerAngleSkew) * Span * RelativeInnerRadius, Math.Cos(AngleA + RelativeInnerAngleSkew) * Span * RelativeInnerRadius) |
---|
| 53 | Dim PointB1 As PointF = New PointF(Math.Sin(AngleB) * Span * RelativeOuterRadius, Math.Cos(AngleB) * Span * RelativeOuterRadius) |
---|
| 54 | Dim PointB2 As PointF = New PointF(Math.Sin(AngleB + RelativeInnerAngleSkew) * Span * RelativeInnerRadius, Math.Cos(AngleB + RelativeInnerAngleSkew) * Span * RelativeInnerRadius) |
---|
| 55 | Dim AngleD As Double = (AngleA + AngleB) / 2 |
---|
| 56 | Dim PointD1 As PointF = New PointF(Math.Sin(AngleD) * Span * RelativeOuterRadius, Math.Cos(AngleD) * Span * RelativeOuterRadius) |
---|
| 57 | Dim PointD2 As PointF = New PointF(Math.Sin(AngleD + RelativeInnerAngleSkew) * Span * RelativeInnerRadius, Math.Cos(AngleD + RelativeInnerAngleSkew) * Span * RelativeInnerRadius) |
---|
| 58 | Dim Path As GraphicsPath = New GraphicsPath |
---|
| 59 | Path.AddLine(PointA1 + Origin, PointA2 + Origin) |
---|
| 60 | Path.AddCurve(New PointF() {PointA2 + Origin, PointD2 + Origin, PointB2 + Origin}) |
---|
| 61 | Path.AddLine(PointB1 + Origin, PointB1 + Origin) |
---|
| 62 | Path.AddCurve(New PointF() {PointB1 + Origin, PointD1 + Origin, PointA1 + Origin}) |
---|
| 63 | e.Graphics.FillPath(FillBrush, Path) |
---|
| 64 | If Span >= 200 Then e.Graphics.DrawPath(OutlinePen, Path) |
---|
| 65 | Next |
---|
| 66 | End Sub |
---|
| 67 | Private Sub UpdateTimer_Tick(sender As Object, e As System.EventArgs) Handles UpdateTimer.Tick |
---|
| 68 | Invalidate() |
---|
| 69 | End Sub |
---|
| 70 | End Class |
---|