[Android] 구름 모양 그리기

uuranus·2024년 7월 23일
0
post-thumbnail

원하는 구름 모양 분석하기

포켓몬 슬립이라는 게임에서 요리를 할 때 나오는 이미지이다. 위 사진처럼 생긴 구름 모양을 만들어 볼 것이다.

피그마를 통해 위에 따라 그려보았고 그 결과

구름 모양 분석

세 가지 크기의 원을 통해 만들었고 각 원의 크기는 반지름 10.dp씩 차이가 나고 원의 위치는 임의적으로 조정해가면서 제일 괜찮은 모양을 찾았다.

radius는 각 원에 대한 반지름 값이다.

구름 그리기

Path에 있는 drawOval 기능을 사용할 것이다.

타원을 그릴 사각형의 공간을 지정해주면 거기에 맞춰서 그려는 메서드로

Rect(
    centerX,
    centerY + middleCircleY - middleCircleRadius,
    centerX + middleCircleRadius * 2,
    centerY + middleCircleY + middleCircleRadius
)

다음과 같이 원의 중심좌표를 토대로 사각형의 범위를 잡아주었다.

그리기

 path.addOval(
    Rect(
        centerX - middleCircleRadius * 2,
        centerY + middleCircleY - middleCircleRadius,
        centerX,
        centerY + middleCircleY + middleCircleRadius
    )
)

다음과 같이 원 8개를 그려주면 된다.

최종 결과물

전체 코드

class CloudShape : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density,
    ): Outline {
        val path = Path()

        val centerX = size.width / 2
        val centerY = size.height / 2

        val width = size.width
        val height = width * 2 / 3
        val largestRadius = height / 3

        val radiusDist = with(density) {
            10.dp.toPx()
        }

        val edgeCircleRadius = largestRadius - radiusDist * 2
        val middleCircleRadius = largestRadius - radiusDist

        val centerCircleY = largestRadius / 2
        val middleCircleY = middleCircleRadius / 2

        val ellipses = listOf(
            Rect(
                0f,
                centerY - edgeCircleRadius,
                edgeCircleRadius * 2,
                centerY + edgeCircleRadius
            ),

            Rect(
                centerX - middleCircleRadius * 2,
                centerY - middleCircleY - middleCircleRadius,
                centerX,
                centerY - middleCircleY + middleCircleRadius,
            ),
            Rect(
                centerX - largestRadius,
                centerY - centerCircleY - largestRadius,
                centerX + largestRadius,
                centerY - centerCircleY + largestRadius
            ),
            Rect(
                centerX,
                centerY - middleCircleY - middleCircleRadius,
                centerX + middleCircleRadius * 2,
                centerY - middleCircleY + middleCircleRadius,
            ),

            Rect(
                width - edgeCircleRadius * 2,
                centerY - edgeCircleRadius,
                width,
                centerY + edgeCircleRadius
            ),

            Rect(
                centerX,
                centerY + middleCircleY - middleCircleRadius,
                centerX + middleCircleRadius * 2,
                centerY + middleCircleY + middleCircleRadius,
            ),
            Rect(
                centerX - largestRadius,
                centerY + centerCircleY - largestRadius,
                centerX + largestRadius,
                centerY + centerCircleY + largestRadius
            ),
            Rect(
                centerX - middleCircleRadius * 2,
                centerY + middleCircleY - middleCircleRadius,
                centerX,
                centerY + middleCircleY + middleCircleRadius,
            ),

            )

        for (ellipse in ellipses) {
            path.addOval(
                Rect(
                    centerX - middleCircleRadius * 2,
                    centerY + middleCircleY - middleCircleRadius,
                    centerX,
                    centerY + middleCircleY + middleCircleRadius,
                ),
            )
        }

        return Outline.Generic(path)

    }
}

깃헙 링크

https://github.com/uuranus/compose-shapes

profile
Frontend Developer

0개의 댓글