Skip to content

Instantly share code, notes, and snippets.

@mahendranv
Last active August 1, 2021 18:38
Show Gist options
  • Save mahendranv/c8fb2d846e2b9000ea51b4979f5cdff3 to your computer and use it in GitHub Desktop.
Save mahendranv/c8fb2d846e2b9000ea51b4979f5cdff3 to your computer and use it in GitHub Desktop.
Polygons - demo
package com.ex2.dribbble.lab
import androidx.annotation.IntRange
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Slider
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.ex2.dribbble.ui.theme.DribbleUITheme
import com.google.accompanist.coil.rememberCoilPainter
import kotlin.math.cos
import kotlin.math.roundToInt
import kotlin.math.sin
/**
*
* @param size Side of the canvas. Expects square canvas
* @param n number of faces
* @param offset top-left offset of the shape
*/
fun buildPolygon(
size: Float,
n: Int,
offset: Offset = Offset(0f, 0f),
offsetAngle: Boolean = true
): Path {
val radius = size / 2
val cx = offset.x + radius
val cy = offset.y + radius
val angle = 2.0 * Math.PI / n
val offAngle = if (offsetAngle) {
0.0
} else 0.0
return Path().apply {
moveTo(
cx + (radius * cos(angle * 0.0 + offAngle)).toFloat(),
cy + (radius * sin(angle * 0.0 + offAngle)).toFloat(),
)
for (i in 1 until n) {
lineTo(
cx + (radius * cos(angle * i + offAngle)).toFloat(),
cy + (radius * sin(angle * i + offAngle)).toFloat(),
)
}
close()
}
}
/**
*
*/
class PolygonShape(
@IntRange(from = 3)
private val n: Int,
) : Shape {
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
val side = size.minDimension
val diff = (size.width - size.height) / 2
val offset = when {
diff == 0f -> {
Offset(0f, 0f)
}
diff > 0f -> {
Offset(diff, 0f)
}
else -> {
Offset(0f, -1f * diff)
}
}
return Outline.Generic(buildPolygon(side, n, offset))
}
}
@Preview(showBackground = true)
@Composable
fun previewPolygon() {
var faces by remember {
mutableStateOf(3f)
}
DribbleUITheme {
Column(Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally) {
Surface(
color = color_orange,
shape =
PolygonShape(faces.toInt()),
modifier = Modifier
.padding(24.dp)
.size(300.dp)
) {
Image(
painter = rememberCoilPainter(
request = "https://pyxis.nymag.com/v1/imgs/cd8/804/e0f612fa12d17e68e3d68ccf55f93cac4f-06-rick-morty.rsquare.w700.jpg"
),
contentDescription = ""
)
}
Spacer(modifier = Modifier.size(10.dp))
Slider(
value = faces,
valueRange = 3f.rangeTo(12f),
steps = 9,
onValueChange = {
faces = it
}
)
Spacer(modifier = Modifier.size(10.dp))
Text(
text = faces.roundToInt().toString(),
style = MaterialTheme.typography.h2,
color = color_orange
)
}
}
}
@mahendranv
Copy link
Author

shape_polygon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment