[Flutter] Custom Clipper - 1. 기초편

S_Soo100·2023년 10월 10일
0

flutter

목록 보기
12/19
post-thumbnail

클리퍼 위젯(**Clipper**)란?

  • 플러터에서 커스텀 도형을 그리는데 사용되는 위젯이다.
  • ClipPath, ClipRectClipRRectClipOval 4가지 클래스로 구성된다. 이중 ClipRect(직사각형), ClipRRect(모서리 적용한 직사각형), ClipOval(원형) 는 정해진 모향을 만들어내지만, ClipPath는 내가 지정한 도형을 자유롭게 만들 수 있다. 그리고 CustomPaint위젯도 비슷한 동작을 하니까 배워두면 추후에 응용이 쉬울 것이라고 생각한다!
    UI에 강점이 있는 플러터의 기본기중 하나이니 알고만 있더라도 큰 도움이 되지 않을까?

ClipPath

  • 클립 패스(ClipPath)클래스는 커스텀클리퍼 안에 Path들을 설계도로 해서 도형을 그린다.
    만들어놓고 보면 svg파일과 비슷하다.
    선을 어느 포인트에서 어느 포인트로 그어야 할 지 정의하는게 거의 전부다.
    아래 코드는 ClipPath의 생성자이다.
ClipPath({Key? key, CustomClipper<Path>? clipper, Clip clipBehavior = Clip.antiAlias, Widget? child})
  • 생성자를 보면 CustomClipper<Path>? 타입의 clipper프로퍼티 안에 도형을 어떻게 그려야할지를 정의한다.
  • 그리고 child위젯에는 내가 원하는 색상과 사이즈가 들어간 콘테이너를 넣어주자.
    편의를 위해 가로 세로 모두 200인 사각형을 우선 그려놓자.
class MyCustopClipWidget extends StatelessWidget {
  MyCustopClipWidget({Key? key, required this.size}) : super(key: key);

  double size;
  
  Widget build(BuildContext context) {
    return ClipPath(
      clipper: MyClipper(),
      child: Container(
        width: size, // 편의를 위해 가로 세로 모두 200으로 하겠다
        height: size,
				color: Colors.lightBlueAccent,
      ),
    );
  }
}

CustomClipper 만들기

  • CustomClipper는 추상 클래스이기 때문에 이를 상속하는 새로운 클래스를 만들어줘야 하는데,
    그 클래스에는 2가지 메서드가 필수적으로 @override되어야 된다.
    `Path` 타입을 리턴하는 `getClip`과 `bool`타입을 리턴하는 `shouldReclip`이다.
    
    ```dart
    class MyClipper extends CustomClipper<Path> {
      @override
      Path getClip(Size size) {
        Path path = Path();
        return path;
      }
    
      @override
    bool shouldReclip(CustomClipper<Path> oldClipper) {
        return true; // 도형이 새로 그려질 수 있게 할 때만 
      }
    }
    ```
    
    기초는 거의 다 왔다. 이제 두 메서드를 살펴보면서 도형을 어떻게 그려야 하는지를 알아보자.

shouldReclip()

공식문서 - shouldReclip abstract method

  • CustomClipper는 코드를 까보면 listenable을 상속하고 있다. true로 두면, listener를 붙이고 새로운 커스텀 클리퍼가 들어올 때 마다 도형을 다시 그려주게 할 수 있다. 핫리로드도 포함되기 때문에 도형을 새로 그리는 동작을 원치 않더라도 디버그 시에는 true로 해두자.

getClip()

  • getClip 메서드는 기본적으로 size를 부모로 부터 받아오고, 이것은 ClipPath 클래스가 가진 child 위젯의 크기로 쓰인다.
  • getClip() 메서드는 도형의 모양을 커스터마이징 한다. 이 안에 커스텀 클리퍼 Path(경로)를 그린다.
    먼저 기본적으로 도형의 이차원 축에 대한 이해와 몇 가지 경로를 그리는 메서드를 이해해야 한다.

  • figma로 그린 간단한 가로 세로 200픽셀의 사각형이다. 왼 쪽 맨 위에 빨간 점이 보일것이다. 저 포인트가 x : 0, y : 0이다.
    그렇다면 정 가운데 점은 가로와 세로의 정확히 절반인 포인트기 때문에 (100, 100) 일 것이다.
    물론 사각형이 커지면 이 포인트의 위치도 변한다. 정확한 좌표로 포인트를 찍는게 어렵다면 가로 세로 비율로 계산해도 좋다.
    예를 들어, 오른 쪽 맨 위는 (size.width, 0) 일 것이며 정 가운데는 (size.width / 2 , size.height / 2) 이다.
  • 이제 우리는 그림을 그릴 준비가 끝났다. Path() 객체 뒤에 “..”를 쓰며 메서드를 이어나가며
    순서대로 선이 그어지도록 지시하면 된다.
    ”어떤 선을 어디서 그어야 하는지”를 알려주는 메서드 들을 알아보자.

기본 메서드

1) ..moveTo(x, y)

  • 선이나 점을 그리지 않고 단순히 (x, y) 포인트로 이동한다.

  Path getClip(Size size) {
    Path path = Path()
      ..moveTo(100, 50)
			..close();

    return path;
  }

2) ..lineTo(x, y)

  • 단순히 내 현재 위치부터 주어진 (x, y)점까지 직선을 긋는다.

  Path getClip(Size size) {
    Path path = Path()
			..moveTo(100, 0)
      ..lineTo(0, 200)
      ..lineTo(200, 200)
			..close();

    return path;
  }
  • 선이나 점을 그리지 않고 단순히 (x, y) 포인트로 이동한다. 그러다 도형의 형태가 구성되면 그대로 색을 칠해준다.
  • 만일 선이 교차하거나 하면 교차한 부분도 포함해서 면이 구성되는 부분만 도형으로 구성한다.

  Path getClip(Size size) {
    Path path = Path()
			..lineTo(200, 200)
      ..lineTo(0, 200)
      ..lineTo(200, 0)
			..close();

    return path;
  }

자, 이제 원하는 위치로 포인터를 옮기고, 거기서 부터 기본적인 직선을 그어서 도형을 구성할 수 있다.
더 자세한 도형 그리기와 곡선 그리기를 다음 글에 이어서 정리해서 알아보자!

profile
플러터, 리액트

0개의 댓글