-
Jun 4th, 2012, 02:43 AM
#1
Thread Starter
Lively Member
[VS2010] VB.NET - Control Fading
Looking around on the net, I have found some clever (and some not so clever) methods for fading label text out. Most of the good examples use Graphics components to overlay a graphical image representation of the ForeGround over the control's background. Some bad examples simply fade white text to black over a black background. Some complicated examples use subforms. My example simply blends the foreground color of the control into the background color.
Me, not being a math person, tried to find an example of my method online to help me with some of the math involved with blending the foreground and background colors. I couldn't find any So, I created this version from scratch. It's pretty rough and can use some dressing, hence why it is in the "Code It Better" forum. In the future, I may clean it up a bit, maybe make a custom fade control, and include a demo application where different color and timer values can be tested on the fly.
It works by getting the difference in values for each of the 3 color channels between the background color and the foreground color of the control. It then divides the difference up into the specified number of fade steps and stores that value as a single. Then, utilizing a timer, adjusts the values of the foreground color a number of times until the text is completely "transparent" - where transparent means "equal to the background color".
This can be easily added to any form. I have created a Class which can be used to simplify implementation and use of the fading effect. As a bonus, since this method uses simple math and functions, it should be fairly lightweight and efficient. The class stores a permanent reference to the control. This can be easily adjusted to suit many different controls. I think it should work with any control that has separate background and foreground colors. In this case, the class operates on a ToolStripStatusLabel because that is what I needed it for. It can be set to a standard label by changing the appropriate references in the class and calling methods.
Constructor:
New(TargetControl) - Only one constructor exists, and it requires a reference to the control to fade.
Public Methods:
StartFade() - Starts the fading effect after an adjustable delay
StopFade() - Halts the fading effect immediately
Public Properties:
FadeCount (ReadOnly) - The current fade step if the control is in the process of fading out
FadedControl (ReadOnly) - A reference to the control that will be faded
Red/Green/BlueMultiplier (ReadOnly) - The amount of color shift for each color channel that will be applied during each fade step. Set when the fade effect is started.
OriginalBack/ForeColor (ReadOnly) - The starting values for the control colors. Useful for resetting the control so it can be used again. The class only fades the foreground into the background. It does not make the foreground visible again - that must be done by the caller.
FadeSteps - ReadOnly when fading. MinValue = 5. Number of transitions before the foreground is no longer visible.
FadeTime - ReadOnly when fading. MinValue = 10Steps (ie, 10ms minimum for each step). The time between transitions.
StepTime (ReadOnly) - The Transition time for each fade step
InitialDelay - ReadOnly when fading. MinValue = 1second (arbitrary). The delay before the foreground begins to fade.
Started (ReadOnly) - True if the fade process has begun.
Here is the TextFade.vb class:
Code:
Public Class TextFade
Private WithEvents _FadeTimer As New Timer
Private _FadeCount As UInt16 = 0
Public ReadOnly Property FadeCount As UInt16
Get
Return _FadeCount
End Get
End Property
Private _FadedControl As ToolStripStatusLabel
Public ReadOnly Property FadedControl As ToolStripStatusLabel
Get
Return _FadedControl
End Get
End Property
Private _RedMultiplier As Single
Public ReadOnly Property RedMultiplier As Single
Get
Return _RedMultiplier
End Get
End Property
Private _GreenMultiplier As Single
Public ReadOnly Property GreenMultiplier As Single
Get
Return _GreenMultiplier
End Get
End Property
Private _BlueMultiplier As Single
Public ReadOnly Property BlueMultiplier As Single
Get
Return _BlueMultiplier
End Get
End Property
Private _OriginalBackColor As Color
Public ReadOnly Property OriginalBackColor As Color
Get
Return _OriginalBackColor
End Get
End Property
Private _OriginalForeColor As Color
Public ReadOnly Property OriginalForeColor As Color
Get
Return _OriginalForeColor
End Get
End Property
Private _FadeSteps As UInt16 = 10
''' <summary>
''' Number of fade steps before text is completely 'transparent'
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Steps As UInt16
Get
Return _FadeSteps
End Get
Set(ByVal value As UInt16)
If Not Started AndAlso value > 4 Then
_FadeSteps = value
End If
End Set
End Property
Private _FadeTime As UInt16 = 1000
''' <summary>
''' Total time before text is completely faded out
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property FadeTime As UInt16
Get
Return _FadeTime
End Get
Set(ByVal value As UInt16)
If Not Started AndAlso value > (Steps * 10) Then 'Minimum fade time between each step is 10ms. This is arbitrary
_FadeTime = value
End If
End Set
End Property
''' <summary>
''' Returns the delay between each fade step
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property StepTime As UInt16
Get
Return FadeTime / Steps
End Get
End Property
Private _InitialDelay As Integer = 60000 '1 minute
''' <summary>
''' Sets the initial delay before starting the fade
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property InitialDelay As Integer
Get
Return _InitialDelay
End Get
Set(ByVal value As Integer)
If Not Started AndAlso value > 1000 Then 'Minimum start delay is 1 second. Again, arbitrary
_InitialDelay = value
End If
End Set
End Property
'Private _Started As Boolean = False
Public ReadOnly Property Started As Boolean
Get
Return _FadeTimer.Enabled
End Get
End Property
Public Sub New(ByRef target As ToolStripStatusLabel)
_FadedControl = target
_OriginalBackColor = target.BackColor
_OriginalForeColor = target.ForeColor
End Sub
Private Sub GetMultipliers()
_RedMultiplier = (OriginalBackColor.R - OriginalForeColor.R) / Steps
_GreenMultiplier = (OriginalBackColor.G - OriginalForeColor.G) / Steps
_BlueMultiplier = (OriginalBackColor.B - OriginalForeColor.B) / Steps
'_FadedControl.BackColor
End Sub
Public Sub StartFade()
If Started Then Exit Sub 'Can't start it twice :p
'Started = True 'Prevents some properties from being modified
GetMultipliers()
_FadeCount = 0
_FadeTimer.Interval = InitialDelay
_FadeTimer.Enabled = True
End Sub
Public Sub StopFade()
If Started Then
_FadeTimer.Enabled = False
'_Started = False
End If
End Sub
Private Sub FadeTimer_Tick() Handles _FadeTimer.Tick
If _FadeCount = 0 Then _FadeTimer.Interval = StepTime
_FadeCount += 1
If FadeCount >= Steps Then
'Not sure how it can be greater than... but you never know :p
'If feeling lucky, remove the greater than comparator
_FadedControl.ForeColor = _FadedControl.BackColor 'Text completely 'transparent'
_FadeTimer.Enabled = False
'_Started = False
Else
_FadedControl.ForeColor = New SolidBrush(Color.FromArgb(OriginalForeColor.R + (_FadeCount * RedMultiplier), OriginalForeColor.G + (_FadeCount * GreenMultiplier), OriginalForeColor.B + (_FadeCount * BlueMultiplier))).Color
End If
End Sub
End Class
Here is the Implementation in my form, where Message is an instance of ToolStripStatusLabel:
Code:
Private MessageFader As TextFade
Private Sub SetStatusMessage(ByVal MessageText As String)
If IsNothing(MessageFader) Then MessageFader = New TextFade(Message)
MessageFader.StopFade() 'Stops the fader if it is running
MessageFader.FadeTime = 5000
MessageFader.InitialDelay = 5000
MessageFader.Steps = 100
Message.ForeColor = MessageFader.OriginalForeColor
Message.BackColor = MessageFader.OriginalBackColor
Message.Text = MessageText
MessageFader.StartFade()
End Sub
Some possible improvements:
1) Make the class more versatile to work with any control
2) Better Error Handling
3) Clean up the code somewhat
4) Better commenting
5) Create a demo app
6) Create custom controls utilizing these properties. For example, a fadelabel could be created that displays text for 30 seconds then slowly fades out, where changing the value of the Text property of the label would start the fade process.
7) Some people have problems with Timers? Maybe a background thread would work better for managing the fade (?)
8) Errors should get thrown if the control becomes unavailable in the middle of the fade process. This hasn't occurred in my implementation, but I can easily see how it could in certain circumstances. Therefore, error handling should be added to prevent the program from crashing unexpectedly.
Limitations:
Obviously, can only fade two solid colors. Can't be used to fade text into an image. Can't fade a foreground of a control where there is no background color specified (background: Transparent). You can sort of get around this by setting the background of the control to the same color as any controls it overlays (such as the form).
If someone else thinks of something, let me know.
That's it. Hopefully this helps someone.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|