Skip to content

Instantly share code, notes, and snippets.

@V-Abhilash-1999
Created May 23, 2023 12:30
Show Gist options
  • Save V-Abhilash-1999/9a0c311ba5649086e3df0eb500e8c969 to your computer and use it in GitHub Desktop.
Save V-Abhilash-1999/9a0c311ba5649086e3df0eb500e8c969 to your computer and use it in GitHub Desktop.
SatValPanel Composable
@Composable
fun SatValPanel(
hue: Float,
setSatVal: (Float, Float) -> Unit
) {
val interactionSource = remember {
MutableInteractionSource()
}
val scope = rememberCoroutineScope()
var sat: Float
var value: Float
val pressOffset = remember {
mutableStateOf(Offset.Zero)
}
Canvas(
modifier = Modifier
.size(300.dp)
.emitDragGesture(interactionSource)
.clip(RoundedCornerShape(12.dp))
) {
val cornerRadius = 12.dp.toPx()
val satValSize = size
val bitmap = Bitmap.createBitmap(size.width.toInt(), size.height.toInt(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
val satValPanel = RectF(0f, 0f, bitmap.width.toFloat(), bitmap.height.toFloat())
val rgb = AndroidColor.HSVToColor(floatArrayOf(hue, 1f, 1f))
val satShader = LinearGradient(
satValPanel.left, satValPanel.top, satValPanel.right, satValPanel.top,
-0x1, rgb, Shader.TileMode.CLAMP
)
val valShader = LinearGradient(
satValPanel.left, satValPanel.top, satValPanel.left, satValPanel.bottom,
-0x1, -0x1000000, Shader.TileMode.CLAMP
)
canvas.drawRoundRect(
satValPanel,
cornerRadius,
cornerRadius,
Paint().apply {
shader = ComposeShader(
valShader,
satShader,
PorterDuff.Mode.MULTIPLY
)
}
)
drawBitmap(
bitmap = bitmap,
panel = satValPanel
)
fun pointToSatVal(pointX: Float, pointY: Float): Pair<Float, Float> {
val width = satValPanel.width()
val height = satValPanel.height()
val x = when {
pointX < satValPanel.left -> 0f
pointX > satValPanel.right -> width
else -> pointX - satValPanel.left
}
val y = when {
pointY < satValPanel.top -> 0f
pointY > satValPanel.bottom -> height
else -> pointY - satValPanel.top
}
val satPoint = 1f / width * x
val valuePoint = 1f - 1f / height * y
return satPoint to valuePoint
}
scope.collectForPress(interactionSource) { pressPosition ->
val pressPositionOffset = Offset(
pressPosition.x.coerceIn(0f..satValSize.width),
pressPosition.y.coerceIn(0f..satValSize.height)
)
pressOffset.value = pressPositionOffset
val (satPoint, valuePoint) = pointToSatVal(pressPositionOffset.x, pressPositionOffset.y)
sat = satPoint
value = valuePoint
setSatVal(sat, value)
}
drawCircle(
color = Color.White,
radius = 8.dp.toPx(),
center = pressOffset.value,
style = Stroke(
width = 2.dp.toPx()
)
)
drawCircle(
color = Color.White,
radius = 2.dp.toPx(),
center = pressOffset.value,
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment