Created
February 26, 2024 20:57
-
-
Save pepijntb/42b1db2188a22d9596c9885ade0d91b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.custom_component_test | |
import androidx.compose.foundation.Canvas | |
import androidx.compose.foundation.gestures.detectTapGestures | |
import androidx.compose.foundation.layout.BoxWithConstraints | |
import androidx.compose.foundation.layout.fillMaxSize | |
import androidx.compose.foundation.layout.size | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.geometry.Size | |
import androidx.compose.ui.geometry.center | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.graphics.Path | |
import androidx.compose.ui.graphics.vector.PathData | |
import androidx.compose.ui.graphics.vector.toPath | |
import androidx.compose.ui.input.pointer.pointerInput | |
import androidx.compose.ui.platform.LocalDensity | |
import androidx.compose.ui.tooling.preview.Preview | |
import androidx.compose.ui.unit.dp | |
import kotlin.math.cos | |
import kotlin.math.sin | |
@Composable | |
fun OrientationPicker( | |
modifier: Modifier = Modifier, | |
) { | |
var selectedAngle by remember { | |
mutableStateOf(0) | |
} | |
BoxWithConstraints( | |
modifier = Modifier.size(200.dp), | |
) { | |
val density = LocalDensity.current | |
val widthInPixels = remember { | |
with(density) { | |
maxWidth.toPx() | |
} | |
} | |
val heightInPixels = remember { | |
with(density) { | |
maxHeight.toPx() | |
} | |
} | |
val paths = remember { | |
buildList { | |
for (angle in 0..315 step 45) { | |
add( | |
angle to getPathForAngle( | |
Size(widthInPixels, heightInPixels), | |
angle.toDouble() | |
) | |
) | |
} | |
} | |
} | |
Canvas( | |
modifier = Modifier | |
.fillMaxSize() | |
.pointerInput(Unit) { | |
detectTapGestures { offset -> | |
paths | |
.firstOrNull { | |
it.second | |
.getBounds() | |
.contains(offset) | |
} | |
?.let { | |
selectedAngle = it.first | |
} | |
} | |
}, | |
) { | |
for (path in paths) { | |
drawPath( | |
path = path.second, | |
color = if (path.first == selectedAngle) Color.Green else Color.Red | |
) | |
} | |
} | |
} | |
} | |
fun getX(centerX: Float, radius: Float, angle: Double): Float = | |
centerX + radius * cos(angle.toFloat()) | |
fun getY(centerY: Float, radius: Float, angle: Double): Float = | |
centerY + radius * sin(angle.toFloat()) | |
fun getPathForAngle( | |
size: Size, | |
angle: Double, | |
): Path = PathData { | |
val angleStart = Math.toRadians(angle - 20.5) | |
val angleEnd = Math.toRadians(angle + 22.0) | |
val centerX = size.center.x | |
val centerY = size.center.y | |
val radiusInner = size.width * .25f | |
val radiusOuter = size.width * .45f | |
moveTo( | |
x = getX(centerX, radiusInner, angleStart), | |
y = getY(centerY, radiusInner, angleStart) | |
) | |
lineTo( | |
x = getX(centerX, radiusOuter, angleStart), | |
y = getY(centerY, radiusOuter, angleStart) | |
) | |
arcTo( | |
horizontalEllipseRadius = radiusInner * 2, | |
verticalEllipseRadius = radiusInner * 2, | |
theta = 0f, | |
isMoreThanHalf = false, | |
isPositiveArc = true, | |
x1 = getX(centerX, radiusOuter, angleEnd), | |
y1 = getY(centerY, radiusOuter, angleEnd) | |
) | |
lineTo( | |
x = getX(centerX, radiusInner, angleEnd), | |
y = getY(centerY, radiusInner, angleEnd) | |
) | |
arcTo( | |
horizontalEllipseRadius = radiusInner, | |
verticalEllipseRadius = radiusInner, | |
theta = 0f, | |
isMoreThanHalf = false, | |
isPositiveArc = false, | |
x1 = getX(centerX, radiusInner, angleStart), | |
y1 = getY(centerY, radiusInner, angleStart) | |
) | |
}.toPath() | |
@Composable | |
@Preview | |
fun Preview() { | |
OrientationPicker() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment