Animation System
The Animation System provides property-based animations with 30+ easing functions for smooth transitions on all UI elements.
Quick Reference
Related Issues:
- #120 - Animation Property Locking (Tier 1 - Active)
- #119 - Animation Completion Callbacks (Closed - Implemented)
- #229 - Animation callbacks pass (target, property, value)
Key Files:
src/AnimationManager.h/src/AnimationManager.cpp- Animation execution enginesrc/Animation.h- Base Animation classsrc/UIDrawable.h- Animatable properties defined here
The .animate() Method
The primary way to create animations is the .animate() method available on all UI elements:
import mcrfpy
frame = mcrfpy.Frame(pos=(100, 100), size=(200, 150))
# animate(property, target_value, duration_seconds, easing)
frame.animate("x", 500.0, 2.0, mcrfpy.Easing.EASE_IN_OUT)
frame.animate("opacity", 0.5, 1.0, mcrfpy.Easing.EASE_OUT_QUAD)
Parameters:
property(str): Name of the property to animatetarget_value: End value (float, int, or Color tuple)duration(float): Duration in secondseasing(Easing): Easing function frommcrfpy.Easingenumcallback(optional): Function called on completion
Animatable Properties by Type
Frame
| Property | Type | Notes |
|---|---|---|
x, y |
float | Position |
w, h |
float | Size |
outline |
float | Outline thickness |
opacity |
float | 0.0 to 1.0 |
fill_color |
Color | Animate as (r, g, b, a) tuple |
outline_color |
Color | Animate as (r, g, b, a) tuple |
Caption
| Property | Type | Notes |
|---|---|---|
x, y |
float | Position |
opacity |
float | 0.0 to 1.0 |
outline |
float | Text outline thickness |
fill_color |
Color | Text fill color |
outline_color |
Color | Text outline color |
Sprite
| Property | Type | Notes |
|---|---|---|
x, y |
float | Position |
scale |
float | Uniform scale factor |
sprite_index |
int | Sprite sheet index (truncated to int) |
opacity |
float | 0.0 to 1.0 |
Grid
| Property | Type | Notes |
|---|---|---|
x, y |
float | Position on screen |
w, h |
float | Viewport size |
center_x, center_y |
float | Camera pan position |
zoom |
float | Camera zoom level |
Entity (must be attached to a Grid)
| Property | Type | Notes |
|---|---|---|
x, y |
float | Alias for draw position |
draw_x, draw_y |
float | Visual position in tile coordinates |
sprite_index |
int | Sprite sheet index |
sprite_scale |
float | Entity sprite scale |
Easing Functions (mcrfpy.Easing)
30+ easing functions are available:
Basic:
Easing.LINEAREasing.EASE_IN,Easing.EASE_OUT,Easing.EASE_IN_OUT
Families (each has _IN, _OUT, _IN_OUT variants):
QUAD- QuadraticCUBIC- CubicQUART- QuarticSINE- SinusoidalEXPO- ExponentialCIRC- CircularELASTIC- Elastic springBACK- OvershootBOUNCE- Bouncing
Example: Easing.EASE_IN_OUT_CUBIC, Easing.EASE_OUT_BOUNCE, Easing.EASE_IN_ELASTIC
Completion Callbacks
Animation callbacks receive (target, property, final_value):
def on_complete(target, prop, value):
print(f"{type(target).__name__}.{prop} reached {value}")
frame.animate("x", 500.0, 2.0, mcrfpy.Easing.EASE_IN_OUT, callback=on_complete)
Callback arguments:
target: The animated object (Frame, Sprite, Entity, etc.)prop(str): Property name that was animated (e.g.,"x","opacity")value: Final value (float, int, or(r, g, b, a)tuple for colors)
Chaining Animations
Use callbacks to create animation sequences:
def step2(target, prop, value):
target.animate("y", 300.0, 1.0, mcrfpy.Easing.EASE_OUT_BOUNCE)
def step1(target, prop, value):
target.animate("x", 500.0, 1.0, mcrfpy.Easing.EASE_IN_OUT, callback=step2)
frame.animate("opacity", 1.0, 0.5, mcrfpy.Easing.EASE_IN, callback=step1)
Note: It is safe to start new animations from within callbacks, including animations on the same target and property.
Execution Model
Pure C++ Execution:
- Animations run in the C++ update loop - no Python callbacks per frame
- High performance: thousands of concurrent animations
- Frame-independent: adjusts for variable frame times
Lifecycle:
- Created via
.animate()call - AnimationManager updates each frame
- Auto-destroyed on completion or target destruction
- Weak pointer tracking prevents use-after-free
Conflicting Animations: Multiple animations on the same property will conflict. The most recently created animation takes precedence. Property locking (#120) is planned to prevent this.
Color Animations
Animate colors by targeting fill_color or outline_color:
# Fade to red fill
frame.animate("fill_color", (255, 0, 0, 255), 1.0, mcrfpy.Easing.EASE_IN)
# Animate outline to transparent
frame.animate("outline_color", (255, 255, 255, 0), 0.5, mcrfpy.Easing.LINEAR)
Color animations interpolate each channel (R, G, B, A) independently.
Common Patterns
Smooth Entity Movement
def move_entity(entity, target_x, target_y, speed=0.3):
entity.animate("x", float(target_x), speed, mcrfpy.Easing.EASE_OUT_QUAD)
entity.animate("y", float(target_y), speed, mcrfpy.Easing.EASE_OUT_QUAD)
Fade In/Out
# Fade in
frame.opacity = 0.0
frame.animate("opacity", 1.0, 0.5, mcrfpy.Easing.EASE_IN)
# Fade out and remove
def remove_on_fade(target, prop, value):
# Remove from parent scene
pass # implement removal logic
frame.animate("opacity", 0.0, 0.5, mcrfpy.Easing.EASE_OUT, callback=remove_on_fade)
Pulse/Breathing Effect
def pulse(target, prop, value):
if value > 0.8:
target.animate("opacity", 0.3, 1.0, mcrfpy.Easing.EASE_IN_OUT_SINE, callback=pulse)
else:
target.animate("opacity", 1.0, 1.0, mcrfpy.Easing.EASE_IN_OUT_SINE, callback=pulse)
frame.animate("opacity", 0.3, 1.0, mcrfpy.Easing.EASE_IN_OUT_SINE, callback=pulse)
Camera Pan
grid.animate("center_x", target_x * 16.0, 0.5, mcrfpy.Easing.EASE_IN_OUT)
grid.animate("center_y", target_y * 16.0, 0.5, mcrfpy.Easing.EASE_IN_OUT)
Animation Object (Advanced)
The mcrfpy.Animation class can be used directly for more control, though .animate() is preferred:
anim = mcrfpy.Animation("x", 500.0, 2.0, mcrfpy.Easing.LINEAR, callback=my_callback)
anim.start(frame)
This is functionally equivalent to frame.animate("x", 500.0, 2.0, mcrfpy.Easing.LINEAR, callback=my_callback).
Related Systems
- UI-Component-Hierarchy - All UIDrawable objects are animatable
- Grid-System - Grid viewport animations (zoom, pan)
- Input-and-Events - Trigger animations from input callbacks
- Performance-and-Profiling - Animation time tracked separately
Last updated: 2026-02-07