Class Rect
좌표가 주어진 원점을 기준으로 불변의 2D 축으로 정렬하여 표기하는 직사각형을 그리는 클래스이다. Rect는 생성자 중 하나를 사용하거나 & 연산자를 사용하여 Offset 및 Size에서 생성한다.
라고 정의 되어 있지만 간다하게 그냥 직사각형을 그리는 클래스라고 생각하면 된다.
아래와 같이 클래스가 정의 되어 있고 오늘은 간단한 사용 방법에 대해 알아보쟈
더보기
class Rect {
const Rect.fromLTRB(this.left, this.top, this.right, this.bottom);
const Rect.fromLTWH(double left, double top, double width, double height) : this.fromLTRB(left, top, left + width, top + height);
Rect.fromCircle({ required Offset center, required double radius }) : this.fromCenter(
center: center,
width: radius * 2,
height: radius * 2,
);
Rect.fromCenter({ required Offset center, required double width, required double height }) : this.fromLTRB(
center.dx - width / 2,
center.dy - height / 2,
center.dx + width / 2,
center.dy + height / 2,
);
Rect.fromPoints(Offset a, Offset b) : this.fromLTRB(
math.min(a.dx, b.dx),
math.min(a.dy, b.dy),
math.max(a.dx, b.dx),
math.max(a.dy, b.dy),
);
Float32List _getValue32() {
final Float32List result = Float32List(4);
result[0] = left;
result[1] = top;
result[2] = right;
result[3] = bottom;
return result;
}
final double left;
final double top;
final double right;
final double bottom;
double get width => right - left;
double get height => bottom - top;
Size get size => Size(width, height);
bool get hasNaN => left.isNaN || top.isNaN || right.isNaN || bottom.isNaN;
static const Rect zero = Rect.fromLTRB(0.0, 0.0, 0.0, 0.0);
static const double _giantScalar = 1.0E+9; // matches kGiantRect from layer.h
static const Rect largest = Rect.fromLTRB(-_giantScalar, -_giantScalar, _giantScalar, _giantScalar);
bool get isInfinite {
return left >= double.infinity
|| top >= double.infinity
|| right >= double.infinity
|| bottom >= double.infinity;
}
bool get isFinite => left.isFinite && top.isFinite && right.isFinite && bottom.isFinite;
bool get isEmpty => left >= right || top >= bottom;
Rect shift(Offset offset) {
return Rect.fromLTRB(left + offset.dx, top + offset.dy, right + offset.dx, bottom + offset.dy);
}
Rect translate(double translateX, double translateY) {
return Rect.fromLTRB(left + translateX, top + translateY, right + translateX, bottom + translateY);
}
Rect inflate(double delta) {
return Rect.fromLTRB(left - delta, top - delta, right + delta, bottom + delta);
}
Rect deflate(double delta) => inflate(-delta);
Rect intersect(Rect other) {
return Rect.fromLTRB(
math.max(left, other.left),
math.max(top, other.top),
math.min(right, other.right),
math.min(bottom, other.bottom)
);
}
Rect expandToInclude(Rect other) {
return Rect.fromLTRB(
math.min(left, other.left),
math.min(top, other.top),
math.max(right, other.right),
math.max(bottom, other.bottom),
);
}
bool overlaps(Rect other) {
if (right <= other.left || other.right <= left) {
return false;
}
if (bottom <= other.top || other.bottom <= top) {
return false;
}
return true;
}
double get shortestSide => math.min(width.abs(), height.abs());
double get longestSide => math.max(width.abs(), height.abs());
Offset get topLeft => Offset(left, top);
Offset get topCenter => Offset(left + width / 2.0, top);
Offset get topRight => Offset(right, top);
Offset get centerLeft => Offset(left, top + height / 2.0);
Offset get center => Offset(left + width / 2.0, top + height / 2.0);
Offset get centerRight => Offset(right, top + height / 2.0);
Offset get bottomLeft => Offset(left, bottom);
Offset get bottomCenter => Offset(left + width / 2.0, bottom);
Offset get bottomRight => Offset(right, bottom);
bool contains(Offset offset) {
return offset.dx >= left && offset.dx < right && offset.dy >= top && offset.dy < bottom;
}
static Rect? lerp(Rect? a, Rect? b, double t) {
if (b == null) {
if (a == null) {
return null;
} else {
final double k = 1.0 - t;
return Rect.fromLTRB(a.left * k, a.top * k, a.right * k, a.bottom * k);
}
} else {
if (a == null) {
return Rect.fromLTRB(b.left * t, b.top * t, b.right * t, b.bottom * t);
} else {
return Rect.fromLTRB(
_lerpDouble(a.left, b.left, t),
_lerpDouble(a.top, b.top, t),
_lerpDouble(a.right, b.right, t),
_lerpDouble(a.bottom, b.bottom, t),
);
}
}
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (runtimeType != other.runtimeType) {
return false;
}
return other is Rect
&& other.left == left
&& other.top == top
&& other.right == right
&& other.bottom == bottom;
}
@override
int get hashCode => Object.hash(left, top, right, bottom);
@override
String toString() => 'Rect.fromLTRB(${left.toStringAsFixed(1)}, ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)})';
}
addRect 과 addRRect
addRect은 직사각형, addRRect은 모서리가 둥근 직사각형을 그리는데 사용한다. addRect은 Rect 클래스를 통해 직사각형을 그릴 좌표와 크기를 지정한다. addRRect 클래스는 RRect 클래스를 통해 동그란 직사각형을 그린다.
두개의 다른점은 RRect는 Radius를 통해 모서리의 둥글기를 설정해 준다는 점이다.
원하는 위치와 형태 사이즈를 그리기위해 아까 바로 위에 적어두었던 Class Rect 의 생성자들을 참조한다.
코드 작성 방법
1. 우선 화면의 어느 지점에 그리고 싶은지 생각하여 Offset 값을 설정한다.
2. 원하는 사이즈를 지정해 준다.
Path path = Path()
..addRect(Rect.fromCenter(center: Offset(120, 60), width: 40, height: 70))
..addRRect(RRect.fromLTRBR(120, 100, 180, 180, Radius.circular(10)));
3. CustomPainer를 상속받아 그려줄 클래스를 생성한다
class PathPainter extends CustomPainter {
final Path path;
PathPainter(this.path);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
4. build에 표기 해 준다.
@override
Widget build(BuildContext context) {
Path path = Path()
..addRect(Rect.fromCenter(center: Offset(120, 60), width: 40, height: 70))
..addRRect(RRect.fromLTRBR(120, 100, 180, 180, Radius.circular(10)));
return Scaffold(
body: Column(
children: [
Expanded(
child: CustomPaint(
painter: PathPainter(path),
),
),
],
),
);
}
'Flutter' 카테고리의 다른 글
Flutter Wrap...Incorrect use of ParentDataWidget 에러 (0) | 2024.05.20 |
---|---|
Flutter 라디오 버튼 크기 조절 (0) | 2024.04.25 |
Flutter 의 CustomPaint 클래스 (1) | 2024.04.18 |
Flutter ElevatedButton - overlayColor 다양한 효과 주기 (0) | 2024.04.10 |
Flutter renderflex overflowed ... error 해결 (0) | 2024.04.09 |