Skip to content

Playback ​

The playback rules are the same on every platform. They are state of the view, not part of the indicator spec. Try them here:

1.00

A speed of 0 or less pauses the clock. Changing the speed never makes the animation jump.

null

With reduce motion on, engines draw a still frame at cycleProgress 0 instead of animating.

Options
{
  "indicator": "BallSpinFadeLoader",
  "animating": true,
  "speed": 1,
  "hidesWhenStopped": true,
  "cycleProgress": null,
  "respectsReduceMotion": true
}

Property names ​

ConceptWebAndroid ViewComposeiOS, macOSWindows
Speedspeedspeedspeedspeed, .speed()Speed
Start and stopanimating, start(), stop()isAnimating, start(), stop()animatingisAnimating, startAnimating(), stopAnimating(), .animating()IsAnimating
Hide when stoppedhidesWhenStoppedhidesWhenStoppednot availablehidesWhenStopped, .hidesWhenStopped()HidesWhenStopped
Freeze a framecycleProgresscycleProgresscycleProgresscycleProgress, .cycleProgress()CycleProgress
Reduced motionrespectsReduceMotionrespectsReduceMotionrespectsReduceMotionrespectsReduceMotion, .respectsReduceMotion()RespectsReduceMotion

On the <loader-kit> element, the attributes are speed, animating, hides-when-stopped, cycle-progress and respects-reduce-motion.

Speed ​

speed is a playback rate. The default is 1, the speed of the spec. 2 is twice as fast, 0.5 is half as fast. A speed of 0 or less pauses the indicator.

Changing the speed never makes the animation jump. The engine keeps a clock and only changes how fast it advances.

html
<loader-kit indicator="SquareSpin" speed="0.5"></loader-kit>
kotlin
loader.speed = 0.5
kotlin
LoaderKitIndicator("SquareSpin", speed = 0.5)
swift
LoaderKitIndicator("SquareSpin").speed(0.5)
xml
<lk:LoaderKitIndicator Indicator="SquareSpin" Speed="0.5" />

Start and stop ​

Stopping freezes the current frame. Starting again continues from that frame, not from the beginning.

With hidesWhenStopped (true by default, like UIActivityIndicatorView), a stopped indicator draws nothing. Set it to false to keep the frozen frame visible.

html
<loader-kit indicator="BallPulse" animating="false" hides-when-stopped="false"></loader-kit>
ts
view.hidesWhenStopped = false;
view.stop();
view.start();
kotlin
loader.hidesWhenStopped = false
loader.stop()
loader.start()
kotlin
// Compose has no hidesWhenStopped: show or remove the composable instead.
if (isLoading) LoaderKitIndicator("BallPulse")
swift
LoaderKitIndicator("BallPulse")
    .animating(isLoading)
    .hidesWhenStopped(false)
xml
<lk:LoaderKitIndicator IsAnimating="{x:Bind ViewModel.IsBusy, Mode=OneWay}" HidesWhenStopped="False" />

Freeze a frame with cycleProgress ​

cycleProgress draws one still frame at a point of the animation cycle, from 0 to 1. Use it for screenshot tests, previews and design reviews. Set it back to null (nil in Swift) to resume the clock from where it was.

It is not a progress bar

cycleProgress does not show how much of a task is done. 0.5 is the middle of one loop of the animation. An indicator does not fill up as the value goes from 0 to 1. To show progress, use a progress indicator.

The engine skips whole cycles until every element has started. So in a frozen frame, no element is still waiting for its stagger delay.

html
<loader-kit indicator="BallPulse" cycle-progress="0.25"></loader-kit>
kotlin
loader.cycleProgress = 0.25   // null resumes. In XML: app:cycleProgress="0.25"
kotlin
LoaderKitIndicator("BallPulse", cycleProgress = 0.25)
swift
LoaderKitIndicator("BallPulse").cycleProgress(0.25)
csharp
indicator.CycleProgress = 0.25;
indicator.CycleProgress = null;   // the clock resumes from where it was

Reduced motion ​

When the user asks the system for reduced motion, LoaderKit draws a still frame (the frame at cycleProgress 0) instead of animating. This is on by default. Set respectsReduceMotion to false only when the animation carries meaning the user needs.

PlatformSystem setting
Webthe prefers-reduced-motion: reduce media query
Androidanimations turned off (Accessibility > Remove animations, or an animator duration scale of 0)
iOSSettings > Accessibility > Motion > Reduce Motion
macOSSystem Settings > Accessibility > Display > Reduce motion
WindowsSettings > Accessibility > Visual effects > Animation effects turned off

What restarts the animation ​

ChangeEffect
Indicator name, spec or paramsrestarts the clock at 0
Color, colors, speed, sizeno restart
Stop, then startcontinues from the frozen frame
Set, then clear cycleProgresscontinues from where the clock was

On Android, the clock also pauses while the view is detached or hidden. On iOS and the other UIKit platforms, animations resume when the app returns to the foreground or the view moves to a new window. On macOS, they resume when the view moves to a new window.

Reusing a view ​

Native views can be recycled in a list. reset() restores every property to its default and restarts the animation:

kotlin
loader.reset()
swift
loader.reset()

Released under the MIT License.