시작점과 현재 기준점을 연결하지 않았을 경우의 문제
아래의 Path를 보자. 아래 Path의 마지막 줄의 lineTo 함수는 이전 기준점인 (300, 100)와 (100, 100)을 잇는 직선을 생성한다.
val path = Path().apply {
moveTo(100.dp.toPx(), 100.dp.toPx()) // 시작 지점 (100, 100)
lineTo(100.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 100.dp.toPx())
lineTo(100.dp.toPx(), 100.dp.toPx()) // (300, 100)과 (100, 100)을 잇는 직선 생성
}
이 Path는 정상적으로 사각형을 만들 것으로 보여 문제가 없을 것으로 보인다.
하지만, 한번 이를 drawPath함수를 통해 Stroke 모드로 그려보자.
@Preview(widthDp = 400, heightDp = 400)
@Composable
fun DrawRectWithPath() {
Canvas(
modifier = Modifier
.fillMaxSize()
.background(Color.White),
onDraw = {
val path = Path().apply {
moveTo(100.dp.toPx(), 100.dp.toPx()) // 시작 지점 옮기기
lineTo(100.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 100.dp.toPx())
lineTo(100.dp.toPx(), 100.dp.toPx())
}
drawPath(
path = path,
color = Color.Blue,
style = Stroke(width = 10.dp.toPx())
)
}
)
}
그러면 다음과 같은 화면이 나온다.
위 화면에서 왼쪽 위 꼭지점이 살짝 네모 형태가 되는 것을 볼 수 있다.
이렇게 왼쪽 위 꼭지점이 살짝 네모 형태가 되는 이유는 시작점(100, 100)과 lineTo 를 통해 만든 새로운 기준점이 같다고 해서, 도형이 만들어지는 것이 아니기 때문이다. 위 Path는 직선 4개로 이루어져 있을 뿐이며, drawPath는 각 직선을 그릴 뿐이다. 이를 해결하기 위해서는 Path를 닫아야(close) 한다
close() 함수 사용해 Path 닫기
먼저 Path의 close가 무엇을 하는지에 대한 설명을 보자.
/**
* Closes the last subpath, as if a straight line had been drawn
* from the current point to the first point of the subpath.
*/
fun close()
이를 요약하면, 마지막 하위 경로를 시작점까지 연결해 닫는다는 뜻이다.
따라서 위 함수에서 마지막 기준점 (100, 100)과 시작점 (100, 100) 사이에 직선을 만들어 닫으려면 아래와 같이 쓰면 된다.
@Preview(widthDp = 400, heightDp = 400)
@Composable
fun DrawRectWithPath() {
Canvas(
modifier = Modifier
.fillMaxSize()
.background(Color.White),
onDraw = {
val path = Path().apply {
moveTo(100.dp.toPx(), 100.dp.toPx()) // 시작 지점 옮기기
lineTo(100.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 100.dp.toPx())
lineTo(100.dp.toPx(), 100.dp.toPx())
close()
}
drawPath(
path = path,
color = Color.Blue,
style = Stroke(width = 10.dp.toPx())
)
}
)
}
그러면 왼쪽 위에 빈 공간이 사라지는 것을 볼 수 있다.
close 사용해 마지막 직선 대체하기
이를 응용하면, 마지막 기준점이 (300, 100)이고, 시작점이 (100, 100)일 때 close()를 사용해 닫힌 도형을 만들어낼 수 있다.
@Preview(widthDp = 400, heightDp = 400)
@Composable
fun DrawRectWithPath() {
Canvas(
modifier = Modifier
.fillMaxSize()
.background(Color.White),
onDraw = {
val path = Path().apply {
moveTo(100.dp.toPx(), 100.dp.toPx()) // 시작 지점 옮기기
lineTo(100.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 300.dp.toPx())
lineTo(300.dp.toPx(), 100.dp.toPx())
close()
}
drawPath(
path = path,
color = Color.Blue,
style = Stroke(width = 10.dp.toPx())
)
}
)
}
이렇게 해도 그림2와 같은 도형이 나온다.
반응형