11package com.maxrave.simpmusic.extension
22
3+ import androidx.compose.ui.graphics.lerp as colorLerp
34import android.app.Activity
45import android.content.Context
56import android.content.ContextWrapper
@@ -25,6 +26,7 @@ import androidx.compose.foundation.layout.calculateStartPadding
2526import androidx.compose.foundation.layout.fillMaxWidth
2627import androidx.compose.foundation.lazy.LazyListItemInfo
2728import androidx.compose.foundation.lazy.LazyListState
29+ import androidx.compose.foundation.lazy.grid.LazyGridState
2830import androidx.compose.material3.ExperimentalMaterial3Api
2931import androidx.compose.material3.SheetState
3032import androidx.compose.material3.SheetValue
@@ -46,6 +48,7 @@ import androidx.compose.ui.BiasAlignment
4648import androidx.compose.ui.Modifier
4749import androidx.compose.ui.composed
4850import androidx.compose.ui.draw.DrawModifier
51+ import androidx.compose.ui.draw.blur
4952import androidx.compose.ui.draw.drawBehind
5053import androidx.compose.ui.geometry.Offset
5154import androidx.compose.ui.geometry.Rect
@@ -55,9 +58,11 @@ import androidx.compose.ui.graphics.ColorFilter
5558import androidx.compose.ui.graphics.ColorMatrix
5659import androidx.compose.ui.graphics.Paint
5760import androidx.compose.ui.graphics.Shape
61+ import androidx.compose.ui.graphics.TransformOrigin
5862import androidx.compose.ui.graphics.asImageBitmap
5963import androidx.compose.ui.graphics.drawscope.ContentDrawScope
6064import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
65+ import androidx.compose.ui.graphics.layer.GraphicsLayer
6166import androidx.compose.ui.graphics.painter.BitmapPainter
6267import androidx.compose.ui.graphics.painter.Painter
6368import androidx.compose.ui.layout.boundsInWindow
@@ -72,6 +77,7 @@ import androidx.compose.ui.text.TextStyle
7277import androidx.compose.ui.unit.Dp
7378import androidx.compose.ui.unit.IntSize
7479import androidx.compose.ui.unit.dp
80+ import androidx.compose.ui.util.lerp
7581import androidx.core.app.PictureInPictureModeChangedInfo
7682import androidx.core.content.res.ResourcesCompat
7783import androidx.core.graphics.ColorUtils
@@ -81,6 +87,8 @@ import com.kmpalette.palette.graphics.Palette
8187import com.kyant.backdrop.Backdrop
8288import com.kyant.backdrop.drawBackdrop
8389import com.kyant.backdrop.effects.blur
90+ import com.kyant.backdrop.effects.colorControls
91+ import com.kyant.backdrop.effects.colorFilter
8492import com.kyant.backdrop.effects.dispersion
8593import com.kyant.backdrop.effects.refraction
8694import com.kyant.backdrop.effects.saturation
@@ -97,6 +105,7 @@ import kotlin.math.cos
97105import kotlin.math.hypot
98106import kotlin.math.max
99107import kotlin.math.min
108+ import kotlin.math.sign
100109import kotlin.math.sin
101110import kotlin.random.Random
102111
@@ -464,6 +473,37 @@ fun LazyListState.isScrollingUp(): Boolean {
464473 }.value
465474}
466475
476+ @Composable
477+ fun LazyGridState.isScrollingUp (): State <Boolean > {
478+ var previousIndex by remember(this ) { mutableIntStateOf(firstVisibleItemIndex) }
479+ var previousScrollOffset by remember(this ) { mutableIntStateOf(firstVisibleItemScrollOffset) }
480+
481+ LaunchedEffect (Unit ) {
482+ snapshotFlow { layoutInfo.totalItemsCount }.collect {
483+ Logger .w(" isScrollingUp" , " firstVisibleItemIndex: $firstVisibleItemIndex " )
484+ previousIndex = firstVisibleItemIndex
485+ previousScrollOffset = firstVisibleItemScrollOffset
486+ }
487+ }
488+
489+ return remember(this ) {
490+ derivedStateOf {
491+ if (firstVisibleItemIndex > 0 ) {
492+ if (previousIndex != firstVisibleItemIndex) {
493+ previousIndex > firstVisibleItemIndex
494+ } else {
495+ previousScrollOffset >= firstVisibleItemScrollOffset
496+ }.also {
497+ previousIndex = firstVisibleItemIndex
498+ previousScrollOffset = firstVisibleItemScrollOffset
499+ }
500+ } else {
501+ true
502+ }
503+ }
504+ }
505+ }
506+
467507@Suppress(" DEPRECATION" )
468508fun setStatusBarsColor (
469509 @ColorInt color : Int ,
@@ -579,33 +619,35 @@ fun animateAlignmentAsState(targetAlignment: Alignment): State<Alignment> {
579619
580620fun Modifier.drawBackdropCustomShape (
581621 backdrop : Backdrop ,
622+ layer : GraphicsLayer ,
623+ luminanceAnimation : Float ,
582624 shape : Shape ,
583- alpha : Float = 0.3f,
584625): Modifier =
585626 this .drawBackdrop(
586627 backdrop = backdrop,
587- shapeProvider = { shape },
588- onDrawSurface = {
589- drawRect(
590- Color .Black .copy(alpha = alpha.coerceIn(0f , 1f )),
628+ effects = {
629+ val l = (luminanceAnimation * 2f - 1f ).let { sign(it) * it * it }
630+ colorControls(
631+ brightness =
632+ if (l > 0f ) lerp(0.1f , 0.5f , l)
633+ else lerp(0.1f , - 0.2f , - l),
634+ contrast =
635+ if (l > 0f ) lerp(1f , 0f , l)
636+ else 1f ,
637+ saturation = 1.5f
638+ )
639+ blur(
640+ if (l > 0f ) lerp(8f .dp.toPx(), 16f .dp.toPx(), l)
641+ else lerp(8f .dp.toPx(), 2f .dp.toPx(), - l)
591642 )
643+ refraction(24f .dp.toPx(), size.minDimension / 2f , true )
592644 },
593- ) {
594- // saturation boost
595- saturation()
596- // blur
597- // lens
598- refraction(
599- height = 16f .dp.toPx(),
600- amount = 84f .dp.toPx(),
601- hasDepthEffect = true ,
602- )
603- dispersion(
604- height = 12 .dp.toPx(),
605- amount = 24 .dp.toPx(),
606- )
607- blur(6 .dp.toPx())
608- }
645+ onDrawBackdrop = { drawBackdrop ->
646+ drawBackdrop()
647+ layer.record { drawBackdrop() }
648+ },
649+ shape = { shape },
650+ )
609651
610652@Composable
611653fun PaddingValues.copy (
0 commit comments