Draggable
Built-in drag behavior for GuiObjects
Overview
Set Draggable = true on a GuiObject to enable built-in dragging. You can also provide OnDragStart, OnDrag, and OnDragEnd callbacks.
Example
local New = Katalyst.New
local win = New("Frame")({
Draggable = true,
OnDragEnd = function(self, pos)
print("dropped at", pos)
end,
})Drag callbacks: signatures and behavior
-
OnDragStart(self, startPos: UDim2, inputPos: Vector2)- Called once when the user begins dragging (mouse down or touch).
startPosis the GuiObject's startingPosition(UDim2) at drag start.inputPosis the input's position (Vector2) at the start.- Use this to capture initial state or veto/prepare dragging.
-
OnDrag(self, delta: Vector2, inputPos: Vector2)- Called continuously while dragging with the change in input since the last event.
deltais the Vector2 difference from the previous input position.inputPosis the current input position.- If
Draggable = true, Katalyst will automatically update the GuiObject'sPositionbased on the accumulated delta. You can useOnDragto update other state (for example, a visual indicator) or to clamp/mutate the position further.
-
OnDragEnd(self, inputPos: Vector2)- Called once when dragging ends (input ends).
inputPosis the last input position.- Use this to finalize state, persist the new position, or run cleanup/tweens.
Example: custom clamped drag
local New = Katalyst.New
local win = New("Frame")({
Draggable = true,
OnDragStart = function(self, startPos, inputPos)
self.BackgroundColor3 = Color3.fromRGB(240,240,240)
self._startPos = startPos
end,
OnDrag = function(self, delta, inputPos)
-- clamp movement to keep the frame inside the screen bounds
local inst = self()
local newX = inst.Position.X.Offset + delta.x
local newY = inst.Position.Y.Offset + delta.y
-- naive clamp (example), adapt for Scale+Offset mixing
newX = math.clamp(newX, 0, 800)
newY = math.clamp(newY, 0, 600)
inst.Position = UDim2.new(inst.Position.X.Scale, newX, inst.Position.Y.Scale, newY)
end,
OnDragEnd = function(self, inputPos)
print("drag finished at", inputPos)
self.BackgroundColor3 = Color3.fromRGB(255,255,255)
end,
})Notes
-
The runtime uses
UserInputService.InputChangedto track movement; drag events use the same input source to ensure smooth tracking across mouse and touch. -
OnDragdelta values are relative between consecutive input events — accumulate or apply immediately depending on your use case. -
If you need more advanced behavior (snapping, inertia), implement it in
OnDragEndor wrap the dragging logic in a small reusable component. -
Important: event handlers still work when
Draggableis false- Katalyst wires
OnDragStart,OnDrag, andOnDragEndwhen those props are present even ifDraggableis nottrue. That means your handlers will still be called if input begins and moves over the element. - The
Draggableprop controls whether Katalyst automatically updates the GuiObject'sPositionduring dragging. IfDraggableisfalse, Katalyst will not auto-move the instance — use the handlers to implement custom movement or constraints instead. - In short: provide handlers without
Draggableto implement fully custom drag logic; setDraggable = trueif you want Katalyst to handle position changes for you.
- Katalyst wires
