Skip to content

Instantly share code, notes, and snippets.

@SmartToolFactory
Created September 3, 2022 08:42
Show Gist options
  • Save SmartToolFactory/d34a51fe9cf9912b26133768ebe092f1 to your computer and use it in GitHub Desktop.
Save SmartToolFactory/d34a51fe9cf9912b26133768ebe092f1 to your computer and use it in GitHub Desktop.

Revisions

  1. SmartToolFactory created this gist Sep 3, 2022.
    238 changes: 238 additions & 0 deletions ClipComposables.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,238 @@

    import androidx.compose.foundation.Image
    import androidx.compose.foundation.background
    import androidx.compose.foundation.clickable
    import androidx.compose.foundation.layout.*
    import androidx.compose.foundation.shape.CutCornerShape
    import androidx.compose.material.BottomNavigation
    import androidx.compose.material.BottomNavigationItem
    import androidx.compose.material.icons.Icons
    import androidx.compose.material.icons.filled.*
    import androidx.compose.material3.*
    import androidx.compose.runtime.*
    import androidx.compose.ui.Alignment
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.draw.drawWithContent
    import androidx.compose.ui.geometry.Offset
    import androidx.compose.ui.geometry.Size
    import androidx.compose.ui.graphics.*
    import androidx.compose.ui.graphics.drawscope.ContentDrawScope
    import androidx.compose.ui.graphics.drawscope.withTransform
    import androidx.compose.ui.graphics.vector.ImageVector
    import androidx.compose.ui.layout.ContentScale
    import androidx.compose.ui.platform.LocalDensity
    import androidx.compose.ui.platform.LocalLayoutDirection
    import androidx.compose.ui.res.imageResource
    import androidx.compose.ui.res.painterResource
    import androidx.compose.ui.unit.IntOffset
    import androidx.compose.ui.unit.IntSize
    import androidx.compose.ui.unit.dp
    import androidx.compose.ui.unit.sp


    @Composable
    fun ClipComposables() {
    Row(
    modifier = Modifier.fillMaxWidth(),
    horizontalArrangement = Arrangement.SpaceEvenly
    ) {
    val imageBitmap = ImageBitmap.imageResource(id = R.drawable.squircle)

    Box(modifier = Modifier
    .size(150.dp)
    .drawWithLayer {

    // Destination
    drawContent()

    // Source
    drawImage(
    image = imageBitmap,
    dstSize = IntSize(width = size.width.toInt(), height = size.height.toInt()),
    blendMode = BlendMode.DstIn
    )

    }
    ) {

    Box(
    modifier = Modifier
    .size(150.dp)
    .clickable { }
    .background(MaterialTheme.colorScheme.inversePrimary),
    contentAlignment = Alignment.Center
    ) {
    Text(text = "Squircle", fontSize = 20.sp)
    }
    }

    Box(modifier = Modifier
    .size(150.dp)
    .drawWithLayer {
    // Destination
    drawContent()

    // Source
    drawImage(
    image = imageBitmap,
    dstSize = IntSize(width = size.width.toInt(), height = size.height.toInt()),
    blendMode = BlendMode.DstIn
    )

    }
    ) {

    Image(
    painterResource(id = R.drawable.squirtle),
    modifier = Modifier
    .size(150.dp),
    contentScale = ContentScale.Crop,
    contentDescription = ""
    )
    }

    }
    }


    @Composable
    fun BottomBarWithCutOutShape() {
    val density = LocalDensity.current
    val shapeSize = density.run { 70.dp.toPx() }

    val cutCornerShape = CutCornerShape(50)
    val outline = cutCornerShape.createOutline(
    Size(shapeSize, shapeSize),
    LocalLayoutDirection.current,
    density
    )

    val icons =
    listOf(Icons.Filled.Home, Icons.Filled.Map, Icons.Filled.Settings, Icons.Filled.LocationOn)

    Box(
    modifier = Modifier.fillMaxWidth()
    ) {
    BottomNavigation(
    modifier = Modifier
    .drawWithLayer {
    with(drawContext.canvas.nativeCanvas) {

    val checkPoint = saveLayer(null, null)
    val width = size.width

    val outlineWidth = outline.bounds.width
    val outlineHeight = outline.bounds.height

    // Destination
    drawContent()

    // Source
    withTransform(
    {
    translate(
    left = (width - outlineWidth) / 2,
    top = -outlineHeight / 2
    )
    }
    ) {
    drawOutline(
    outline = outline,
    color = Color.Transparent,
    blendMode = BlendMode.Clear
    )
    }

    restoreToCount(checkPoint)
    }
    },
    backgroundColor = Color.White
    ) {

    var selectedIndex by remember { mutableStateOf(0) }

    icons.forEachIndexed { index, imageVector: ImageVector ->
    if (index == 2) {
    Spacer(modifier = Modifier.weight(1f))
    BottomNavigationItem(
    icon = { Icon(imageVector, contentDescription = null) },
    label = null,
    selected = selectedIndex == index,
    onClick = {
    selectedIndex = index
    }
    )
    } else {
    BottomNavigationItem(
    icon = { Icon(imageVector, contentDescription = null) },
    label = null,
    selected = selectedIndex == index,
    onClick = {
    selectedIndex = index
    }
    )
    }
    }
    }

    // This is size fo BottomNavigationItem
    val bottomNavigationHeight = LocalDensity.current.run { 56.dp.roundToPx() }

    FloatingActionButton(
    modifier = Modifier
    .align(Alignment.TopCenter)
    .offset {
    IntOffset(0, -bottomNavigationHeight / 2)
    },
    shape = cutCornerShape,
    onClick = {}
    ) {
    Icon(imageVector = Icons.Default.Add, contentDescription = null)
    }
    }
    }


    @Composable
    fun WhoAteMyButton() {
    val circleSize = LocalDensity.current.run { 100.dp.toPx() }
    Box(
    modifier = Modifier
    .fillMaxWidth()
    .drawWithLayer {
    // Destination
    drawContent()
    // Source
    drawCircle(
    center = Offset(0f, 10f),
    radius = circleSize,
    blendMode = BlendMode.SrcOut,
    color = Color.Transparent
    )
    }
    ) {
    Button(
    modifier = Modifier
    .padding(horizontal = 10.dp)
    .fillMaxWidth(),
    onClick = { /*TODO*/ }) {
    Text("Hello World")
    }
    }
    }

    fun Modifier.drawWithLayer(block: ContentDrawScope.() -> Unit) = this.then(
    Modifier.drawWithContent {
    drawWithLayer {
    block()
    }
    }
    )

    fun ContentDrawScope.drawWithLayer(block: ContentDrawScope.() -> Unit) {
    with(drawContext.canvas.nativeCanvas) {
    val checkPoint = saveLayer(null, null)
    block()
    restoreToCount(checkPoint)
    }
    }