Skip to content

Instantly share code, notes, and snippets.

@WSAyan
Last active April 20, 2023 20:13
Show Gist options
  • Save WSAyan/b58a5f84ba522024c57f859665b71b72 to your computer and use it in GitHub Desktop.
Save WSAyan/b58a5f84ba522024c57f859665b71b72 to your computer and use it in GitHub Desktop.
Jetpack compose draw rectangle with touch
package com.wsayan.compose_playground
import android.graphics.RectF
import android.os.Bundle
import android.view.MotionEvent
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathMeasure
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.core.graphics.PathUtils
import com.wsayan.compose_playground.ui.theme.Compose_playgroundTheme
import kotlin.math.max
import kotlin.math.min
class MainActivity : ComponentActivity() {
val action: MutableState<Pair<Boolean, Pair<Float, Float>>?> = mutableStateOf(null)
val path = Path()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Compose_playgroundTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
RectangleDrawer(action, path)
}
}
}
}
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun RectangleDrawer(action: MutableState<Pair<Boolean, Pair<Float, Float>>?>, path: Path) {
Canvas(modifier = Modifier
.fillMaxSize()
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
action.value = Pair(true, Pair(it.x, it.y))
path.moveTo(it.x, it.y)
}
MotionEvent.ACTION_MOVE -> {
action.value = Pair(false, Pair(it.x, it.y))
path.lineTo(it.x, it.y)
}
MotionEvent.ACTION_UP -> {
path.reset()
}
else -> false
}
true
}
) {
action.value?.let {
val bounds = path.getBounds()
drawRect(
color = Color.Green,
alpha = 1f,
style = Stroke(10f),
topLeft = Offset(bounds.left, bounds.top),
size = bounds.size
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment