Optimize compose async thumb clip

This commit is contained in:
tarsin committed 2023-04-06 15:28:09 +08:00
1 parent e7c077c31e
commit 8a542aebe2
1 file changed
+33 -31
@@ -1,5 +1,6 @@
package com.hippo.ehviewer.ui.widget
import android.graphics.drawable.BitmapDrawable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
@@ -7,22 +8,22 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter
import coil.request.ImageRequest
import com.google.accompanist.drawablepainter.DrawablePainter
import com.hippo.drawable.PreciselyClipDrawable
import com.hippo.ehviewer.client.data.GalleryPreview
import com.hippo.ehviewer.coil.ehUrl
@Composable
@ReadOnlyComposable
fun requestOf(model: String?): ImageRequest {
return ImageRequest.Builder(LocalContext.current).apply {
model?.let { ehUrl(it) }
}.build()
return ImageRequest.Builder(LocalContext.current).apply { model?.let { ehUrl(it) } }.build()
}
@Composable
@@ -37,6 +38,12 @@ fun EhAsyncThumb(
contentScale = contentScale,
)
private val GalleryPreview.shouldClip
get() = offsetX != Int.MIN_VALUE
/**
* Show a part of the original drawable, non-animated only implementation.
*/
@Composable
fun EhAsyncPreview(
model: GalleryPreview,
@@ -48,38 +55,33 @@ fun EhAsyncPreview(
contentDescription = "",
modifier = modifier,
transform = {
if (it is AsyncImagePainter.State.Success) {
model.run {
if (offsetX == Int.MIN_VALUE) {
it
} else {
it.copy(
painter = DrawablePainter(
PreciselyClipDrawable(
it.result.drawable,
offsetX,
offsetY,
clipWidth,
clipHeight,
),
),
)
}
model.run {
if (it is AsyncImagePainter.State.Success && shouldClip) {
it.copy(
painter = BitmapPainter(
(it.result.drawable as BitmapDrawable).bitmap.asImageBitmap(),
IntOffset(offsetX, offsetY),
IntSize(clipWidth, clipHeight - 1),
),
)
} else {
it
}
} else {
it
}
},
onState = {
if (it is AsyncImagePainter.State.Success) {
it.result.drawable.run {
if (intrinsicWidth.toFloat() / intrinsicHeight in 0.5..0.8) {
if (contentScale == ContentScale.Fit) contentScale = ContentScale.Crop
}
}
model.run {
if (clipWidth.toFloat() / clipHeight in 0.5..0.8) {
if (contentScale == ContentScale.Fit) contentScale = ContentScale.Crop
if (shouldClip) {
if (clipWidth.toFloat() / clipHeight in 0.5..0.8) {
if (contentScale == ContentScale.Fit) contentScale = ContentScale.Crop
}
} else {
it.result.drawable.run {
if (intrinsicWidth.toFloat() / intrinsicHeight in 0.5..0.8) {
if (contentScale == ContentScale.Fit) contentScale = ContentScale.Crop
}
}
}
}
}