Quantcast
Channel: VBForums - Visual Basic .NET
Viewing all articles
Browse latest Browse all 27554

VS 2010 PictureBox Transparency for Animation

$
0
0
Hi,

I'm writing a little program at the moment and I'm trying to animate the buttons so that they spin when I click them.

Now I've managed to do this using screenshots, a PictureBox and a Timer, but the PictureBox has an Opaque background so it covers other controls when it runs.

Can anyone tell me how to change the PictureBox so it has a transparent background? By this I meant transparent in a way that allows you to put the PictureBox in front of a button but still see the button.

Also, I'm guessing that since my screenshot is a Bitmap, that would not be transparent so it would also cover the other controls with a grey background.

The code I currently have is below, to implement this, create a form with 4 buttons (Button1, Button2, Button3 and Button4) and then add the code onto the form.
When you click the buttons, they will spin, but if they are too close to another, it will obscure the other buttons.

Code:

Public Class Form1
    Dim bmpScreenGrab(999) As Bitmap
    Dim gScreenGrab(999) As System.Drawing.Graphics
    Dim intCurAngle(999) As Integer
    Dim intAngleChange(999) As Integer
    Dim ctrlCtrl(999) As Control
    Dim intNewMax As Integer = -1

    Private Sub Button_Click(sender As Object, e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click
        SpinIt(sender, 1, 10)
    End Sub

    Private Sub SpinIt(Ctrl As Control, Optional intDelay As Integer = 1, Optional intAngle As Integer = 1)
        Dim pntOrig As Point = Ctrl.Location
        Dim blnOrigVis As Boolean = Ctrl.Visible
        Dim TmpBMP As Bitmap

        intNewMax += 1

        intAngleChange(intNewMax) = intAngle

        ' Move Ctrl to 0,0 and make sure visible so a screenshot can be taken
        Ctrl.Location = New Point(0, 0)
        Ctrl.Visible = True

        ' Create new bitmap
        TmpBMP = New Bitmap(Ctrl.Width, Ctrl.Height)

        bmpScreenGrab(intNewMax) = TmpBMP

        Me.Refresh()

        ' Get screenshot
        gScreenGrab(intNewMax) = System.Drawing.Graphics.FromImage(bmpScreenGrab(intNewMax))

        gScreenGrab(intNewMax).CopyFromScreen(Ctrl.PointToScreen(New Point(0, 0)), New Point(0, 0), New Size(Ctrl.Width, Ctrl.Height), CopyPixelOperation.SourceCopy)

        ' Move Ctrl back to original location and set visibility to original visibility
        Ctrl.Location = pntOrig
        Ctrl.Visible = blnOrigVis

        Me.Refresh()

        ' Set Tag as intNewMax so it has some sort of identifier for the later code
        Ctrl.Tag = intNewMax

        ' Set the Ctrl's current angle to 0 as it hasn't yet moved
        intCurAngle(intNewMax) = 0

        ' Create new PictureBox for the bmpScreenGrab
        Dim NewPB As New PictureBox

        With NewPB
            ' So none of the graphics are missing we need to set the Height and Width to the same value
            ' the value needs to be the higher value of the Ctrl's height or width.
            ' Since the height or width may be changed, we also need to offset the PictureBox by half the difference
            If bmpScreenGrab(intNewMax).Width > bmpScreenGrab(intNewMax).Height Then
                .Size = New Size(bmpScreenGrab(intNewMax).Width, bmpScreenGrab(intNewMax).Width)
                .Left = Ctrl.Left
                .Top = Ctrl.Top - ((bmpScreenGrab(intNewMax).Width - bmpScreenGrab(intNewMax).Height) / 2)
            Else
                .Size = New Size(bmpScreenGrab(intNewMax).Height, bmpScreenGrab(intNewMax).Height)
                .Left = Ctrl.Left - ((bmpScreenGrab(intNewMax).Height - bmpScreenGrab(intNewMax).Width) / 2)
                .Top = Ctrl.Top
            End If

            ' Give the PicturBox a unique name so it's unlikely to be accidentalyy used in other code
            .Name = "_SpinItPB" & intNewMax
            .Tag = intNewMax

            ' Make it visible
            .Visible = True
        End With

        ' Add the PictureBox Paint handler so the animation is visible
        AddHandler NewPB.Paint, AddressOf PictureBox_Paint

        ' Add the PictureBox to the Form
        Me.Controls.Add(NewPB)
        NewPB.BringToFront()

        ' Create a new Timer for this Ctrl alone
        Dim NewTimer As New Timer
        AddHandler NewTimer.Tick, AddressOf NewTimer_Tick

        ' Set the NewTimers interval and Tag then start it
        With NewTimer
            .Tag = intNewMax
            .Interval = intDelay
            .Start()
        End With
    End Sub

    Private Sub NewTimer_Tick(sender As Object, e As System.EventArgs)
        Dim TmpPB As PictureBox = Nothing

        ' Increase the Current Angle by the intAngleChange
        intCurAngle(CInt(sender.tag)) += intAngleChange(CInt(sender.tag))

        ' Find the relevant PictureBox for this Timer
        For Each TmpCtrl As Control In Me.Controls
            If TypeOf TmpCtrl Is PictureBox Then
                If TmpCtrl.Name = "_SpinItPB" & sender.Tag Then
                    TmpPB = TmpCtrl
                    Exit For
                End If
            End If
        Next TmpCtrl

        ' Refresh the PictureBox to show the new Angle
        TmpPB.Refresh()

        ' If the Angle is up to 360 then it has done a full rotation
        ' in this case, make the PictureBox invisible so the original
        ' control is showing and then stop the timer
        If intCurAngle(CInt(sender.tag)) >= 360 Then
            TmpPB.Visible = False
            Me.Controls.Remove(TmpPB)
            sender.Stop()
        End If
    End Sub

    Private Sub PictureBox_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs)
        ' When the form is first loaded there are no Bitmaps so trying to use
        ' them will cause an error.
        ' The Bitmap will be Nothing so Exit Sub
        If bmpScreenGrab(CInt(sender.tag)) Is Nothing Then Exit Sub

        ' Rotate the screenshot image
        With e.Graphics
            ' Move the centre of rotation to the centre of the image
            .TranslateTransform(sender.Width \ 2, sender.Height \ 2)

            ' Rotate the image
            .RotateTransform(intCurAngle(CInt(sender.tag)))

            ' Draw the image
            .DrawImage(bmpScreenGrab(CInt(sender.tag)), -bmpScreenGrab(CInt(sender.tag)).Width \ 2, -bmpScreenGrab(CInt(sender.tag)).Height \ 2)
        End With
    End Sub
End Class

Any help would be much appreciated

Thanks

Viewing all articles
Browse latest Browse all 27554

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>