Public Class Form1

    ' Wskazuje, czy animacja jest obecnie pokazywana
    Private IsAnimating As Boolean = False

    ' Śledzi czas trwania animacji
    Private StartTime As DateTime

    Private Sub Form_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

        ' Sprawdzamy, czy animacja jest pokazywana
        If IsAnimating Then

            ' Przygotowujemy się do narysowania bieżącej ramki
            Dim g As Graphics = e.Graphics
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality

            ' Rysujemy tło
            Dim BackBrush As New System.Drawing.Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(100, 100), Color.Blue, Color.LightBlue)
            g.FillRectangle(BackBrush, New Rectangle(New Point(0, 0), Me.ClientSize))
            g.FillRectangle(Brushes.LightPink, New Rectangle(New Point(10, 10), New Point(Me.Width - 30, Me.Height - 50)))

            ' Obliczamy miniony czas
            Dim Elapsed As Double = DateTime.Now.Subtract(StartTime).TotalSeconds

            Dim CurrentPosition As Double = (-100 + 24 * Elapsed ^ 2) / 10

            ' Rysujemy kilka ruchomych obiektów
            Dim Pen As New Pen(Color.Blue, 10)
            Dim Brush As Brush = Brushes.Chartreuse
            g.DrawEllipse(Pen, CInt(Elapsed * 100), CInt(CurrentPosition), 10, 10)
            g.FillEllipse(Brush, CInt(Elapsed * 100), CInt(CurrentPosition), 10, 10)

            g.DrawEllipse(Pen, CInt(Elapsed * 50), CInt(CurrentPosition), 10, 10)
            g.FillEllipse(Brush, CInt(Elapsed * 50), CInt(CurrentPosition), 10, 10)

            g.DrawEllipse(Pen, CInt(Elapsed * 76), CInt(CurrentPosition) * 2, 10, 10)
            g.FillEllipse(Brush, CInt(Elapsed * 55), CInt(CurrentPosition) * 3, 10, 10)

            g.DrawEllipse(Pen, CInt(Elapsed * 66), CInt(CurrentPosition) * 4, 10, 10)
            g.FillEllipse(Brush, CInt(Elapsed * 72), CInt(CurrentPosition) * 3, 10, 10)

            If Elapsed > 10 Then
                ' Zatrzymujemy animację
                tmrInvalidate.Stop()
                IsAnimating = False
            End If

        Else
            ' Animacja jest zatrzymana. Rysujemy tło
            MyBase.OnPaintBackground(e)
        End If

    End Sub


    Private Sub tmrInvalidate_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrInvalidate.Tick
        ' Unieważniamy formularz, co powoduje odświeżenie
        Me.Invalidate()
    End Sub

    Private Sub cmdStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStart.Click
        ' Uruchamiamy zegar, który będzie regularnie wyzwalał
        ' proces odświeżania
        Me.DoubleBuffered = True
        Start()
    End Sub

    Private Sub Start()
        IsAnimating = True
        StartTime = DateTime.Now
        tmrInvalidate.Start()
    End Sub


    Private Sub cmdStartNoBuffer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStartNoBuffer.Click
        Me.DoubleBuffered = False
        Start()
    End Sub



    ' Wyłączamy automatyczne przerysowywanie okna po unieważnieniu
    ' formularza. Nie jest to konieczne, ponieważ formularz będzie
    ' przerysowywany przez procedu obsługi zdarzenia Paint. Jeśli jednak
    ' nie przesłonimy tej metody, przy każdym odświeżeniu formularza
    ' okno będzie wymazywane i wypełniane kolorem tła, co powoduje
    ' dodatkowe migotanie.
    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        ' Nie robimy niczego
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

End Class
