IntAnimationLib — Integer Animation Library

Animates integer properties of visual controls. While most visual properties (position, opacity, scale) are floats, integer animation excels at animating counters, scores, progress percentages, and Tag-based values with smooth interpolation. The Tag property — an integer available on every control — makes this library a powerful tool for driving custom logic via the onprocess callback. 46 functions.

CategoryCountDescription
Error Handling4intani_error, errormsg$, strerror$, clearerror
Creation & Destruction3intani# (2 overloads), intani_free
Playback Control3start, stop, stopatcurrent
Core Properties10propertyname, startvalue, stopvalue, duration, delay (get/set)
Behavior — Easing4animationtype, interpolation (get/set)
Behavior — Flags10autoreverse, inverse, loop, enabled, startfromcurrent (get/set)
State Queries3running, normalizedtime, name$
Triggers4trigger, triggerinverse (get/set)
Events5onfinish, onprocess (get/set), clearcallbacks#

Cross-Platform Support

PlatformStatusNotes
Windows✅ Full SupportWin32/Win64
Linux✅ Full SupportGTK-based
Android✅ Full SupportHardware-accelerated

Error Handling

FunctionSignatureDescription
intani_error()intani_error@Last error code (0 = no error)
intani_errormsg$()intani_errormsg$@Last error message as string
intani_strerror$(code)intani_strerror$@nDescription for a given error code
intani_clearerror()intani_clearerror@Clear the error state

Error Codes

CodeConstantDescription
0ERR_NONENo error
1ERR_NIL_ANIMATIONAnimation pointer is nil
2ERR_INVALID_PROPERTYInvalid property name or object
3ERR_INVALID_VALUEInvalid parameter value
4ERR_ANIMATION_RUNNINGCannot modify while animation is running

How It Works

The integer animation smoothly transitions a single integer property from a start value to a stop value over a given duration. The most common pattern uses the Tag property (available on all controls) combined with an onprocess callback to update the UI on every frame:

╯ basic pattern
' 1. Create the animation on a control
let ani# = intani#(myLabel#)

' 2. REQUIRED: set which property to animate
intani_propertyname#(ani#, "Tag")

' 3. Set integer range
intani_startvalue#(ani#, 0)
intani_stopvalue#(ani#, 100)

' 4. Set timing
intani_duration#(ani#, 5.0)

' 5. Set callback to react to value changes
intani_onprocess#(ani#, "OnUpdate")

' 6. Start!
intani_start(ani#)

function OnUpdate(sender#) local val
    val = label_tag(myLabel#)
    label_text#(myLabel#, "Value: " + str$(val))
endfunction
⚠ Required: You MUST set intani_propertyname# before starting the animation. Without it, the animation will not run. Use "Tag" as the property name for most use cases.

Int vs Float Animation

Most FireMonkey visual properties (Position, Opacity, Scale, RotationAngle) are float-based. Use FloatAnimationLib for those. IntAnimationLib is designed specifically for:

Use CaseRecommended LibraryWhy
Move a control (Position.X/Y)FloatAnimationLibPosition is a float property
Fade a control (Opacity)FloatAnimationLibOpacity is a float (0.0–1.0)
Rotate a control (RotationAngle)FloatAnimationLibAngle is a float
Animate a counter (0 → 100)IntAnimationLibTag is an integer
Animate a score displayIntAnimationLibScores are whole numbers
Drive a progress bar percentageIntAnimationLibClean integer steps (0%–100%)
Countdown timer (10 → 0)IntAnimationLibWhole second display

Interpolation & Easing

Interpolation Curves

InterpolationCharacterBest For
"Linear"Constant speedCounters, timers, steady progress
"Quadratic"Gentle curveSmooth progress bars
"Cubic"Moderate curveScore reveals
"Quartic"Pronounced curveDramatic number reveals
"Quintic"Very pronouncedEmphatic counter effects
"Sinusoidal"Sine-wave smoothnessNatural-feeling transitions
"Exponential"Sharp start or endFast ramp-up/ramp-down
"Circular"Arc-basedOrbital counting effects
"Elastic"Springy overshootBouncy score counters
"Back"Overshoots then settlesAttention-grabbing numbers
"Bounce"Bouncing ball effectPlayful score reveals

Easing Types (AnimationType)

TypeEffectDescription
"In"Slow start → fast endAcceleration at the beginning
"Out"Fast start → slow endDeceleration at the end
"InOut"Slow → fast → slowAccelerate then decelerate

Creation & Destruction

FunctionSignatureDescription
intani#(parent#)intani#@#Create animation attached to parent control
intani#(parent#, name$)intani#@#$Create named animation attached to parent
intani_free(ani#)intani_free@#Destroy animation object

Playback Control

FunctionSignatureDescription
intani_start(ani#)intani_start@#Start the animation
intani_stop(ani#)intani_stop@#Stop and reset to start value
intani_stopatcurrent(ani#)intani_stopatcurrent@#Stop at current interpolated value

Core Properties

Property Name

FunctionSignatureDescription
intani_propertyname#(ani#, name$)intani_propertyname#@#$REQUIRED — Set which property to animate
intani_propertyname$(ani#)intani_propertyname$@#Get the property name

Value Range

FunctionSignatureDescription
intani_startvalue#(ani#, value)intani_startvalue#@#nSet starting integer value
intani_startvalue(ani#)intani_startvalue@#Get starting value
intani_stopvalue#(ani#, value)intani_stopvalue#@#nSet ending integer value
intani_stopvalue(ani#)intani_stopvalue@#Get ending value

Timing

FunctionSignatureDescription
intani_duration#(ani#, seconds)intani_duration#@#nSet duration in seconds
intani_duration(ani#)intani_duration@#Get duration
intani_delay#(ani#, seconds)intani_delay#@#nSet delay before animation starts
intani_delay(ani#)intani_delay@#Get delay

Behavior Flags

Easing & Interpolation

FunctionSignatureDescription
intani_animationtype#(ani#, type$)intani_animationtype#@#$Set easing: "In", "Out", "InOut"
intani_animationtype$(ani#)intani_animationtype$@#Get current easing type
intani_interpolation#(ani#, type$)intani_interpolation#@#$Set interpolation curve
intani_interpolation$(ani#)intani_interpolation$@#Get current interpolation type

Boolean Flags

FunctionSignatureDescription
intani_autoreverse#(ani#, flag)intani_autoreverse#@#nIf 1, plays forward then backward
intani_autoreverse(ani#)intani_autoreverse@#Get autoreverse flag
intani_inverse#(ani#, flag)intani_inverse#@#nIf 1, plays in reverse direction
intani_inverse(ani#)intani_inverse@#Get inverse flag
intani_loop#(ani#, flag)intani_loop#@#nIf 1, loops indefinitely
intani_loop(ani#)intani_loop@#Get loop flag
intani_enabled#(ani#, flag)intani_enabled#@#nEnable or disable the animation
intani_enabled(ani#)intani_enabled@#Get enabled state
intani_startfromcurrent#(ani#, flag)intani_startfromcurrent#@#nIf 1, begins from current property value
intani_startfromcurrent(ani#)intani_startfromcurrent@#Get startfromcurrent flag

State Queries

FunctionSignatureDescription
intani_running(ani#)intani_running@#Returns 1 if currently animating
intani_normalizedtime(ani#)intani_normalizedtime@#Returns progress from 0.0 to 1.0
intani_name$(ani#)intani_name$@#Get the animation’s name

Triggers

Triggers let an animation start or reverse automatically when a parent property changes, without calling intani_start manually.

FunctionSignatureDescription
intani_trigger#(ani#, expr$)intani_trigger#@#$Set trigger expression (starts animation)
intani_trigger$(ani#)intani_trigger$@#Get trigger expression
intani_triggerinverse#(ani#, expr$)intani_triggerinverse#@#$Set inverse trigger (reverses animation)
intani_triggerinverse$(ani#)intani_triggerinverse$@#Get inverse trigger expression

Events

Each event has a setter and a getter. Use intani_clearcallbacks# to disconnect all at once.

Event SetterGetterCallback SignatureDescription
intani_onfinish#(ani#, func$)intani_onfinish$(ani#)function name(sender#)Fired when animation completes
intani_onprocess#(ani#, func$)intani_onprocess$(ani#)function name(sender#)Fired on every animation frame
intani_clearcallbacks#(ani#)Disconnect all callbacks
ⓘ Key pattern: The onprocess callback is the heart of integer animation. Inside it, read the control’s Tag property (which the animation is updating) and use that value to update your UI — labels, progress bars, or any other visual element.

Complete Examples

Counter Animation (0 to 100)

╯ counter.bas
let frm# = form#("Counter Demo", 400, 200)
form_position#(frm#, 4)

let lbl# = label#(frm#, "Count: 0")
label_move#(lbl#, 130, 80)
label_fontsize#(lbl#, 28)

' Animate Tag from 0 to 100 over 5 seconds
let intAni# = intani#(lbl#)
intani_propertyname#(intAni#, "Tag")
intani_startvalue#(intAni#, 0)
intani_stopvalue#(intAni#, 100)
intani_duration#(intAni#, 5.0)
intani_interpolation#(intAni#, "Linear")
intani_onprocess#(intAni#, "updatecount")
intani_start(intAni#)

form_show(frm#)

function updatecount(sender#) local tagval
    tagval = label_tag(lbl#)
    label_text#(lbl#, "Count: " + str$(tagval))
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Countdown Timer (10 to 0)

╯ countdown.bas
let frm# = form#("Countdown Demo", 300, 200)
form_position#(frm#, 4)

let lbl# = label#(frm#, "10")
label_move#(lbl#, 120, 70)
label_fontsize#(lbl#, 48)

let intAni# = intani#(lbl#)
intani_propertyname#(intAni#, "Tag")
intani_startvalue#(intAni#, 10)
intani_stopvalue#(intAni#, 0)
intani_duration#(intAni#, 10.0)
intani_interpolation#(intAni#, "Linear")
intani_onprocess#(intAni#, "showcountdown")
intani_onfinish#(intAni#, "countdone")
intani_start(intAni#)

form_show(frm#)

function showcountdown(sender#) local tagval
    tagval = label_tag(lbl#)
    label_text#(lbl#, str$(tagval))
endfunction

function countdone(sender#)
    label_text#(lbl#, "Done!")
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Progress Bar

╯ progress.bas
let frm# = form#("Progress Demo", 400, 150)
form_position#(frm#, 4)

let progressBg# = rectangle#(frm#, 50, 50, 300, 30)
rectangle_fill#(progressBg#, "#ecf0f1")

let progressBar# = rectangle#(frm#, 50, 50, 0, 30)
rectangle_fill#(progressBar#, "#27ae60")

let lbl# = label#(frm#, "0%")
label_move#(lbl#, 180, 90)

' Animate Tag 0-100, use onprocess to update bar width
let intAni# = intani#(progressBar#)
intani_propertyname#(intAni#, "Tag")
intani_startvalue#(intAni#, 0)
intani_stopvalue#(intAni#, 100)
intani_duration#(intAni#, 3.0)
intani_interpolation#(intAni#, "Quadratic")
intani_animationtype#(intAni#, "Out")
intani_onprocess#(intAni#, "updateprogress")
intani_start(intAni#)

form_show(frm#)

function updateprogress(sender#) local pct
    pct = rectangle_tag(progressBar#)
    label_text#(lbl#, str$(pct) + "%")
    rectangle_width#(progressBar#, pct * 3)
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Score with Bounce Effect

╯ score.bas
let frm# = form#("Score Demo", 400, 200)
form_position#(frm#, 4)

let lbl# = label#(frm#, "Score: 0")
label_move#(lbl#, 120, 80)
label_fontsize#(lbl#, 24)

' Bounce-eased score counter: 0 to 1000
let intAni# = intani#(lbl#)
intani_propertyname#(intAni#, "Tag")
intani_startvalue#(intAni#, 0)
intani_stopvalue#(intAni#, 1000)
intani_duration#(intAni#, 2.0)
intani_interpolation#(intAni#, "Bounce")
intani_animationtype#(intAni#, "Out")
intani_onprocess#(intAni#, "updatescore")
intani_start(intAni#)

form_show(frm#)

function updatescore(sender#) local score
    score = label_tag(lbl#)
    label_text#(lbl#, "Score: " + str$(score))
endfunction

while form_visible(frm#) = 1
    processmessages()
end while

Best Practices

PracticeWhy
Always set intani_propertyname#(ani#, "Tag")Required — animation will not run without it
Use "Tag" as the property for most casesAvailable on all controls, perfect for driving onprocess logic
Read the Tag in onprocess to update UIThe Tag is silently updated; you reflect the change visually
Declare local variables on the function linePlan9Basic requires: function name(sender#) local var1, var2
Use "Linear" for timers and steady countersOther curves make the counting speed uneven
Use "Bounce" + "Out" for playful score revealsCreates an engaging bouncing number effect
Use "Quadratic" + "Out" for progress barsFast start, gentle deceleration feels natural
Prefer FloatAnimationLib for visual propertiesPosition, Opacity, Scale, RotationAngle are float properties
Use onfinish for completion actionsTrigger next step, show “Done!” message, start another animation

Quick Reference

FunctionSignatureDescription
intani_error / errormsg$ / strerror$ / clearerrorvariousError handling (4)
intani#(parent#[, name$])intani#@# / intani#@#$Create (2 overloads)
intani_free(ani#)intani_free@#Destroy
intani_start / stop / stopatcurrentvariousPlayback control (3)
intani_propertyname# / propertyname$variousTarget property (2)
intani_startvalue / stopvaluevariousValue range (4)
intani_duration / delayvariousTiming (4)
intani_animationtype / interpolationvariousEasing & curves (4)
intani_autoreverse / inverse / loop / enabled / startfromcurrentvariousBehavior flags (10)
intani_running / normalizedtime / name$variousState queries (3)
intani_trigger / triggerinversevariousAutomatic triggers (4)
intani_onfinish / onprocess / clearcallbacks#variousEvents (5)

46 functions. Part of the Plan9Basic Animation library system.