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 ^^.
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.