are offered along with this description; ScrollText2Shrink.ini and ScrollText2CenterZoom.ini
ScrollText2Shrink shrinks the text as it progresses up the skin and back down.
ScrollText2CenterZoom maximizes the size near the vertical center.
Scrolling the text vertically requires us to know several things about the skin in order to control the display:
With that information we can create variables and formulas to determine the position of the text and control when to display it.
We need to control and know how much space an item takes in order to determine it's position and hide/show it.
The font selected will effect the line height, so I use a formula to adjust that variable LINEHEIGHT=
#*1.6. The actually relationship is closer to 1.4 but using 1.6 prevents clipping of the bottom on some fonts. You can adjust the multiplier if your selected font is being clipped.
# variable we can decide on the spacing and set a limit on the number of lines in one line of information by setting up a
MARGINS VARIABLES
If no image is used as background or overlay, then the top, bottom, and margins can be the skin defaults; Top=0, Bottom=
#PanelHeight#. The sides would be Left=0 and Right=
#PanelWidth#. Side margins can be expanded for aesthetics, but if left as default, the string clipping will just use the left & right skin edges.
If an image is used, we will need to create margin variables to prevent the text from appearing above or around the image:
TopMargin = 10
BottomMargin = (#PanelHeight#/6 + #LineHeight#)
MISC VARIABLES
Variables allow easy control of the option to hide/show the included graphic meters. The BGShade variable adjust the background shading if no underlay are used.
The items being displayed are included in these skins, but it is a simple matter to use an
include file with the info, or add a web parser and display information from the string indexes.
#Lines# equals the number of items displayed. It is used to hide/show lines based on vertical position in skin. You will need to add or delete [mZoomLine?] measures and [Text?] meters to match the number of text line variables (above).
SCROLLING
Next we need to set up a few variables for the scroll:
#DefaultSpeed# is the Scroll Default Speed (0 = None)
#StepRate# sets the mouse wheel change rate; how mush is add/subtracted from the current speed value on mouse wheel movement.
#Speed# is set dynamically by the mouse wheel action on the background meter.
Version 2 changes the scroll control impact by only controlling the first meter; all other meters are relatively positioned to that meter. This allows setting a unique link for each item.
Scrolling is accomplished with 1 measure [MeasureY] acting on 1 meter [Text0].
[MeasureY]
Measure = Calc
Formula = (MeasureY-#Speed#)
Dynamicvariables = 1
The [MeasureY] starts at '0' and increases or decreases via the changes to
#Speed# variable.
First string meter:
[Text0]
Meter = string
MeterStyle = Style
FontColor = #TitleColor#
Y = (#PanelHeight# + [MeasureY])
W = (#PanelWidth# - (#Margin#*2))
H = #LineSpace#
Text = #T0#
Hidden = ((#PanelHeight# + #LineHeight# + ([MeasureY])) > (#PanelHeight# - #BottomMargin#))? 1 : ([Text0:Y] < #TopMargin#)?
LeftMouseUpAction = ["eclectic-tech.deviantart.com"]
ToolTipText = My DeviantArt Site
DynamicVariables = 1
Group = Text
TransformationMatrix = ([mZoomLine0]);0;0;([mZoomLine0]);((1-([mZoomLine0]))*#PanelWidth#/2);((1-([mZoomLine0]))*[#CURRENTSECTION#:Y])
HIDDEN checks the current line position of the based on the current MEASURE Y, and hides it until it is in the Viewable Area; the second portion of the Hidden Calc checks if the current Y value is less than top margin and hides the meter if it is above it.
DECRYPTING THE TRANSFORMATIONMATRIX FORMULA DEFINITION
Before we look at the zooming, I think another look at the TransformationMatrix command will help.
The manual offers a very good guide on IMAGE transformations here:
docs.rainmeter.net/tips/transf…The short explanation given in the manual leaves a lot of people scratching their heads, that's the way I was also.
{
From the manual}
docs.rainmeter.net/manual-beta…
TransformationMatrix Default: 1;0;0;1;0;0
Defines a 3x2 matrix which can be used to transform the meter. Transformations include: scaling, skewing, and translating (ie. moving). There must be exactly 6 values separated by semicolons ";". Combining these will have drastic effects on the meter it is applied to.
Examples:
TransformationMatrix=-1; 0; 0; 1; 40; 0: This will flip X along the line X=20.
TransformationMatrix=1; 0; 0; -1; 0; 100: This will flip Y along the line Y=50.
TransformationMatrix=0.5; 0; 0; 1; 25; 0: This will scale X by 0.5 at X=50.
Note: All transformations are relative to the top left corner of the window and not to the meter itself. So if you want to rotate the meter by its center the translation component in the matrix must be relative to the top left corner of the window.
Also note that the even if the meter's visual location and orientation is changed by the transformation the place where it would be located without the transformation will still be used to define the window size and register the mouse clicks. This might change in the future though.
{
End of manual}
Okay, now I'm TOTALLY confused...
So I decided to "play" with this tool using the expanded guide in the manual (link above) as a starting point and see what happens...
First, I believed the best way to do this was to only deal with 1 section at a time (scaling, skewing, or moving) and see the results. Doing that improved my understanding of the effects those changes had on the "image" and resulted in my preferred definition of the matrix:
TransformationMatrix = {scale x};{skew y};{skew x};{scale y};{move x};{move y}
Remember that every transformation is relative to the upper left corner of the skin, changing the scale or skew will also change the X & Y position in the skin. This means that the last 2 values {move x};{move y} need to be adjusted to achieve the desired effect AND correct any shift.
For strictly scaling (zooming in or out) another forum member, Xanci, offered a universal formula:
TransformationMatrix = #zoom#;0;0;#zoom#;1-#zoom#*[#CURRENTSECTION#: X];1-#zoom#*[#CURRENTSECTION#: Y]
DynamicVariables=1
This works very well and will scale from the original size and position in either direction. You will also see that the range of values for
#zoom# is rather small (the effects are large!)... 0.1 to 5 are usable, beyond those values you will see the image/text is either so small, or so large, it is unrecognisable.
You will also notice the image/text shifts to the left when zooming out and shifts to the right when zooming in. This is because all transformations are relative to the upper left corner of the skin and the starting X & Y positions.
For an image meter, shifting left or right, may not be an issue, but with string meters, formatting can be critical. My desire was to keep the text in the same X position (centered) while scaling. I added a background with a
#PanelWidth# variable, and made a slight change to Xanci's universal formula:
TransformationMatrix = #zoom#;0;0;#zoom#;((1-#zoom#)*(#PanelWidth#/2));((1-#zoom#)*[#CURRENTSECTION#:Y])
DynamicVariables=1
As you can see it was simply a matter of substituting the section variable '[
#CURRENTSECTION#: X]' with the value of my panel center '(
#PanelWidth#/2)' as the initial value to be transformed in the {move x} portion of the transformation matrix. The new X position will always be 'near' the center of my skin for most transformations (0~2).
NO SKEWING?
Because most text is usually written/read left-to-right (or visa-versa) and not at angles, I am not utilizing the {skew y};{skew x} portions of the transformation. If you are so inclined, try changing those values and see the effect; I may attempt a skin utilizing skew (a clock perhaps) but not until I get more familiar with the matrix.
ZOOM IN or OUT (Scaling based on Vertical Position in the skin)
Now that we can transform the text and have it remain centered, my next goal was to set up zoom measures for each line item and control the size based on screen position. For that I had to create zoom variables (see VARIABLES above); I decided on 10 levels of zoom, which means the skin height must also be divided by 10 or multiples of it to give me uniform zoom features. The shrinking text use 10 zoom levels based on 0.1 of the skin height (0.1, 0.2, 0.3, ...). The center zoom skin uses 20 zoom levels, the same 10 levels, but based on 20 divisions of the skin height (0.05, 0.1, 0.15, 0.2, ...). Notice that I include a preceding zero '0' in the calculation; Rainmeter will not recognize decimal in a Calc formula, without an integer included (learning by trial and error!).
Measure to determine zoom for first meter [Text0]:
[mZoomLine0]
Measure = Calc
Formula = ([Text0:Y])<(#PanelHeight#*0.1)? #Zoom9# : (([Text0:Y])<(#PanelHeight#*0.2)? #Zoom8# : (([Text0:Y])<(#PanelHeight#*0.3)? #Zoom7# : (([Text0:Y])<(#PanelHeight#*0.4)? #Zoom6# : (([Text0:Y])<(#PanelHeight#*0.5)? #Zoom5# : (([Text0:Y])<(#PanelHeight#*0.6)? #Zoom4# : (([Text0:Y])<(#PanelHeight#*0.7)? #Zoom3# : (([Text0:Y])<(#PanelHeight#*0.8)? #Zoom2# : (([Text0:Y])<(#PanelHeight#*0.9)? #Zoom1# : #Zoom0#))))))))
DynamicVariables = 1
Sets the zoom variable based on the current Y position of the line being checked, line [Text0] in this case. The measures below for the other lines, set the zoom for each line of text. If you add or delete lines, these measures should be adjusted to match.
The measures use the Y value of the section variable; the next measure [mZoonLine1] will be identical except the section variable would point to [TEXT1:Y]. This is repeated for each measure matching the number of lines.
THE DISPLAY METERS
Controlling the scrolling is done only to the first meter [TEXT0], using the [MeasureY] measure.
The remaining text meters are set relative to the first one and will follow the scroll position.
I created a style for these meters since most attributes are common.
Here is the style and common text meter:
; ============== STYLE ===============================
[Style]
SolidColor = 0,0,0,1
FontColor = #TextColor#
FontEffectColor = 0,0,0,200
FontFace = #FontName#
FontSize = #FontHeight#
StringAlign = #TextAlign#
StringEffect = shadow
StringStyle = BOLDItalic
AntiAlias = 1
X = (#PanelWidth# * #TextAlignNum#)
Y = (#LineSpace#)r
W = (#PanelWidth#) - (#Margin#*2))
H = #LineSpace#
ClipString = 2
[Text1]
Meter = string
MeterStyle = Style
Text = #T1#
Hidden = (((#LineSpace#*1) + #LineHeight# + #PanelHeight# + ([MeasureY])) > (#PanelHeight# - #BottomMargin#))? 1 : ([Text1:Y] < #TopMargin#)?
LeftMouseUpAction = ["eclectic-tech.deviantart.com"]
ToolTipText = My DeviantArt Site
DynamicVariables = 1
Group = Text
TransformationMatrix = ([mZoomLine1]);0;0;([mZoomLine1]);((1 - ([mZoomLine1]))*#PanelWidth#/2);((1-([mZoomLine1]))*[#CURRENTSECTION#:Y])
All the other text meters are identical to this one; only the name and references are different:
[Text2]
Meter = string
MeterStyle = Style
Text = #T2#
Hidden = (((#LineSpace#*2) + #LineHeight# + #PanelHeight# + ([MeasureY])) > (#PanelHeight# - #BottomMargin#))? 1 : ([Text2:Y] < #TopMargin#)?
LeftMouseUpAction = ["#CURRENTPATH#scrolltext2shrink.ini"]
ToolTipText = See Skin Code
DynamicVariables = 1
Group = Text
TransformationMatrix = ([mZoomLine2]);0;0;([mZoomLine2]);((1 - ([mZoomLine2]))*#PanelWidth#/2);((1-([mZoomLine2]))*[#CURRENTSECTION#:Y])
Do notice that the 'HIDDEN=' calc multiplies the
#LineSpace# variable by incremental amounts!
ARE WE DONE YET? "ALMOST!"
Finally, we need to know when the last line item has reached the top or bottom of the display, so we can reverse or refresh the skin. Both example skins reverse the direction, but it is your option as what to do once the information has been displayed.
Here is the measure that checks the position of the last line [actually, it checks both the top and bottom line positions]:
[mLastLinePosRefresh]
Measure = Calc
Formula = ((#LineSpace# * #Lines#) + #PanelHeight# + (MeasureY)<0)? 1 : (((MeasureY)>0)? 2 : 0)
IfEqualValue = 1
IfEqualAction = [!SetVariable Speed (#Speed# - (#Speed#*2))][!Update]
; Use the formula below if a refresh is desired instead of reversal
;IfEqualAction = !Refresh
IfAboveValue = 1
IfAboveAction = [!SetVariable Speed (#DefaultSpeed#)][!Update]
; Use the formula below if a refresh is desired instead of reversal
;IfAboveAction = !Refresh
DynamicVariables = 1
Checks the position based on the amount of space for each item
#LineSpace# times the number of
#Lines#, plus the
#PanelHeight#, plus the current MeasureY, and if it is above (less than) the defined skin top (value is below '0') the scroll value is inverted AND if NOT, it checks if the top line (MeasureY) is below (greater than) it's initial position (value is above '0'), and if it is, the scroll is reset, otherwise it returns '0'.
The commented out 'If...Action=!Refresh' lines can be used to refresh the skin instead of reversing direction, if that is your choice.
SUMMARY
So with some tweaking, you should be able to create skins that move and transform the text being displayed. Perhaps not everyone's 'cup of tea', but that's what makes the world such a wonderfully diverse place. 'Beauty is in the eye of the beholder'.
Note: With TransformationMatrix meters, normal string alignment commands have little or no control, everything is done by way of the matrix transformations.
Eclectic Tech
eclectic-tech.deviantart.com
October 6, 2013