Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compose-util 모듈 업데이트 #7

Merged
merged 4 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.lemon.core.compose.util
package io.lemon.core.compose.util.modifier

import androidx.compose.foundation.Indication
import androidx.compose.foundation.clickable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package io.lemon.core.compose.util.modifier

import android.graphics.BlurMaskFilter
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawOutline
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp

/**
* @param shape 그림자에 적용할 모양
* @param color 그림자 색상
* @param offset 그림자의 위치
* @param blur 그림자 흐림 효과 (번짐의 정도)
* @param spread 그림자의 확산효과이며, 그림자의 크기;
* 음수로 할 경우 그림자의 크기가 기존 도형보다 줄어듭니다.
*/
fun Modifier.dropShadow(
shape: Shape,
color: Color,
offset: DpOffset,
blur: Dp = 1.dp,
spread: Dp = 0.dp
) = drawBehind {

drawIntoCanvas { canvas ->
canvas.save()
canvas.translate(dx = offset.x.toPx(), dy = offset.y.toPx()) // 캔버스 위치 이동
canvas.drawOutline(
outline = shape.createOutline(
size = Size(
width = size.width + spread.toPx(),
height = size.height + spread.toPx()
),
layoutDirection = layoutDirection,
density = this
), // 그림자 사이즈 구성
paint = Paint().apply {
this.color = color
blur.toPx().takeIf { it > 0f }?.let { radius ->
asFrameworkPaint().apply {
maskFilter = BlurMaskFilter(
/* radius = */ radius,
/* style = */ BlurMaskFilter.Blur.NORMAL
)
}
}
} // 그림자 스타일 구성
) // 그림자 생성
canvas.restore()
}
}

/**
* @param shape 그림자에 적용할 모양
* @param color 그림자 색상
* @param yOffset 그림자의 y 오프셋
* @param xOffset 그림자의 x 오프셋
* @param blur 그림자 흐림 효과 (번짐의 정도)
* @param spread 그림자의 확산효과이며, 그림자의 크기;
* 음수로 할 경우 그림자의 크기가 기존 도형보다 줄어듭니다.
*/
fun Modifier.dropShadow(
shape: Shape,
color: Color,
yOffset: Dp = 0.dp,
xOffset: Dp = 0.dp,
blur: Dp = 1.dp,
spread: Dp = 0.dp
) = drawBehind {

drawIntoCanvas { canvas ->
canvas.save()
canvas.translate(dx = xOffset.toPx(), dy = yOffset.toPx()) // 캔버스 위치 이동
canvas.drawOutline(
outline = shape.createOutline(
size = Size(
width = size.width + spread.toPx(),
height = size.height + spread.toPx()
),
layoutDirection = layoutDirection,
density = this
), // 그림자 사이즈 구성
paint = Paint().apply {
this.color = color
blur.toPx().takeIf { it > 0f }?.let { radius ->
asFrameworkPaint().apply {
maskFilter = BlurMaskFilter(
/* radius = */ radius,
/* style = */ BlurMaskFilter.Blur.NORMAL
)
}
}
} // 그림자 스타일 구성
) // 그림자 생성
canvas.restore()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package io.lemon.core.compose.util.modifier

import androidx.compose.foundation.Indication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.selection.toggleable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.semantics.Role
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
* Toggle interaction 이 연속적으로 발생하는 것을 방지하는 확장자
*/
fun Modifier.throttleToggleable(
value: Boolean,
onValueChange: (Boolean) -> Unit,
enabled: Boolean = true,
role: Role? = null,
coroutineDispatcher: CoroutineDispatcher = Dispatchers.Main,
throttleTime: Long = 250L,
) = composed {
val coroutineScope = rememberCoroutineScope { coroutineDispatcher }
var lastEmissionTime: Long by remember { mutableLongStateOf(0L) }

toggleable(
value = value,
onValueChange = {
val currentTime = System.currentTimeMillis()
if (currentTime - lastEmissionTime >= throttleTime) {
coroutineScope.launch {
lastEmissionTime = currentTime
onValueChange(it)
}
}
lastEmissionTime = currentTime
},
enabled = enabled,
role = role,
)
}

/**
* Toggle interaction 이 연속적으로 발생하는 것을 방지하는 확장자
*/
fun Modifier.throttleToggleable(
value: Boolean,
onValueChange: (Boolean) -> Unit,
interactionSource: MutableInteractionSource = MutableInteractionSource(),
indication: Indication? = null,
enabled: Boolean = true,
role: Role? = null,
coroutineDispatcher: CoroutineDispatcher = Dispatchers.Main,
throttleTime: Long = 250L,
) = composed {
val coroutineScope = rememberCoroutineScope { coroutineDispatcher }
var lastEmissionTime: Long by remember { mutableLongStateOf(0L) }

noRippleToggleable(
value = value,
onValueChange = {
val currentTime = System.currentTimeMillis()
if (currentTime - lastEmissionTime >= throttleTime) {
coroutineScope.launch {
lastEmissionTime = currentTime
onValueChange(it)
}
}
lastEmissionTime = currentTime
},
interactionSource = remember { interactionSource },
indication = indication,
enabled = enabled,
role = role
)
}

/**
* Toggle interaction 중 발생하는 시각 이펙트를 제거하는 확장자
*/
fun Modifier.noRippleToggleable(
value: Boolean,
onValueChange: (Boolean) -> Unit,
interactionSource: MutableInteractionSource = MutableInteractionSource(),
indication: Indication? = null,
enabled: Boolean = true,
role: Role? = null,
) = composed {
toggleable(
value = value,
interactionSource = remember { interactionSource },
indication = indication,
enabled = enabled,
onValueChange = onValueChange,
role = role
)
}