@ -10,7 +10,7 @@ import org.jetbrains.skia.Codec
import java.net.MalformedURLException
import java.net.MalformedURLException
import java.net.URL
import java.net.URL
private const val DEFAULT _FRAME _DURATION = 5 0
private const val DEFAULT _FRAME _DURATION = 10 0
actual class AnimatedImage ( val codec : Codec )
actual class AnimatedImage ( val codec : Codec )
@ -26,42 +26,50 @@ actual suspend fun loadResourceAnimatedImage(path: String): AnimatedImage {
@Composable
@Composable
actual fun AnimatedImage . animate ( ) : ImageBitmap {
actual fun AnimatedImage . animate ( ) : ImageBitmap {
val transition = rememberInfiniteTransition ( )
when ( codec . frameCount ) {
val frameIndex by transition . animateValue (
0 -> return ImageBitmap . Blank // No frames at all
initialValue = 0 ,
1 -> {
targetValue = codec . frameCount - 1 ,
// Just one frame, no animation
Int . VectorConverter ,
val bitmap = remember ( codec ) { Bitmap ( ) . apply { allocPixels ( codec . imageInfo ) } }
animationSpec = infiniteRepeatable (
remember ( bitmap ) {
animation = keyframes {
codec . readPixels ( bitmap , 0 )
durationMillis = 0
for ( ( index , frame ) in codec . framesInfo . withIndex ( ) ) {
index at durationMillis
val frameDuration = calcFrameDuration ( frame )
durationMillis += frameDuration
}
}
}
)
return bitmap . asComposeImageBitmap ( )
)
}
else -> {
val transition = rememberInfiniteTransition ( )
val frameIndex by transition . animateValue (
initialValue = 0 ,
targetValue = codec . frameCount - 1 ,
Int . VectorConverter ,
animationSpec = infiniteRepeatable (
animation = keyframes {
durationMillis = 0
for ( ( index , frame ) in codec . framesInfo . withIndex ( ) ) {
index at durationMillis
val frameDuration = calcFrameDuration ( frame )
val bitmap = remember ( codec ) { Bitmap ( ) . apply { allocPixels ( codec . imageInfo ) } }
durationMillis += frameDuration
}
}
)
)
remember ( bitmap , frameIndex ) {
val bitmap = remember ( codec ) { Bitmap ( ) . apply { allocPixels ( codec . imageInfo ) } }
codec . readPixels ( bitmap , frameIndex )
}
remember ( bitmap , frameIndex ) {
codec . readPixels ( bitmap , frameIndex )
}
return bitmap . asComposeImageBitmap ( )
return bitmap . asComposeImageBitmap ( )
}
}
}
}
private fun calcFrameDuration ( frame : AnimationFrameInfo ) : Int {
private fun calcFrameDuration ( frame : AnimationFrameInfo ) : Int {
var frameDuration = frame . duration
// If the frame does not contain information about a duration, set a reasonable constant duration
// If the frame does not contain information about a duration, set a reasonable constant duration
if ( frameDuration == 0 ) {
val frameDuration = frame . duration
frameDuration = DEFAULT _FRAME _DURATION
return if ( frameDuration == 0 ) DEFAULT _FRAME _DURATION else frameDuration
}
return frameDuration
}
}
/ * *
/ * *