It is currently April 24th, 2024, 4:37 pm

Simple fade effect

Tips and Tricks from the Rainmeter Community
User avatar
haibusa2005
Posts: 52
Joined: June 15th, 2011, 7:23 pm
Location: Bulgaria, Varna

Simple fade effect

Post by haibusa2005 »

I haven't seen a simple method of showing and hiding different meters in a skin using fade effect do I decided to show you how I do it. So, first thing is setting a low Update value, something like 10 or 50 milliseconds. The update parameter basically controls the smoothness of the fade effect. High values make the animation choppy. Next thing worth mentioning is that you have two ways of showing a meter - using the bangs !ShowMeter or !ShowMeterGroup and using transparency value of the current meter. I believe the bangs don't need an explanation so I will just stick to controlling the transparency value. First we need a variable which will control the fade effect - do we need a fade in or a fade out animation, just for convenience we name the variable "Fade".

Code: Select all

[Variables]
Fade=0
The initial value of the variable determines the state of the controlled meters - if they are hidden or visible. Fade=0 means hidden initial state. Next thing is the actual fade control algorithm, which is named "FadeControl"

Code: Select all

[FadeControl]
DynamicVariables=1
Measure=Calc
Formula=#Fade#=1?(FadeControl=250?250:FadeControl+25):(FadeControl=0?0:FadeControl-25)
A bit of explanation - DynamicVariables parameter makes the fade effect working two ways as we use the Fade variable to control it. FadeControl=250?250 sets the maximum opacity for the controlled meters and FadeControl±25 controls the step of the fade effect - the smaller the value, the animation is smoother and also the longer it takes to make the controlled meters fully opaque. The speed of the fading effect is actually linked to Update parameter we set, as one step of the fade animation is displayed in the number of milliseconds we set as Update value. A simple rule that applies here is that FadeControl maximum value must be devideble to the add/substract value with no remainder. The actual meaning of the formula is: "Check of fade in or fade out. If fade in, check if meters are already opaque. If they are, do nothing or if they are with opacity lower than 250, add 25 to current value. If fade out is required, check if meters are already fully transparent. If they are, do nothing or if they are with opacity higher than 0 substract 25 of the current value." Values over 255 set opacity as "(current value - 255)%255" which basically means if opacity is 300, actual value will be 45, if it's 700 actual value will be 190 and so on.
Setting the Fade variable can be achieved in different ways but I assume the most frequent ways are on mouse over/mouse leave control or by clicking a button. Here it is a variant with a hovering mouse

Code: Select all

[FadeHoverButton]
Meter=Image
SolidColor=0,255,0,100
x=0
y=70
w=20
h=20
MouseOverAction=!Execute [!SetVariable Fade 1]
MouseLeaveAction=!Execute [!SetVariable Fade 0]
DynamicVariables=1
A clickable button

Code: Select all

[FadeInButton]
UpdateDivider=50
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 1] [!HideMeter FadeInButton] [!ShowMeter FadeOutButton]
DynamicVariables=1

[FadeOutButton]
UpdateDivider=50
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 0] [!HideMeter FadeOutButton] [!ShowMeter FadeInButton]
Hidden=1
DynamicVariables=1
The UpdateDivider parameter is multiplied with the Update parameter which is set in the [Rainmeter] section. Its meaning to the overall skin is how much time will pass until we can switch from fading in or fading out to the opposite animation (respectively how much opaque the controlled meters will become between the clicks) if the toggle button is double clicked.

Here is an example of a fading text meter and an image meter

Code: Select all

[FadedText]
Meter=String
Text="Faded text"
FontFace=Calibri
AntiAlias=1
StringAlign=Left
FontSize=20
FontColor=255,255,255,[FadeControl]
x=60
y=0
h=30
w=150
DynamicVariables=1

Code: Select all

[ImageFade]
Meter=Image
ImageName=Random.png
x=60
y=40
x=300
y=300
AntiAlias=1
ImageTint=255,255,255,[FadeControl]
DynamicVariables=1
Addition on 24.07.12, edited on 26.07.12

The method listed above is a quite brute force one, making the skin which is using it very CPU intensive if the skin has a lot of images and strings so we will add some optimization. The goal is to make all the fading elements and the fading algorithm active only during the fading effect. Once the meters have reached maximum opacity the update rate should be back to a not so CPU intensive value.

First we will add a new variable - DividerVar which we will include in every faded element of the skin. We should set the value as DividerVar*Update to be 1000 ms or something similar.

Code: Select all

Fade=0
DividerVar=100
We will set initial state of FadeControl as disabled and also make it set a DividerVar at big value effectively setting faded elements to "normal", not-so-CPU-intensive state.

Code: Select all

[FadeControl]
UpdateDivider=#DividerVar#
DynamicVariables=1
Measure=Calc
Formula=#Fade#=1?(FadeControl=250?250:FadeControl+25):(FadeControl=0?0:FadeControl-25)
IfEqualValue=250
IfEqualAction=[!SetVariable DividerVar 100]
We need to introduce a new element of the optimization - a counter which waits a certain amount of time (as long as needed for the elements to completely fade out) and then disables itself and the FadeControl as well. Its initial state is also disabled, similar to FadeControl. The IfEqualValue can be calculated as maximum opacity of the fade effect divided on the step of the fade control+1. For example - maximum opacity is 250, step is 25 so IfEqualValue is 250/25+1=11. The 1 at the end is added to make sure the faded meters are already transparent before disabling the FadeControl. Setting a value lower than the result of the formula will probably result in chopping of the end of the animation. For example setting IfEqualValue to 5 will make the meters disappear in the middle of their fading out.

Code: Select all

[DisableFadeControlTimer]
DynamicVariables=1
Measure=Calc
Formula=DisableFadeControlTimer+1
IfEqualValue=11
IfEqualAction=!Execute [!DisableMeasure FadeControl] [!SetVariable DividerVar 100] [!DisableMeasure DisableFadeControlTimer]
We will need some additions to the buttons as well. On click or hover they should set DividerVar at 1 and enable the FadeControl, the other matters are handled by the FadeControl itself. The fade out button must enable the fade out timer which will wait for the FadeControl to fade out and then disable it, set DividerVar at 100 and then disable itself. The same applies for the hover button.

Code: Select all

[FadeInButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 1] [!SetVariable DividerVar 1] [!EnableMeasure FadeControl] [!HideMeter FadeInButton] [!HideMeter FadeHoverButton] [!ShowMeter FadeOutButton] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX] 
DynamicVariables=1

[FadeOutButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 0] [!SetVariable DividerVar 1] [!HideMeter FadeOutButton] [!ShowMeter FadeHoverButton] [!ShowMeter FadeInButton] [!EnableMeasure DisableFadeControlTimer] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX] 
Hidden=1
DynamicVariables=1

[FadeHoverButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=0,255,0,100
x=0
y=70
w=20
h=20
MouseOverAction=!Execute [!SetVariable Fade 1] [!SetVariable DividerVar 1] [!EnableMeasure FadeControl] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX] 
MouseLeaveAction=!Execute [!SetVariable Fade 0] [!SetVariable DividerVar 1] [!EnableMeasure DisableFadeControlTimer] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX] 
DynamicVariables=1
We add the bangs !UpdateMeasure and !UpdateMeter so the faded meters can start fading immediately after clicking/hovering the control buttons without waiting for the current update cycle to end. The only disadvantage of this optimization method is that FadeControl remains active as long as the controlled meters are opaque in order to maintain their opaque state. This can be bared however, since the current CPUs provide performance way over the needs of an temporary active measure. If FadeControl is disabled after reaching full opaque state, its value becomes zero, meaning disappearing meters which should be opaque. This can be bypassed by using an external variable but the code becomes even more complicated as it's now, as we are already a bit off the term "simple".


Full code of the optimized skin below
[Rainmeter]
Author=Haibusa2005
AppVersion=1.0
Update=10

[Metadata]
Description=Test fade effect
License=Creative Commons BY-NC-SA 3.0
Version=0.01

[Variables]
Fade=0
DividerVar=100

[FadeControl]
UpdateDivider=#DividerVar#
DynamicVariables=1
Measure=Calc
Formula=#Fade#=1?(FadeControl=250?250:FadeControl+25):(FadeControl=0?0:FadeControl-25)
IfEqualValue=250
IfEqualAction=[!SetVariable DividerVar 100]

[DisableFadeControlTimer]
DynamicVariables=1
Measure=Calc
Formula=DisableFadeControlTimer+1
IfEqualValue=11
IfEqualAction=!Execute [!DisableMeasure FadeControl] [!SetVariable DividerVar 100] [!DisableMeasure DisableFadeControlTimer]

[FadeInButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 1] [!SetVariable DividerVar 1] [!EnableMeasure FadeControl] [!HideMeter FadeInButton] [!HideMeter FadeHoverButton] [!ShowMeter FadeOutButton] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX]
DynamicVariables=1

[FadeOutButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=255,0,0,100
x=0
y=30
w=20
h=20
LeftMouseUpAction=!Execute [!SetVariable Fade 0] [!SetVariable DividerVar 1] [!HideMeter FadeOutButton] [!ShowMeter FadeHoverButton] [!ShowMeter FadeInButton] [!EnableMeasure DisableFadeControlTimer] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX]
Hidden=1
DynamicVariables=1

[FadeHoverButton]
UpdateDivider=#DividerVar#
Meter=Image
SolidColor=0,255,0,100
x=0
y=70
w=20
h=20
MouseOverAction=!Execute [!SetVariable Fade 1] [!SetVariable DividerVar 1] [!EnableMeasure FadeControl] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX]
MouseLeaveAction=!Execute [!SetVariable Fade 0] [!SetVariable DividerVar 1] [!EnableMeasure DisableFadeControlTimer] [!UpdateMeasure FadeControl] [!UpdateMeterGroup GFX]
DynamicVariables=1

[FadedText]
UpdateDivider=#DividerVar#
Meter=String
Text="Faded text"
FontFace=Calibri
AntiAlias=1
StringAlign=Left
FontSize=20
FontColor=255,255,255,[FadeControl]
x=60
y=0
h=30
w=150
DynamicVariables=1
Group=GFX

[ImageFade]
UpdateDivider=#DividerVar#
Meter=Image
ImageName=Random.png
x=60
y=40
x=300
y=300
AntiAlias=1
ImageTint=255,255,255,[FadeControl]
DynamicVariables=1
Group=GFX
Last edited by haibusa2005 on July 26th, 2012, 12:36 pm, edited 6 times in total.
User avatar
Kaelri
Developer
Posts: 1721
Joined: July 25th, 2009, 4:47 am

Re: Simple fade effect

Post by Kaelri »

Well done. :) This is a great way to get a simple transition when you don't need too many bells and whistles. Attractively compact, as well.