Transform and opacity helpers.
Emerge.UI.Transform changes how an element is painted without changing how a
row, column, or generic container measures and places that element.
Use:
move_x/1andmove_y/1to offset the painted element in logical pixelsrotate/1to turn an element around its centerscale/1to grow or shrink an element around its centeralpha/1to reduce opacity for the rendered element subtree
Layout vs Paint
Transforms do not reserve extra layout space. The element keeps its normal layout slot, then the transform is applied when rendering.
This is useful for lifted cards, pressed states, emphasis, decorative tilt, and motion styles that should not push siblings around.
Interaction
Pointer hit testing follows the transformed shape that the user sees on screen, not the pre-transform slot. Hover, press, and move handlers stay attached to the painted result.
Opacity
alpha/1 affects the rendered element subtree. Background, border, text,
images, and children all inherit that opacity while layout stays unchanged.
Examples
Translation moves the painted element while the row still keeps its original slot:
row(
[
width(px(340)),
spacing(16),
padding(12),
Background.color(color(:slate, 900)),
Border.rounded(12)
],
[
el(
[
width(px(140)),
height(px(72)),
Transform.move_x(26),
Transform.move_y(8),
Background.color(color(:slate, 100)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 800))
],
column([center_x(), center_y(), spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Moved")),
el([Font.size(11), Font.color(color(:slate, 500))], text("+26px, +8px"))
])
),
el(
[
width(px(140)),
height(px(72)),
Background.color(color(:slate, 50)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 700))
],
column([center_x(), center_y(), spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Layout slot")),
el([Font.size(11), Font.color(color(:slate, 500))], text("Still placed normally"))
])
)
]
)
Rotation and scale both happen around the element center:
row(
[
width(px(360)),
spacing(24),
padding(12),
Background.color(color(:slate, 900)),
Border.rounded(12)
],
[
el(
[
width(px(150)),
height(px(84)),
Transform.rotate(-10),
Background.color(color(:slate, 100)),
Border.rounded(14),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 800))
],
column([center_x(), center_y(), spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Rotate")),
el([Font.size(11), Font.color(color(:slate, 500))], text("Around the center"))
])
),
el(
[
width(px(150)),
height(px(84)),
Transform.scale(1.14),
Background.color(color(:slate, 50)),
Border.rounded(14),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 800))
],
column([center_x(), center_y(), spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Scale")),
el(
[Font.size(11), Font.color(color(:slate, 500))],
text("Same slot, bigger paint")
)
])
)
]
)
Opacity is useful for de-emphasized branches without changing layout:
row(
[
width(px(320)),
spacing(12),
padding(12),
Background.color(color(:slate, 900)),
Border.rounded(12)
],
[
el(
[
width(fill()),
padding(12),
Background.color(color(:slate, 50)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 900))
],
column([spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Primary")),
el([Font.size(11), Font.color(color(:slate, 500))], text("Fully visible"))
])
),
el(
[
width(fill()),
padding(12),
Background.color(color(:slate, 50)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Transform.alpha(0.45),
Font.color(color(:slate, 900))
],
column([spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Archived")),
el([Font.size(11), Font.color(color(:slate, 500))], text("Same layout, lower emphasis"))
])
)
]
)
The faint outline below marks the original slot. The transformed card is what the user sees and what pointer hit testing follows:
el(
[
width(px(360)),
height(px(180)),
padding(20),
Background.color(color(:slate, 900)),
Border.rounded(14)
],
el(
[
width(px(128)),
height(px(76)),
center_x(),
center_y(),
Background.color(color_rgba(248, 250, 252, 0.72)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Border.dashed(),
Font.color(color(:slate, 400)),
Nearby.in_front(
el(
[
width(fill()),
height(fill()),
Transform.move_x(40),
Transform.move_y(-8),
Transform.rotate(-10),
Background.color(color(:slate, 100)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 300)),
Font.color(color(:slate, 800))
],
column([center_x(), center_y(), spacing(4)], [
el([Font.size(14), Font.semi_bold()], text("Painted card")),
el(
[Font.size(11), Font.color(color(:slate, 500))],
text("Hit testing follows this")
)
])
)
)
],
el([center_x(), center_y(), Font.size(11)], text("Original slot"))
)
)
Summary
Functions
Set opacity for the rendered element subtree.
Move the painted element on the X axis.
Move the painted element on the Y axis.
Rotate the painted element in degrees around its center.
Scale the painted element uniformly around its center.
Types
Functions
Set opacity for the rendered element subtree.
Use values between 0.0 and 1.0, where 0.0 is fully transparent and
1.0 is fully opaque.
Example
This dims the whole card, including its text and border.
el(
[
padding(12),
Transform.alpha(0.45),
Background.color(color(:white)),
Border.rounded(12),
Border.width(1),
Border.color(color(:slate, 200))
],
text("Archived")
)
Move the painted element on the X axis.
Positive values move right. Negative values move left. The layout slot does not move.
Example
el(
[
width(px(120)),
height(px(64)),
Transform.move_x(18),
Background.color(color(:sky, 600)),
Border.rounded(12),
Font.color(color(:white))
],
text("Shifted")
)
Move the painted element on the Y axis.
Positive values move down. Negative values move up. The layout slot does not move.
Example
A subtle downward nudge is useful for pressed or resting floating-card states.
el(
[
width(px(120)),
height(px(64)),
Transform.move_y(6),
Background.color(color(:emerald, 600)),
Border.rounded(12),
Font.color(color(:white))
],
text("Lowered")
)
Rotate the painted element in degrees around its center.
Rotation does not change the element's layout slot.
Example
el(
[
width(px(140)),
height(px(72)),
Transform.rotate(-8),
Background.color(color(:violet, 600)),
Border.rounded(12),
Font.color(color(:white))
],
text("Tilted note")
)
Scale the painted element uniformly around its center.
1.0 keeps the original size, values above 1.0 enlarge, and values between
0.0 and 1.0 shrink.
Example
el(
[
width(px(140)),
height(px(72)),
Transform.scale(1.1),
Background.color(color(:amber, 500)),
Border.rounded(12),
Font.color(color(:slate, 950))
],
text("Emphasized")
)