View Transformations
View transformation enables a wide range of visual effects by manipulating views through translation, rotation, scaling, and skewing. These transformations are essential for creating dynamic, interactive designs, enhancing user experience with engaging visual content.
Below are the frequently used properties that participate in view transformation.
Property | Type | Description |
---|---|---|
"transform" | TransformProperty |
Auxiliary property which maintain view translation, rotation, scale, and skew |
"transform-origin-x" | SizeUnit |
The X-coordinate of the point around which a view transformation is applied |
"transform-origin-y" | SizeUnit |
The Y-coordinate of the point around which a view transformation is applied |
"transform-origin-z" | SizeUnit |
The Z-coordinate of the point around which a view transformation is applied |
"perspective" | SizeUnit |
Distance between the z-plane and the user in order to give a 3D-positioned view some perspective |
"perspective-origin-x" | SizeUnit |
The vanishing point of the "perspective" property |
"perspective-origin-y" | SizeUnit |
The vanishing point of the "perspective" property |
"backface-visibility" | bool |
Controls whether the back face of a view is visible when turned towards the user |
Besides these properties, there are others, but for simplicity, we'll cover them later on this page since they are just a shorthand to the "transform" property.
The "transform" property is a generic one and holds the value of the TransformProperty
interface.
An instance of that interface can be created using the global rui.NewTransformProperty()
function:
Go
func NewTransformProperty(params rui.Params) rui.TransformProperty
where rui.Params
is a map which can contain the following properties:
Property | Type | Description |
---|---|---|
"perspective" | SizeUnit |
Distance between the z-plane and the user in order to give a view some perspective transformation |
"rotate" | AngleUnit |
The angle of the view rotation around specified axis by "rotate-x", "rotate-y", and "rotate-z" properties |
"rotate-x" | float |
The X-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"rotate-y" | float |
The Y-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"rotate-z" | float |
The Z-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"scale-x" | float |
The X-axis scaling factor |
"scale-y" | float |
The Y-axis scaling factor |
"scale-z" | float |
The Z-axis scaling factor |
"skew-x" | AngleUnit |
The angle to use to distort the view along the X-axis |
"skew-y" | AngleUnit |
The angle to use to distort the view along the Y-axis |
"translate-x" | SizeUnit |
Translation of the view along X-axis |
"translate-y" | SizeUnit |
Translation of the view along Y-axis |
"translate-z" | SizeUnit |
Translation of the view along Z-axis |
As most of other properties of the view, "transform" can be set during the view creation process.
Go
view := rui.NewGridLayout(session, rui.Params{
rui.Width: rui.Percent(100),
rui.Height: rui.Percent(100),
// Center content on the screen
rui.CellHorizontalAlign: rui.CenterAlign,
rui.CellVerticalAlign: rui.CenterAlign,
rui.Content: rui.NewTextView(session, rui.Params{
rui.Text: "Transformed text",
rui.Transform: rui.NewTransformProperty(rui.Params{
rui.TranslateX: rui.Px(10), // Move view by 10 pixels in positive X-axis direction
rui.Rotate: rui.Deg(45), // Rotate the view by 45 degrees
rui.ScaleX: 0.9, // Scale down the view by 10%
rui.ScaleY: 0.9, // Scale down the view by 10%
}),
}),
})
Or we can change the property at any time using the Set()
method of the view or its global function variant.
Go
view.Set(rui.Transform, rui.NewTransformProperty(rui.Params{
rui.TranslateX: rui.Px(50), // Move view by 50 pixels in positive X-axis direction
rui.Rotate: rui.Deg(45), // Rotate the view by 45 degrees
rui.ScaleX: 0.9, // Scale down the view by 10%
rui.ScaleY: 0.9, // Scale down the view by 10%
}))
When describing that property in resource description file a specific object format is used:
RUI
_{
perspective = <size-value>,
rotate-x = <float-value>,
rotate-y = <float-value>,
rotate-z = <float-value>,
rotate = <angle-value>,
translate-x = <size-value>,
translate-y = <size-value>,
translate-z = <size-value>,
scale-x = <float-value>,
scale-y = <float-value>,
scale-z = <float-value>,
skew-x = <angle-value>,
skew-y = <angle-value>,
}
Where <float-value>
is a text representation of the float
value, <angle-value>
is a text representation of the AngleUnit
value, and <size-value>
is a text representation of the SizeUnit
value.
Transforming the view using the "transform" property from resource description file:
RUI
GridLayout {
width = 100%,
height = 100%,
// Center content on the screen
cell-horizontal-align = center,
cell-vertical-align = center,
content = TextView {
text = "Transformed text",
transform = _{
translate-x = 50px, // Move view by 50 pixels in positive X-axis direction
rotate = 45deg, // Rotate the view by 45 degrees
scale-x = 0.9, // Scale down the view by 10%
scale-y = 0.9, // Scale down the view by 10%
}
}
}
Here’s how the above examples look:
To read the actual values of the view transform, we can use the global rui.GetTransform()
function, which will return a TransformProperty
interface.
Go
if transform := rui.GetTransform(rootView, "view-id"); transform != nil {
if angle, ok := transform.Get(rui.Rotate).(rui.AngleUnit); ok {
// Do something with the angle value
}
// ...
}
The view also supports other transform-related properties, which may be convenient to use in some cases:
Property | Type | Description |
---|---|---|
"rotate" | AngleUnit |
The angle of the view rotation around specified axis or Z-axis by default |
"rotate-x" | float |
The X-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"rotate-y" | float |
The Y-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"rotate-z" | float |
The Z-coordinate of the vector denoting the axis of rotation in range 0 to 1 |
"scale-x" | float |
The X-axis scaling factor |
"scale-y" | float |
The Y-axis scaling factor |
"scale-z" | float |
The Z-axis scaling factor |
"skew-x" | AngleUnit |
The angle to use to distort the view along the X-axis |
"skew-y" | AngleUnit |
The angle to use to distort the view along the Y-axis |
"translate-x" | SizeUnit |
Translation of the view along X-axis |
"translate-y" | SizeUnit |
Translation of the view along Y-axis |
"translate-z" | SizeUnit |
Translation of the view along Z-axis |
They are exactly the same as what rui.TransformProperty
interface accepts.
When setting such properties library will first check whether the "transform" property has been set and if not will create it implicitly, then update its corresponding values.
Below are a few examples that use such properties.
RUI
GridLayout {
width = 100%,
height = 100%,
// Center content on the screen
cell-horizontal-align = center,
cell-vertical-align = center,
content = TextView {
text = "Transformed text",
translate-x = 50px, // Move view by 50 pixels in positive X-axis direction
rotate-z = 1.0, // Specify the vector over which the view will be rotated
rotate = 45deg, // Rotate the view by 45 degrees
scale-x = 0.9, // Scale down the view by 10%
scale-y = 0.9, // Scale down the view by 10%
}
}
Go
view := rui.NewGridLayout(session, rui.Params{
rui.Width: rui.Percent(100),
rui.Height: rui.Percent(100),
// Center content on the screen
rui.CellHorizontalAlign: rui.CenterAlign,
rui.CellVerticalAlign: rui.CenterAlign,
rui.Content: rui.NewTextView(session, rui.Params{
rui.Text: "Transformed text",
rui.TranslateX: rui.Px(10), // Move view by 10 pixels in positive X-axis direction
rui.RotateZ: 1.0, // Specify the vector over which the view will be rotated
rui.Rotate: rui.Deg(45), // Rotate the view by 45 degrees
rui.ScaleX: 0.9, // Scale down the view by 10%
rui.ScaleY: 0.9, // Scale down the view by 10%
}),
})
There is a set of convenient global functions we can use to get back the values of the listed properties. These functions are different from what we saw for other properties of the view. They return values for several transform-related properties at once:
Go
rotateX, rotateY, rotateZ, rotateAngle := rui.GetRotate(rootView, "view-id")
// Do something with the view rotation
scaleX, scaleY, scaleZ := rui.GetScale(rootView, "view-id")
// Do something with the view scaling
translateX, translateY, translateZ := rui.GetTranslate(rootView, "view-id")
// Do something with the view translation
skewX, skewY := rui.GetSkew(rootView, "view-id")
// Do something with the view slanting
For more information please refer to TransformProperty
interface and View
reference documentation.
All transformations of the view are applied against the origin point, by default this is the center of the view, but it can be changed using the "transform-origin-x", "transform-origin-y", and "transform-origin-z" properties.
These properties are not part of the "transform" property and must be set directly on the view.
We can use a different types of units here since properties hold the values of the SizeUnit
type.
Below is an example of how to scale the text starting from the left border of the view while hovering the mouse.
Go
// View creation code
view := rui.NewGridLayout(session, rui.Params{
rui.Width: rui.Percent(100),
rui.Height: rui.Percent(100),
// Center content on the screen
rui.CellHorizontalAlign: rui.CenterAlign,
rui.CellVerticalAlign: rui.CenterAlign,
rui.Content: rui.NewTextView(session, rui.Params{
rui.Text: "Transformed text",
rui.TransformOriginX: rui.Px(0), // The border of the view
rui.MouseOver: mouseOver, // Mouse over event handler
rui.MouseOut: mouseOut, // Mouse out event handler
}),
})
// mouseOver event handler function
func mouseOver(view rui.View, _ rui.MouseEvent) {
view.Set(rui.Transform, rui.NewTransformProperty(rui.Params{
rui.ScaleX: 1.1,
}))
}
// mouseOut event handler function
func mouseOut(view rui.View, _ rui.MouseEvent) {
view.Set(rui.Transform, rui.NewTransformProperty(rui.Params{
rui.ScaleX: 1,
}))
}
TODO: add explanation of 3D transform operations with examples and uncover properties which miss the explanations
Missing properties