KiteAsyncImage

fun KiteAsyncImage(model: Any?, contentDescription: String?, modifier: Modifier = Modifier, imageLoader: ImageLoader = SingletonImageLoader.get(LocalPlatformContext.current), alignment: Alignment = Alignment.Center, contentScale: ContentScale = ContentScale.Fit, alpha: Float = DefaultAlpha, colorFilter: ColorFilter? = null, filterQuality: FilterQuality = DrawScope.DefaultFilterQuality, animate: Boolean = true, placeholder: Painter? = null, error: Painter? = null, onSuccess: (SuccessResult) -> Unit? = null, onError: (ErrorResult) -> Unit? = null)

AsyncImage, but animations actually play: on every target.

Coil does what Coil is for: model goes through its full pipeline (network fetchers, disk cache, memory cache, request lifecycle) via imageLoader. Rendering is ours. When the result is a KiteAnimationImage (produced by a registered KiteImageDecoder), this composable plays it with KiteAnimatedImage's elapsed-time frame loop: per-frame delays, loop count, last-frame hold and no drift. That composable lives in kiteimage-compose, which this module depends on as implementation, so declare it yourself if you want to call it directly. Any other result renders exactly as AsyncImage would, via Image.asPainter.

The request carries this composable's layout constraints as its target size (unless model is an ImageRequest that already defines one), so KiteImageDecoder downscales still images and every animation frame to what will actually be drawn instead of decoding wallpaper-sized pixels for an avatar slot.

model may be anything Coil accepts as data, or a prebuilt ImageRequest (used as-is, plus the constraints size when it doesn't define its own). animate pins animated results to their first frame when false. placeholder shows while the request is in flight, error on failure; onSuccess / onError fire once per completed request.