이번에는 Compose에서 Canvas를 사용하다 보면 접하게 되는 drawContext.canvas.nativeCanvas 에 대해서 설명한다.
보통은 Canvas()를 이용해 웬만한건 다 그릴 수 있다. 하지만, 조금 더 디테일하거나 꼼꼼하게 그리고자 한다면 drawContext.canvas.nativeCanvas (이하 NativeCanvas)를 사용해야 한다.
예시1
위 화면에 보이는 동그라미 두개를 앞서 설명한 Canvas와 NativeCanvas로 그려보자. 두개 모두 동일하게 drawCircle()을 사용한다.
상단 동그라미, Canvas
Canvas(modifier = Modifier.size(300.dp).background(color = Color.Cyan)) {
drawCircle(
color = Color.White,
radius = 100f,
center = center,
style = Stroke(
width = 30f,
),
)
}
Kotlin
복사
하단 동그라미, NativeCanvas
Canvas(modifier = Modifier.size(300.dp).background(color = Color.Cyan)) {
drawContext.canvas.nativeCanvas.apply {
drawCircle(
center.x,
center.y,
100f,
Paint().apply {
strokeWidth = 30f
color = android.graphics.Color.WHITE
style = Paint.Style.STROKE
}
)
}
}
Kotlin
복사
차이점이 있다면, 하단 동그라미의 NativeCanvas에서 사용되는 drawCircle()은 Paint()를 사용한다.
흰색 동그라미 Stroke에 그림자 추가
위와 같은 동그라미를 그려보자. 앞선 코드에서 배경을 흰색으로 바꾼 후(그림자를 더 잘 보이게 하기 위함) Stroke에 그림자만 추가하면 된다.
Canvas
Canvas(modifier = Modifier.size(300.dp).background(color = Color.White)){
drawCircle(
color = Color.White,
radius = 100f,
center = center,
style = Stroke(
width = 30f,
),
)
}
}
Kotlin
복사
Canvas에서는 그림자를 표현할 방법이 없다. 따라서 흰 배경에 흰 동그라미를 한 상황으로서는 아무런 것도 볼 수 없다.
NativeCanvas
Canvas(modifier = Modifier.size(300.dp).background(color = Color.White)) {
drawContext.canvas.nativeCanvas.apply {
drawCircle(
center.x,
center.y,
100f,
Paint().apply {
strokeWidth = 30f
color = android.graphics.Color.WHITE
style = Paint.Style.STROKE
setShadowLayer(
30f,
0f,
0f,
android.graphics.Color.argb(30, 0, 0, 0)
)
}
)
}
}
Kotlin
복사
앞에서 설명 했듯이, Canvas와 NativeCanvas의 큰 차이는 Paint()의 사용 유무이다. 따라서 Paint()에서 shadow 값을 줄 수 있다.
뿐만 아니라 Paint()를 이용해 다양한 효과를 줄 수 있다.
정리
최종 화면
최종 코드
@Composable
fun MyNewCircle(){
Column(modifier = Modifier.fillMaxSize().background(color = Color.White)) {
Canvas(modifier = Modifier.size(300.dp).background(color = Color.White)) {
drawCircle(
color = Color.White,
radius = 100f,
center = center,
style = Stroke(
width = 30f,
),
)
}
Canvas(modifier = Modifier.size(300.dp).background(color = Color.White)) {
drawContext.canvas.nativeCanvas.apply {
drawCircle(
center.x,
center.y,
100f,
Paint().apply {
strokeWidth = 30f
color = android.graphics.Color.WHITE
style = Paint.Style.STROKE
setShadowLayer(
30f,
0f,
0f,
android.graphics.Color.argb(30, 0, 0, 0)
)
}
)
}
}
}
}
Kotlin
복사
추가 내용
drawCircle()에서 Stroke를 사용할 때 stroke Width가 어디를 기준으로 늘어나는지 알아보자
100.dp의 radius를 가진 동그라미를 그려보자. style은 FILL이다. 여기서 STROKE로 바꿔 줘 보자. stroke width는 30.dp로 준다.
이렇게 그려지는 것을 알 수 있는데, 동그라미의 radius인 100.dp 사이즈의 동그라미를 같은 위치에 하나 더 추가해보면 된다. 컬러는 빨간색으로 준다.
이렇게 하면 알아보기 힘드니 빨간색 동그라미에 알파값을 줘보면
이런 화면을 볼 수 있다.
radius outLine 부터 바깥쪽과 안쪽으로 증가하는 것을 볼 수 있다.