Collisions
Aether provides a way of detecting (and avoiding) collisions, via detectOverflow()
.
detectOverflow()
detects when the floating or reference element is overflowing a clipping container or custom boundary.
Visibility optimizer middleware use this function for collision detection, making it useful for your own custom middleware that do the same.
Understanding Boundaries
A boundary (or clipping container) is an area that causes child elements inside it to be clipped if they overflow it.
detectOverflow
takes two types of boundaries:
"boundary"
which is the area that overflow will be checked relative to."rootBoundary"
which is the "root" area that overflow will be checked relative to. This sounds like it has the same purpose as"boundary"
, but the "root" is there because it involves screen boundaries.
More info can be found in the config.
Example
Here's an example of a custom middleware using detectOverflow()
:
- luau
- roblox-ts
local Aether = require(path.to.aether)
local middleware: Aether.Middleware = {
name = "middleware",
run = function(state)
local overflow = Aether.detectOverflow(state)
return {}
end,
}
import { detectOverflow, type Middleware } from "@rbxts/aether";
const middleware: Middleware = {
name: "middleware",
run: (state) => {
const overflow = detectOverflow(state);
return {}
},
};
The returned value, overflow
, is a SideObject
containing side properties with numbers representing offsets.
- A positive number means the element is overflowing the clipping boundary by that number of pixels. (more pixels = further away from the boundary)
- A negative number means the element has that number of pixels left before it will overflow the clipping boundary. (less pixels = closer to the boundary)
0
means the side lies flush with the clipping boundary.
Config
detectOverflow()
takes a config as a second argument:
- luau
- roblox-ts
type DetectOverflowConfig = {
boundary: Boundary?,
rootBoundary: RootBoundary?,
elementContext: ElementContext?,
altBoundary: boolean?,
padding: Padding?
}
interface DetectOverflowConfig {
boundary?: Boundary;
rootBoundary?: RootBoundary;
elementContext?: ElementContext;
altBoundary?: boolean;
padding?: Padding;
}
boundary
- luau
- roblox-ts
type Boundary = "clipping-ancestors" | GuiObject | { GuiObject } | Rect
type Boundary = "clipping-ancestors" | GuiObject | GuiObject[] | Rect;
This describes the clipping element(s) or area that overflow will be checked relative to. The default is "clipping-ancestors"
, which are the overflow ancestors which will cause the element to be clipped.
You can also pass multiple GuiObject
s, or a custom Rect
.
An "overflow ancestor" is a GuiObject
that has ClipsDescendants
enabled.
rootBoundary
- luau
- roblox-ts
type RootBoundary = "layer-collector" | Rect
type RootBoundary = "layer-collector" | Rect;
This describes the root boundary that the element will be checked for overflow relative to. The default is "layer-collector"
, which is the ancestor LayerCollector that contains the element. Most of the time, this could just be known as the screen area.
You may also pass a Rect
object to define a custom boundary area (relative to the screen).
elementContext
- luau
- roblox-ts
type ElementContext = "reference" | "target"
type ElementContext = "reference" | "target";
By default, the "target"
element is the one being checked for overflow.
But you can also change the context to "reference"
to instead check its overflow relative to its clipping boundary.
altBoundary
This is a boolean value which determines whether to check the alternate elementContext
’s boundary.
For instance, if the elementContext
is "target"
, and you enable this option, then the boundary in which overflow is checked for is the "reference"
’s boundary. This only applies if you are using the default "clipping-ancestors"
string as the boundary.
padding
This describes the virtual Padding around the boundary to check for overflow.