Skip to main content

Utility

Aether provides different utility functions to help with usage of the library.

getPlacementPosition​

This is useful for when you have a value with a Placement type and need to extract the side and/or the alignment.

local Aether = require(path.to.aether)

local side, alignment = Aether.getPlacementPosition("top-start")
print(side, alignment) -- "top" "start"

local side, alignment = Aether.getPlacementPosition("bottom")
print(side, alignment) -- "bottom" "nil"

getOppositePlacement​

Returns the opposite side part of a given placement.

The opposite sides are as follows:

  • "top" - "bottom"
  • "bottom" - "top"
  • "left" - ""right"
  • "right" - "left"
local Aether = require(path.to.aether)

local placement = Aether.getOppositePlacement("top-start")
print(placement) -- "bottom-start"

getOppositeAlignmentPlacement​

Returns the opposite alignment part of a given placement.

The opposite alignments are as follows:

  • "start" - "end"
  • "end" - "start"
local Aether = require(path.to.aether)

local placement = Aether.getOppositeAlignmentPlacement("top-start")
print(placement) -- "top-end"

getExpandedPlacements​

Provides all possible alternative values for a given placement, excluding the initial placement itself.

local Aether = require(path.to.aether)

local placements = Aether.getExpandedPlacements("top-start")
print(placements) -- "{ "top-end", "bottom-start", "bottom-end" }"

getOppositeAxisPlacements​

Returns all of the possible placements from the opposite axis of a given placement.

The following parameters can be passed:

placement​

The placement to extract from.

flipAlignment​

When the given placement has an alignment and this is set to true, the returned placements will include the opposite alignment placements as well.

direction​

The alignment to start from. This affects the order of placements.

For example, when the side of the placement is set to top or bottom, and the direction is set to start, the opposite side order becomes [left, right]. Conversely, a direction of end or none results in [right, left].

note

When rtl is set to true, the resulting value is flipped to the opposite end of its usual direction.

rtl​

When set to true, right-to-left calculations will be used instead.

Example​

local Aether = require(path.to.aether)

local placements = Aether.getOppositeAxisPlacements("top-start", true, "start")

-- Since flipAlignment is `true`, we have an extra two values that are both opposite alignments.
-- The direction is also "start", so the order is [left, right].

print(placements) -- { "left-start", "bottom-start", "left-end", "bottom-end" }

getAlignmentSides​

Returns the two possible sides of a given placement, listed in order as the main side followed by the cross (opposite) side.

The following parameters can be passed:

placement​

The placement to extract from.

rects​

The element rects to use. Typically, this will be the rects value provided by middleware.

rtl​

Default value: false

When set to true, right-to-left calculations will be used instead.

Example​

local Aether = require(path.to.aether)

-- Lets say "rects" is derived from `state.rects` via middleware.
local main, cross = Aether.getAlignmentSides("top-start", rects)

print(main, cross) -- - "bottom", "top";
note

The length (dimension) of the elements provided via rects is considered during the process, based on the axis variant of the given placement's alignment.

If the reference element's length exceeds that of the target element, the main side is flipped to its opposite direction, making the cross side its counterpart.

getElementBoundingRect​

Returns the BoundingRect of a given element, with extra calculations to get the precise area.

The following parameters can be passed:

element​

The element to calculate the rect for. This can be a virtual element.

includeScale​

When set to true, the ancestor UIScale's will be accounted for in the calculation. I.e., values will be scaled down based on the final factor.

offsetParent​

The element to calculate relative to. When includeScale is set to true, the ancestor UIScale's of this element will be considered instead of the given element. Note that offsetParent is typically just the Parent property of the element, and it also doesn't have to necessarily be accessed off of element itself.

cache​

The lifecycle cache

getElementRects​

Takes in the elements and returns the element Rect objects.

The following parameters can be passed:

reference​

The x and y values of a reference Rect should be its coordinates relative to the floating element’s Parent element if required rather than the screen.

target​

Both x and y are not relevant initially, so you can set these both of these to 0.

cache​

The lifecycle cache

getClippingRect​

Returns the Rect (relative to the screen) whose outside bounds will clip the given element. For instance, the screen itself.

The following parameters can be passed:

element​

The GuiObject to calculate the clipping rect for.

boundary​

The boundary to use.

rootBoundary​

The root boundary to use.

cache​

The lifecycle cache

getScale​

Returns the scale of the given element.

The scale of an element is the factor of each ancestor UIScale that affects it.

element​

The element to check

cache​

The lifecycle cache

getOffsetParent​

Returns the "offset" parent of the given element.

The "offset" parent is the first valid parent of the given element. Most of the time,this is just the Parent value, but there are cases where a Folder instance may be used. Because of that, this is useful for being safe.

element​

The element to get the parent from.

getLayerElement​

Returns the contaning LayerCollector instance of the given element, if one exists.

element​

The element to retrieve from.

convertOffsetParentRectToRelativeRect​

Converts the given rect into a rect that is relative to that of the given offset parent.

rect​

The rect to go off of.

offsetParent​

The offset parent element.

cache​

The lifecycle cache

isElement​

Determines if the passed value is a GuiObject.

local Aether = require(path.to.aether)

local reference = Instance.new("Frame")

print(Aether.isElement(reference)) -- true

unwrapElement​

Used for unwrapping an element into its GuiObject form, if viable. For example, extracting the contextElement from a virtual element when present.

If the element is already a GuiObject then that will be returned.

local Aether = require(path.to.aether)

local reference = Instance.new("Frame")

print(Aether.unwrapElement(reference)) -- Frame

local contextElement = Instance.new("TextLabel")
local reference: Aether.VirtualElement = {
getBoundingRect = function()
return ...
end,

contextElement = contextElement,
}

print(Aether.unwrapElement(reference)) -- TextLabel

convertRectToBoundingRect​

Converts a Rect into its BoundingRect form.

local Aether = require(path.to.aether)

local rect: Aether.Rect = {
x = 5,
y = 10,
width = 15,
height = 20,
}

local result = Aether.convertRectToBoundingRect(rect)

--[[
Resulting BoundingRect:

x: 5,
y: 10,
width: 15,
height: 15,
left: 5,
top: 10,
left: 5,
right: 20,
bottom: 30,
]]

isSameRect​

Returns true if two Rect objects are the same (i.e., the same values).

local Aether = require(path.to.aether)

local one: Aether.Rect = {
x = 0,
y = 0,
width = 0,
height = 0,
}

local two: Aether.Rect = {
x = 0,
y = 0,
width = 10,
height = 10,
}

print(isSameRect(one, one)) -- "true"
print(isSameRect(one, two)) -- "false"

read​

Allows you to evaluate middleware input when it is derivable, being able to take advantage of passing the lifecycle.

local Aether = require(path.to.aether)

local function middleware(input: Aether.Derivable<number>): Aether.Middleware
return {
name = "middleware",
run = function(state)
local value = Aether.read(input, state)
-- ...
end
}
end

getPaddingObject​

This is used for converting a Padding value into a usable SideObject.

local Aether = require(path.to.aether)

local padding = Aether.getPaddingObject(5)

--[[
The padding value will be:

top: 5,
bottom: 5,
left: 5,
right: 5,
]]

local padding = Aether.getPaddingObject({
top = 5,
bottom = 5,
})

--[[
The padding value will be:

top: 5,
bottom: 5,
left: 0,
right: 0,
]]
note

When providing a SideObject value, any omitted sides are automatically evaluated as 0.