-
-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
All methods are called on the library instance obtained via LibStub:
local LibAnimate = LibStub("LibAnimate")LibAnimate:Animate(frame, animationName, options?) -> booleanPlays a registered animation on a frame.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The WoW frame to animate |
animationName |
string |
✅ | Name of a registered animation (e.g. "fadeInUp") |
options |
table |
❌ | Animation options (see below) |
| Field | Type | Default | Description |
|---|---|---|---|
duration |
number |
Animation's defaultDuration
|
Duration in seconds |
distance |
number |
Animation's defaultDistance
|
Travel distance in pixels |
delay |
number |
0 |
Delay in seconds before animation starts |
repeatCount |
number |
1 |
Number of times to play (0 = infinite) |
onFinished |
function(frame) |
nil |
Callback fired when animation completes naturally |
true if the animation started successfully.
- If the frame is already animating, the current animation is stopped and restored before the new one starts.
- Entrance animations move the frame from an offset to its current anchor position.
-
Exit animations move the frame away from its anchor. The frame is left at its final state - you should call
frame:Hide()inonFinished. - Attention animations animate in place and automatically return to the original state.
- If
delayis set, the frame remains in its pre-animation state for the specified duration before the animation begins. - If
repeatCountis greater than 1, the animation replays automatically. Use0for infinite looping. The delay only applies before the first play, not between repeats. -
onFinishedfires only after the final repeat completes. - The
onFinishedcallback receives the frame as its argument.
- Throws if
frameis not a valid WoW frame - Throws if
animationNameis not a registered animation - Throws if the frame does not have exactly one anchor point
LibAnimate:Animate(myFrame, "bounceIn", {
duration = 0.75,
distance = 400,
onFinished = function(frame)
print(frame:GetName() .. " finished animating!")
end,
})-- Pulse 3 times with a 0.5s delay before starting
LibAnimate:Animate(myFrame, "pulse", {
delay = 0.5,
repeatCount = 3,
onFinished = function(frame)
print("Done pulsing!")
end,
})
-- Loop infinitely until stopped
LibAnimate:Animate(myFrame, "heartBeat", {
repeatCount = 0,
})
-- Later: LibAnimate:Stop(myFrame)LibAnimate:Stop(frame)Stops any active animation on the frame and restores it to its pre-animation state (original anchor position, scale, and alpha).
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to stop animating |
- The
onFinishedcallback is not fired when stopping. - If the frame is not currently animating, this is a no-op.
- The frame's anchor, scale, and alpha are restored to the values captured when
Animate()was called. - If the frame has an active animation queue, the queue is also cleared.
-- Stop and let the frame return to where it was
LibAnimate:Stop(myFrame)LibAnimate:UpdateAnchor(frame, x, y)Updates the base anchor offsets of a frame that is currently animating. Use this when you need to reposition a frame (e.g., a notification moving up in a stack) while its animation continues.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame being animated |
x |
number |
✅ | New base X offset |
y |
number |
✅ | New base Y offset |
-- Move the notification's base position up while it's fading in
LibAnimate:UpdateAnchor(notificationFrame, 0, 200)LibAnimate:IsAnimating(frame) -> booleanChecks whether a frame currently has an active animation.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to check |
true if the frame is currently being animated by LibAnimate, false otherwise.
if LibAnimate:IsAnimating(myFrame) then
LibAnimate:Stop(myFrame)
endLibAnimate:Queue(frame, entries, opts?)Queues a sequence of animations to play one after another on a frame. Each entry can have its own duration, distance, delay, repeatCount, and completion callback.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The WoW frame to animate |
entries |
QueueEntry[] |
✅ | Array of animation steps |
opts |
QueueOpts |
❌ | Sequence-level options |
| Field | Type | Default | Description |
|---|---|---|---|
name |
string |
- | Animation name (required) |
duration |
number |
Animation default | Duration override in seconds |
distance |
number |
Animation default | Distance override in pixels |
delay |
number |
0 |
Delay before this step starts |
repeatCount |
number |
1 |
Repeat count (0 = infinite) |
onFinished |
function(frame) |
nil |
Called when this step completes |
| Field | Type | Description |
|---|---|---|
onFinished |
function(frame) |
Called when the entire sequence completes |
loop |
boolean |
When true, the queue restarts from the first entry after the last entry finishes |
- All animation names are validated upfront - an error is thrown immediately if any entry has an invalid name.
- Any existing animation or queue on the frame is stopped before the new queue starts.
- Per-step
onFinishedcallbacks fire before the next step begins. - The sequence-level
onFinishedfires after the last step completes. - Calling
Animate()directly on a queued frame clears the queue. - Calling
Stop()on a queued frame clears the queue and restores the frame. - When
loopistrue, the queue automatically restarts from entry 1 after the last entry completes. The sequence-levelonFinishedis not called while looping. - Use
ClearQueue()orStop()to end a looping queue.
LibAnimate:Queue(notificationFrame, {
{
name = "fadeInRight",
duration = 0.3,
distance = 300,
onFinished = function(f)
print("Toast visible!")
end,
},
{
name = "pulse",
delay = 0.2,
repeatCount = 2,
},
{
name = "fadeOutRight",
delay = 5.0,
distance = 300,
onFinished = function(f)
f:Hide()
end,
},
}, {
onFinished = function(f)
print("Toast lifecycle complete")
end,
})-- Looping idle animation
LibAnimate:Queue(idleFrame, {
{ name = "pulse", duration = 2.0 },
{ name = "heartBeat", duration = 1.3 },
}, {
loop = true,
})
-- Later: stop the loop
LibAnimate:ClearQueue(idleFrame)LibAnimate:ClearQueue(frame)Cancels the animation queue on a frame and stops the current animation. The frame is restored to its pre-animation state. No callbacks are fired.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to cancel the queue on |
LibAnimate:ClearQueue(notificationFrame)LibAnimate:IsQueued(frame) -> booleanReturns whether a frame has an active animation queue.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to check |
true if the frame has a pending animation queue, false otherwise.
LibAnimate:PauseQueue(frame)Pauses the currently playing animation on a queued frame, freezing it at its current progress. Any active SlideAnchor transition is also paused.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to pause |
- The animation freezes mid-progress and can be resumed with
ResumeQueue(). - If the frame is not animating or is already paused, this is a no-op.
- Any active
SlideAnchortransition on the frame is also frozen.
-- Pause a notification while the user hovers over it
frame:SetScript("OnEnter", function(self)
LibAnimate:PauseQueue(self)
end)LibAnimate:ResumeQueue(frame)Resumes a previously paused animation from exactly where it left off. Any paused SlideAnchor transition also resumes.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to resume |
- The animation continues from the exact progress point where it was paused.
- If the frame is not paused, this is a no-op.
- Any paused
SlideAnchortransition also resumes.
frame:SetScript("OnLeave", function(self)
LibAnimate:ResumeQueue(self)
end)LibAnimate:IsPaused(frame) -> booleanChecks whether a frame's animation is currently paused.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to check |
true if the frame has an active animation that is currently paused, false otherwise.
if LibAnimate:IsPaused(myFrame) then
LibAnimate:ResumeQueue(myFrame)
else
LibAnimate:PauseQueue(myFrame)
endLibAnimate:SlideAnchor(frame, newX, newY, duration)Smoothly interpolates the frame's base anchor position over a duration without interrupting the current animation. Useful for repositioning frames (e.g., notifications shifting in a stack) while their entrance/exit animations continue playing.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame being animated |
newX |
number |
✅ | Target base X offset |
newY |
number |
✅ | Target base Y offset |
duration |
number |
✅ | Slide duration in seconds |
- If the frame is not currently animating, this falls back to a direct
UpdateAnchor()call instead. - If a slide is already in progress, the current slide snaps to its target before the new slide begins.
- The slide respects pause state: while paused, the slide does not advance.
- The slide runs independently of the animation and continues across queue entry transitions.
-- Smoothly reposition a notification upward over 0.3 seconds
LibAnimate:SlideAnchor(notificationFrame, 0, 200, 0.3)
-- Chain: animate in, then slide to a new position
LibAnimate:Animate(frame, "fadeInRight", {
duration = 0.4,
distance = 300,
onFinished = function(f)
LibAnimate:SlideAnchor(f, 0, 100, 0.5)
end,
})LibAnimate:GetQueueInfo(frame) -> number | nil, number | nilReturns the current position and total size of a frame's animation queue.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame to query |
-
currentIndex(number | nil) - The 1-based index of the currently playing entry, ornilif no queue is active. -
totalEntries(number | nil) - The total number of entries in the queue, ornilif no queue is active.
local current, total = LibAnimate:GetQueueInfo(myFrame)
if current then
print("Playing entry " .. current .. " of " .. total)
endLibAnimate:SkipToEntry(frame, index)Jumps directly to a specific entry in the animation queue, skipping all intermediate steps.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame with an active queue |
index |
number |
✅ | The 1-based index of the target entry |
- The current animation is stopped and the target entry begins immediately.
- All skipped entries'
onFinishedcallbacks are not fired. - If the frame has no active queue or the index is out of range, this is a silent no-op.
-- Skip directly to the exit animation (entry 3)
LibAnimate:SkipToEntry(myFrame, 3)
-- Skip to the last entry
local _, total = LibAnimate:GetQueueInfo(myFrame)
if total then
LibAnimate:SkipToEntry(myFrame, total)
endLibAnimate:RemoveQueueEntry(frame, index)Removes a specific entry from the animation queue by its 1-based index.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame with an active queue |
index |
number |
✅ | The 1-based index of the entry to remove |
- Before current entry: The entry is removed and the queue index is decremented to keep the current animation unaffected.
- At current entry: The current animation is stopped and the next entry begins immediately.
- After current entry: The entry is simply removed from the queue.
- If the frame has no active queue or the index is out of range, this is a silent no-op.
-- Remove the delay step from a notification queue
local current, total = LibAnimate:GetQueueInfo(myFrame)
if total and total >= 2 then
LibAnimate:RemoveQueueEntry(myFrame, 2)
endLibAnimate:InsertQueueEntry(frame, entry, index?)Inserts a new entry into an active animation queue at the specified position.
| Parameter | Type | Required | Description |
|---|---|---|---|
frame |
Frame |
✅ | The frame with an active queue |
entry |
QueueEntry |
✅ | The queue entry to insert |
index |
number |
❌ | 1-based insertion position (appends to end if omitted) |
- The
entry.nameis validated against registered animations. An error is thrown if the animation does not exist. - If
indexis omitted or beyond the queue length, the entry is appended to the end. - If inserting before or at the currently playing entry, the queue index is incremented so the current animation continues uninterrupted.
- Entries inserted before the current index will not be played (they have already been passed).
- Works on both running and paused queues.
- Throws if
frameis nil - Throws if the frame has no active queue
- Throws if
entryis not a valid table - Throws if
entry.nameis not a registered animation
-- Append a pulse to the end of the queue
LibAnimate:InsertQueueEntry(myFrame, {
name = "pulse",
repeatCount = 2,
})
-- Insert an attention seeker before the exit animation
LibAnimate:InsertQueueEntry(myFrame, {
name = "tada",
duration = 0.8,
}, 2)LibAnimate:GetAnimationInfo(name) -> AnimationDefinition | nilReturns the full definition table for a registered animation, or nil if no animation with that name exists.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
✅ | The animation name to look up |
An AnimationDefinition table with the following fields:
| Field | Type | Description |
|---|---|---|
type |
string |
"entrance", "exit", or "attention"
|
defaultDuration |
number? |
Default duration in seconds |
defaultDistance |
number? |
Default distance in pixels |
keyframes |
table[] |
Array of keyframe tables |
local info = LibAnimate:GetAnimationInfo("fadeInUp")
if info then
print("Type:", info.type)
print("Duration:", info.defaultDuration)
print("Keyframes:", #info.keyframes)
endLibAnimate:GetAnimationNames() -> string[]Returns an alphabetically sorted list of all registered animation names.
A table of strings - all animation names currently registered.
local names = LibAnimate:GetAnimationNames()
for _, name in ipairs(names) do
print(name)
endLibAnimate:GetEntranceAnimations() -> string[]Returns an alphabetically sorted list of all animations with type = "entrance".
LibAnimate:GetExitAnimations() -> string[]Returns an alphabetically sorted list of all animations with type = "exit".
LibAnimate:GetAttentionAnimations() -> string[]Returns an alphabetically sorted list of all animations with type = "attention".
-- Print all attention seeker animations
local attention = LibAnimate:GetAttentionAnimations()
for _, name in ipairs(attention) do
print(name) -- bounce, flash, headShake, heartBeat, ...
endLibAnimate:RegisterAnimation(name, definition)Registers a custom animation that can then be played with Animate().
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
✅ | Unique name for the animation |
definition |
AnimationDefinition |
✅ | The animation definition table |
{
type = "entrance", -- "entrance", "exit", or "attention"
defaultDuration = 0.6, -- seconds (optional)
defaultDistance = 300, -- pixels (optional)
keyframes = { ... }, -- required, at least 2
}{
progress = 0.0, -- required: 0.0 to 1.0
translateX = 0, -- optional: fraction of distance (default 0)
translateY = 1.0, -- optional: fraction of distance (default 0)
scale = 0.7, -- optional: uniform scale (default 1.0)
alpha = 0.5, -- optional: opacity 0-1 (default 1.0)
easing = "easeOutCubic", -- optional: easing for segment STARTING at this keyframe
}-
namemust be a non-empty string -
typemust be"entrance","exit", or"attention" - Must have at least 2 keyframes
- Keyframes must be sorted by ascending
progress(0.0 to 1.0) - Overwrites any existing animation with the same name
Throws descriptive error messages on validation failure:
"name must be a non-empty string""definition must be a table""type must be 'entrance', 'exit', or 'attention'""keyframes must be a table with at least 2 entries""keyframes must be sorted by ascending progress"
LibAnimate:RegisterAnimation("myCustomFade", {
type = "entrance",
defaultDuration = 0.5,
keyframes = {
{ progress = 0.0, alpha = 0, scale = 0.8 },
{ progress = 0.6, alpha = 0.8, scale = 1.05, easing = "easeOutCubic" },
{ progress = 1.0, alpha = 1.0, scale = 1.0, easing = "easeInOutQuad" },
},
})
-- Now use it like any built-in animation
LibAnimate:Animate(myFrame, "myCustomFade")---@class AnimateOpts
---@field duration number? Duration in seconds
---@field distance number? Distance override in pixels
---@field delay number? Delay before animation starts
---@field repeatCount number? Number of times to play (0 = infinite)
---@field onFinished fun(frame: Frame)? Completion callback---@class QueueEntry
---@field name string Animation name
---@field duration number? Duration override in seconds
---@field distance number? Distance override in pixels
---@field delay number? Delay before this step starts
---@field repeatCount number? Repeat count (0 = infinite)
---@field onFinished fun(frame: Frame)? Step completion callback---@class QueueOpts
---@field onFinished fun(frame: Frame)? Sequence completion callback
---@field loop boolean? Restart queue from beginning after last entry---@class AnimationDefinition
---@field type "entrance"|"exit"|"attention"
---@field defaultDuration number?
---@field defaultDistance number?
---@field keyframes Keyframe[]---@class Keyframe
---@field progress number 0.0 to 1.0
---@field translateX number? Fraction of distance (default 0)
---@field translateY number? Fraction of distance (default 0)
---@field scale number? Uniform scale (default 1.0, min 0.001)
---@field alpha number? Opacity (default 1.0)
---@field easing EasingSpec? Easing for segment starting at this keyframe---@alias EasingSpec string | number[]
-- string: preset name (e.g. "easeOutCubic")
-- number[]: cubic-bezier control points {p1x, p1y, p2x, p2y}