Flutter Canvas 그리기 예제 - (4) Canvas에 Text 그리기
28 Dec 2021 | FlutterCanvas에 Text 그리기
실행 화면
화면 특정 좌표에 원과 텍스트를 그리는 예제입니다. 원, 사각형, 라인 등은 좌표만 입력하면 쉽게 그릴 수 있기 때문에 사용법이 조금 다른 텍스트 그리기 위주로 포스팅합니다.

Text 그리는 함수 예제
void _drawText(Canvas canvas, centerX, centerY, text, style) {
final textSpan = TextSpan(
text: text,
style: style,
);
final textPainter = TextPainter()
..text = textSpan
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center
..layout();
final xCenter = (centerX - textPainter.width / 2);
final yCenter = (centerY - textPainter.height / 2);
final offset = Offset(xCenter, yCenter);
textPainter.paint(canvas, offset);
}
전체 코드
import 'package:flutter/material.dart';
import 'package:snowdeer_canvas_example/drag_and_drop/node.dart';
class DraggableObjectPage extends StatefulWidget {
const DraggableObjectPage({Key key}) : super(key: key);
@override
State createState() => DraggableObjectPageState();
}
class DraggableObjectPageState extends State<DraggableObjectPage> {
final List<Node> nodeList = List.empty(growable: true);
DraggableObjectPageState() {
initNodes();
}
void initNodes() {
nodeList.clear();
nodeList.add(Node("1", "Node\n1", 150.0, 180.0));
nodeList.add(Node("2", "Node\n2", 220.0, 40.0));
nodeList.add(Node("3", "Node\n3", 380.0, 240.0));
nodeList.add(Node("4", "Node\n4", 640.0, 190.0));
nodeList.add(Node("5", "Node\n5", 480.0, 350.0));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTapDown: (detail) {
print("onTapDown:(${detail.localPosition})");
},
onTapUp: (detail) {
print("onTapUp(${detail.localPosition})");
},
onHorizontalDragUpdate: (detail) {
print("onHorizontalDragUpdate:(${detail.localPosition})");
},
child: CustomPaint(
child: Container(),
painter: DraggablePainter(nodeList),
),
),
);
}
}
class DraggablePainter extends CustomPainter {
static const gridWidth = 50.0;
static const gridHeight = 50.0;
var _width = 0.0;
var _height = 0.0;
final List<Node> nodeList;
DraggablePainter(this.nodeList);
void _drawBackground(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.white70
..isAntiAlias = true;
Rect rect = Rect.fromLTWH(0, 0, _width, _height);
canvas.drawRect(rect, paint);
}
void _drawGrid(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.grey
..isAntiAlias = true;
final rows = _height / gridHeight;
final cols = _width / gridWidth;
for (int r = 0; r < rows; r++) {
final y = r * gridHeight;
final p1 = Offset(0, y);
final p2 = Offset(_width, y);
canvas.drawLine(p1, p2, paint);
}
for (int c = 0; c < cols; c++) {
final x = c * gridWidth;
final p1 = Offset(x, 0);
final p2 = Offset(x, _height);
canvas.drawLine(p1, p2, paint);
}
}
void _drawNodes(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.amber
..isAntiAlias = true;
const textStyle = TextStyle(
color: Colors.black,
fontSize: 18,
);
const radius = 30.0;
for (int i = 0; i < nodeList.length; i++) {
final c = Offset(nodeList[i].x, nodeList[i].y);
canvas.drawCircle(c, radius, paint);
_drawText(
canvas, nodeList[i].x, nodeList[i].y, nodeList[i].name, textStyle);
}
}
void _drawText(Canvas canvas, centerX, centerY, text, style) {
final textSpan = TextSpan(
text: text,
style: style,
);
final textPainter = TextPainter()
..text = textSpan
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center
..layout();
final xCenter = (centerX - textPainter.width / 2);
final yCenter = (centerY - textPainter.height / 2);
final offset = Offset(xCenter, yCenter);
textPainter.paint(canvas, offset);
}
@override
void paint(Canvas canvas, Size size) {
_width = size.width;
_height = size.height;
_drawBackground(canvas);
_drawGrid(canvas);
_drawNodes(canvas);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
전체 코드
import 'package:flutter/material.dart';
import 'package:snowdeer_canvas_example/drag_and_drop/node.dart';
class DraggableObjectPage extends StatefulWidget {
const DraggableObjectPage({Key key}) : super(key: key);
@override
State createState() => DraggableObjectPageState();
}
class DraggableObjectPageState extends State {
final List nodeList = List.empty(growable: true);
DraggableObjectPageState() {
initNodes();
}
void initNodes() {
nodeList.clear();
nodeList.add(Node("1", "Node\n1", 150.0, 180.0));
nodeList.add(Node("2", "Node\n2", 220.0, 40.0));
nodeList.add(Node("3", "Node\n3", 380.0, 240.0));
nodeList.add(Node("4", "Node\n4", 640.0, 190.0));
nodeList.add(Node("5", "Node\n5", 480.0, 350.0));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTapDown: (detail) {
print("onTapDown:(${detail.localPosition})");
},
onTapUp: (detail) {
print("onTapUp(${detail.localPosition})");
},
onHorizontalDragUpdate: (detail) {
print("onHorizontalDragUpdate:(${detail.localPosition})");
},
child: CustomPaint(
child: Container(),
painter: DraggablePainter(nodeList),
),
),
);
}
}
class DraggablePainter extends CustomPainter {
static const gridWidth = 50.0;
static const gridHeight = 50.0;
var _width = 0.0;
var _height = 0.0;
final List nodeList;
DraggablePainter(this.nodeList);
void _drawBackground(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.white70
..isAntiAlias = true;
Rect rect = Rect.fromLTWH(0, 0, _width, _height);
canvas.drawRect(rect, paint);
}
void _drawGrid(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.grey
..isAntiAlias = true;
final rows = _height / gridHeight;
final cols = _width / gridWidth;
for (int r = 0; r < rows; r++) {
final y = r * gridHeight;
final p1 = Offset(0, y);
final p2 = Offset(_width, y);
canvas.drawLine(p1, p2, paint);
}
for (int c = 0; c < cols; c++) {
final x = c * gridWidth;
final p1 = Offset(x, 0);
final p2 = Offset(x, _height);
canvas.drawLine(p1, p2, paint);
}
}
void _drawNodes(Canvas canvas) {
var paint = Paint()
..style = PaintingStyle.fill
..color = Colors.amber
..isAntiAlias = true;
const textStyle = TextStyle(
color: Colors.black,
fontSize: 18,
);
const radius = 30.0;
for (int i = 0; i < nodeList.length; i++) {
final c = Offset(nodeList[i].x, nodeList[i].y);
canvas.drawCircle(c, radius, paint);
_drawText(
canvas, nodeList[i].x, nodeList[i].y, nodeList[i].name, textStyle);
}
}
void _drawText(Canvas canvas, centerX, centerY, text, style) {
final textSpan = TextSpan(
text: text,
style: style,
);
final textPainter = TextPainter()
..text = textSpan
..textDirection = TextDirection.ltr
..textAlign = TextAlign.center
..layout();
final xCenter = (centerX - textPainter.width / 2);
final yCenter = (centerY - textPainter.height / 2);
final offset = Offset(xCenter, yCenter);
textPainter.paint(canvas, offset);
}
@override
void paint(Canvas canvas, Size size) {
_width = size.width;
_height = size.height;
_drawBackground(canvas);
_drawGrid(canvas);
_drawNodes(canvas);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
</pre>