Fond de feuille animé : dégradé mouvant pour about ou splashscreen

Soyez le premier à donner votre avis sur cette source.

Vue 16 640 fois - Téléchargée 1 179 fois


Description

Hello tout le monde,
hier je m'amusait à chercher comment rendre mes moches applis un peu plus attractives, et je me suis renseigné sur les dégradés gerés par le framework .net (merci Richard Clark).
C'est en bidouillant un peu avec que je suis arrivé à ce resultat assez simpa. Des degradés mouvants!
Vous spécifiez deux couleur et un type de degradé, et la classe se charge de redessiner en permance la feuille.
Le plus interessant est je pense, celui en "diagonale", mais les verticaux et horizontaux font aussi leur petit effet.
J'ai donc tenter de rendre mon code générique en écrivant une petit classe très simple à utiliser.
La méthode en elle même est, comme je l'ai dit, une bidouille.
En effet, je ne travaille pas sur le fond de la feuille, mais sur un label de la taille de la feuille, ajouté en arrière plan.
Ceci du fait qu'en travaillant sur la feuille elle même, le form_paint est appelé en permanence, et produit un clignottement très désagréable.

Enfin, je precise dans le titre "pour about ou splashscreen", car ce petit effet de cowboy est gourmand en ressources,
à eviter donc sur une vraie appli ^^

Deux classes donc ici, la première, destiné à mettre en fond une image dégradé sur un control, et l'autre qui se charge de l'effet mouvant.
J'ai également mis un petit sample dans le zip.

Have fun

Source / Exemple :


'classe de dessin de degradés sur un controle

Public Class HbCtrlDegrad

    Public Enum TypeDegrad
        Horizontal
        Vertical
        Diagonale_avant
        Diagonale_arriere
    End Enum

    Friend Shared Sub Degrade(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal type As TypeDegrad)
        Degrade(ctrl, startcolor, endcolor, type, 0)
    End Sub

    Friend Shared Sub Degrade(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal angle As Single)
        Degrade(ctrl, startcolor, endcolor, 5, angle)
    End Sub

    Friend Shared Sub Degrade(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal type As TypeDegrad, ByVal angle As Single, Optional ByVal width As Integer = -1, Optional ByVal height As Integer = -1)
        If width = -1 Then width = ctrl.Width
        If height = -1 Then height = ctrl.Height
        Dim a As Image = New Bitmap(ctrl.Width, ctrl.Height)
        Dim bgGraph As Graphics = Graphics.FromImage(a)
        Dim rect As New Rectangle(New Point(0, 0), New Point(width, height))
        Dim degradbrush As Drawing2D.LinearGradientBrush
        Select Case type
            Case TypeDegrad.Horizontal
                degradbrush = New Drawing2D.LinearGradientBrush(rect, startcolor, endcolor, Drawing2D.LinearGradientMode.Horizontal)
            Case TypeDegrad.Vertical
                degradbrush = New Drawing2D.LinearGradientBrush(rect, startcolor, endcolor, Drawing2D.LinearGradientMode.Vertical)
            Case TypeDegrad.Diagonale_avant
                degradbrush = New Drawing2D.LinearGradientBrush(rect, startcolor, endcolor, Drawing2D.LinearGradientMode.ForwardDiagonal)
            Case TypeDegrad.Diagonale_arriere
                degradbrush = New Drawing2D.LinearGradientBrush(rect, startcolor, endcolor, Drawing2D.LinearGradientMode.BackwardDiagonal)
            Case Else
                degradbrush = New Drawing2D.LinearGradientBrush(rect, startcolor, endcolor, angle, True)
        End Select
        bgGraph.FillRectangle(degradbrush, rect)
        ctrl.BackgroundImage = a
    End Sub

End Class

'classe de gestion de fond mouvant 

Public Class RollingBG

    Private b As Boolean
    Private _interval As Integer
    Private _startcolor As Color
    Private _endcolor As Color
    Private _curform As Form
    Private _backlabel As Label = New Label
    Private _angle As Single
    Private thread1 As Threading.Thread

    Public Enum TypeDegrad
        Horizontal
        Vertical
        Diagonale
    End Enum

    Private Delegate Sub DelegateAddLabel(ByVal newlabel As Label)
    Private Delegate Sub DelegateRemoveLabel(ByVal newlabel As Label)
    Private Delegate Sub DelegateChangeBGColor(ByVal clr As Color)
    Private Delegate Sub DelegateDegrade(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal angle As Single)
    Private Delegate Sub DelegateDegradeHV(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal type As TypeDegrad, ByVal angle As Single, ByVal width As Integer, ByVal height As Integer)

    Public Sub New()
        _interval = 10
    End Sub

    Public Sub New(ByVal interval As Integer)
        If interval > 0 Then
            _interval = interval
        Else
            _interval = 10
        End If
    End Sub

    Private Function newlabel(ByVal width As Single, ByVal height As Single) As Label
        Dim newlbl As New Label
        newlbl.Width = width
        newlbl.Height = height
        Return newlbl
    End Function

    Public Sub vertical(ByRef curform As Form, ByVal startcolor As Color, ByVal endcolor As Color)
        start(curform, startcolor, endcolor, 2)
    End Sub

    Public Sub horizontal(ByRef curform As Form, ByVal startcolor As Color, ByVal endcolor As Color)
        start(curform, startcolor, endcolor, 1)
    End Sub

    Public Sub diagonal(ByRef curform As Form, ByVal startcolor As Color, ByVal endcolor As Color)
        start(curform, startcolor, endcolor, 0)
    End Sub

    Private Sub start(ByRef curform As Form, ByVal startcolor As Color, ByVal endcolor As Color, ByVal type As Integer)
        pause()
        Select Case type
            Case 0
                thread1 = New Threading.Thread(AddressOf diagonal_thread)
            Case 1
                thread1 = New Threading.Thread(AddressOf horizontal_thread)
            Case 2
                thread1 = New Threading.Thread(AddressOf vertical_thread)
        End Select
        'pause()
        b = True
        _curform = curform
        _startcolor = startcolor
        _endcolor = endcolor
        AddHandler _curform.FormClosing, AddressOf FormClosing
        thread1.Start()
    End Sub

    Private Sub vertical_thread()
        Dim descendant As Boolean = True
        Dim i As Integer = 1
        Dim max As Integer = _curform.Height + (_curform.Height / 4)
        _curform.Invoke(New DelegateChangeBGColor(AddressOf changeBGcolor), New Object() {_endcolor})
        _backlabel = newlabel(_curform.Width, _curform.Height)
        _curform.Invoke(New DelegateAddLabel(AddressOf addlabel), New Object() {_backlabel})
        Do While b = True
            Do While (i < max) And (i >= 1)
                If b = False Then Exit Do
                _backlabel.Invoke(New DelegateDegradeHV(AddressOf DegradeA), New Object() {_backlabel, _startcolor, _endcolor, TypeDegrad.Vertical, 0, -1, i})
                Threading.Thread.Sleep(_interval)
                If descendant = True Then i += 1 Else i -= 1
            Loop
            descendant = Not descendant
            If descendant = False Then i -= 1 Else i += 1
        Loop
        _curform.Invoke(New DelegateRemoveLabel(AddressOf removelabel), New Object() {_backlabel})
    End Sub

    Private Sub horizontal_thread()
        Dim descendant As Boolean = True
        Dim i As Integer = 1
        Dim max As Integer = _curform.Width + (_curform.Width / 4)
        _curform.Invoke(New DelegateChangeBGColor(AddressOf changeBGcolor), New Object() {_endcolor})
        _backlabel = newlabel(_curform.Width, _curform.Height)
        _curform.Invoke(New DelegateAddLabel(AddressOf addlabel), New Object() {_backlabel})
        Do While b = True
            Do While (i < max) And (i >= 1)
                If b = False Then Exit Do
                _backlabel.Invoke(New DelegateDegradeHV(AddressOf DegradeA), New Object() {_backlabel, _startcolor, _endcolor, TypeDegrad.Horizontal, 0, i, -1})
                Threading.Thread.Sleep(_interval)
                If descendant = True Then i += 1 Else i -= 1
            Loop
            descendant = Not descendant
            If descendant = False Then i -= 1 Else i += 1
        Loop
        _curform.Invoke(New DelegateRemoveLabel(AddressOf removelabel), New Object() {_backlabel})

    End Sub

    Private Sub diagonal_thread()
        _backlabel = newlabel(_curform.Width, _curform.Height)
        _curform.Invoke(New DelegateAddLabel(AddressOf addlabel), New Object() {_backlabel})
        Do While b
            For i As Integer = 1 To 360
                If b = False Then Exit For
                If i Mod 90 = 0 Then i = i + 1 'evite le clignottement des angles "droits" (90,180,270)
                _backlabel.Invoke(New DelegateDegrade(AddressOf DegradeB), New Object() {CType(_backlabel, Control), _startcolor, _endcolor, i})
                Threading.Thread.Sleep(_interval)
            Next
        Loop
        _curform.Invoke(New DelegateRemoveLabel(AddressOf removelabel), New Object() {_backlabel})
    End Sub

    'event ajouté à la form 
    Private Sub FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs)
        pause()
    End Sub

    Public Sub pause()
        b = False
        If Not IsNothing(thread1) Then
            thread1.Abort()
            removelabel(_backlabel)
        End If
    End Sub

    'Sub deleguées
    Private Sub addlabel(ByVal newlabel As Label)
        _curform.Controls.Add(newlabel)
    End Sub

    Private Sub removelabel(ByVal newlabel As Label)
        _curform.Controls.Remove(newlabel)
    End Sub

    Private Sub changeBGcolor(ByVal clr As Color)
        _curform.BackColor = clr
    End Sub

    Private Sub DegradeA(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal type As TypeDegrad, ByVal angle As Single, ByVal width As Integer, ByVal height As Integer)
        If b = True Then
            HbCtrlDegrad.Degrade(ctrl, startcolor, endcolor, type, 0, width, height)
        End If
    End Sub

    Private Sub DegradeB(ByRef ctrl As Control, ByVal startcolor As Color, ByVal endcolor As Color, ByVal angle As Single)
        If b = True Then
            HbCtrlDegrad.Degrade(ctrl, startcolor, endcolor, 5, angle)
        End If
    End Sub

End Class

Conclusion :


J'ai presque honte de perdre du temps la dessus, mais bon... ^^'
Je met niveau Initié, même si l'utilisation de la classe est simpliste, et que la partie algorithmique se resume à peu de ligne de code, le fait qu'elle implémente threads et autres delegués necessite je pense, ce niveau 2. Faites le moi savoir si vous pensez que je m'emballe ^^.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

gillardg
Messages postés
3275
Date d'inscription
jeudi 3 avril 2008
Statut
Membre
Dernière intervention
14 septembre 2014
3 -
ça c'est urile
c'est sympa
bravo
Elxior
Messages postés
56
Date d'inscription
jeudi 28 juin 2007
Statut
Membre
Dernière intervention
29 août 2010
1 -
"effectivement le "= true" est facultatif à écrire, mais je ne suis pas sur que cela soit réelement plus rapide une fois compilé, le gain de temps serait de toutes façons minime (1µs? ^^)"

http://www.c2i.fr/code.aspx?IDCode=377

Sans le = true, c'est 2x plus rapide à l'exécution ;).
hvb
Messages postés
939
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
27 janvier 2009
1 -
oui, comme je l'ai dit :
"Enfin, je precise dans le titre "pour about ou splashscreen", car ce petit effet de cowboy est gourmand en ressources,
à eviter donc sur une vraie appli ^^"

ça reste un juste un délire ^^
XelectroX
Messages postés
209
Date d'inscription
samedi 11 novembre 2000
Statut
Membre
Dernière intervention
6 novembre 2009
-
Pauvre mémoire :s
http://www.imagehosting.com/out.php/i1314504_tmp.jpg -> Va voir ;)

Et quand on anime avec le délai 10, mon processeur passe à 80%
hvb
Messages postés
939
Date d'inscription
vendredi 25 octobre 2002
Statut
Membre
Dernière intervention
27 janvier 2009
1 -
rah, *$¤%§# d'erreur 500, j'avais écris tout un roman... tant pis.
En résumé, j'ai detecté le problème, je pense avoir une solution, je testerais ce soir de chez moi, je suis au boulot pour l'instant.

Have fun

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.