CustomClipper<Path>
를 기준으로 설명하는 글 입니다.
사용자가 커스텀 한 모양을 그리기 위한 클래스입니다, 예를 들면 쿠키틀과 같은 역할을 한다고 볼 수 있습니다.
기본적인 선언 형식으로 추상 클래스인 CustomClipper<T>
를 상속받아 사용하며, T는 원하는 모양의 타입을 넣어주면 됩니다.
예시 코드
class CustomClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
// 원하는 경로 추가
return path;
}
bool shouldReclip(CustomClipper<Path> oldClipper) {
return false;
}
}
도양을 다시 그려야 하는지에 대한 여부를 반환하는 메서드입니다.
예를 들어 애니메이션 중에 클리핑 모양이 변경되어야 하는 경우 true
를 반환하여 다시 모양을 그릴 수 있습니다.
getClip 메서드는 필수 재정의 메서드이며, 적용시킬 모양을 반환해야 합니다.
Size 매개변수를 통해 해당 크기 내에서 클리핑 모양을 그리며, Size 값은 상위 부모 위젯으로부터 받아 사용합니다.
현재 위치를 지정 좌표로 이동시키는 메서드입니다.
x, y의 순서로 좌표가 적용되며, 일반적으로는 해당 메서드를 이용하여 시작점을 설정합니다.
시작점을 0, 0 으로 사용하신다면 해당 메서드로 시작점을 설정하실 필요는 없습니다.
path.moveTo(50, 50); // 좌표를 (x, y)으로 이동
현재 좌표에서 지정한 좌표까지 직선을 그리는 메서드입니다.
path.lineTo(150, 50); // 현 좌표에서 (x, y)까지 직선 그리기
해당 함수의 경우 단일로 사용되었을 경우 UI에서는 아무것도 보이지 않습니다.
// 단일 lineTo 예제
class OneLineToClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.lineTo(150, 50);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
// 2중 lineTo 예제
class TwoLineToClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.lineTo(150, 50);
path.lineTo(0, 50);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
현재 위치에서 제어점과 끝 점을 이용해 곡선을 그리는 메서드입니다.
path.quadraticBezierTo(100, 100, 150, 0);
// 현 좌표에서 (x1, y1 x2, y2) 곡선 그리기
이때 x1, y1은 곡선의 형태와 방향을 제어하는 제어점의 x y 좌표이며, x2, y2는 끝 점의 좌표입니다.
class QuadraticBezierToClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.quadraticBezierTo(100, 100, 150, 0);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
현재 좌표에서 시작점을 연결하여 경로를 닫는 역할을 합니다.
필수 메서드는 아니지만 명시적 하기 위하여 작성해 주는 것이 좋습니다.
path.close();
더욱 다양한 Path 메소드는 공식 문서로 확인 가능합니다.
https://api.flutter.dev/flutter/dart-ui/Path-class.html
Path는 별도로 정해진 순서 없이 사용자가 정의한 순서대로 선을 이어줍니다, 이는 예제를 통해 쉽게 알아볼 수 있습니다.
아래는 다이아몬드 다각형을 그리는 실제 코드와 빌드로 통해 나타는 결과입니다.
class PolygonClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.moveTo(50, 0); // 시작점 세팅
path.lineTo(100, 0);
path.lineTo(150, 50);
path.lineTo(75, 100);
path.lineTo(0, 50);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
해당 결과물 위에 선과 좌표, 순서를 참고용으로 적어둔 후 알아보면 아래 같으며 코드와 같이 시계 방향대로 그리고 있음을 알 수 있습니다.
그러면 점을 그리는 시작점과 반시계 방향으로 순서를 바꿔보겠습니다.
class PolygonClipper extends CustomClipper<Path> {
Path getClip(Size size) {
final path = Path();
path.moveTo(75, 100); // 시작점 세팅
path.lineTo(150, 50);
path.lineTo(100, 0);
path.lineTo(50, 0);
path.lineTo(0, 50);
path.close();
return path;
}
bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
return false;
}
}
시작점과 순서가 바뀌었음에도 그리는 도형의 형태는 여전함을 알 수 있습니다, 이처럼 해당 Path에서는 그리는 시작점과 그리는 방향의 중요성보다는 좌표값을 인지하고 원하는 위치에 지정하는 것이 휠씬 중요함을 알 수 있습니다.
customCliper로 정의한 모양을 사용하여 하위 위젯의 모양을 클리핑 할 수 있는 위젯입니다.
클리핑 클래스로 만든 쿠키틀을 실제로 찍어낸 후의 결과를 보여주는 위젯이라고 볼 수 있습니다.
ClipPath(
clipper: CustomClipper(), // 적용할 클리핑 클래스
child: Container( // 클리핑 적용되는 자식 위젯
width: 250,
height: 250,
color: Colors.yellow,
),
)
공식 영상을 통해 이미지와 함께 간단한 설명을 확인할 수 있는 아래 영상도 존재하니 필요시 확인하면 좋을 듯합니다.
다양한 CustomClipper를 제공해 주는 flutter_custom_clippers 패키지가 존재하니 해당 패키지에 필요한 Clipper가 존재한다면 해당 패키지를 사용하는 것 또한 개발 시간을 줄 일 수 있는 하나의 방법입니다.
flutter_custom_clippers 패키지 링크
해당 코드들의 전문은 Github 레파지토리에서 확인 가능합니다!