Flutter的自定義繪圖,主要利用CustomPaint這個部件,CustomPaint的建構式如下。
const CustomPaint({
Key? key,
this.painter, //位於child下的背景
this.foregroundPainter, //位於child上的前景
this.size = Size.zero, //大小,如果有設置child,就以child的大小為主
this.isComplex = false, //是否混合
this.willChange = false, //是否在下一幀改變
Widget? child,
}) : assert(size != null),
assert(isComplex != null),
assert(willChange != null),
assert(painter != null || foregroundPainter != null || (!isComplex && !willChange)),
super(key: key, child: child);
一般常用的屬性是painter或是child。
child就是你要放置的內容,可以透過這個child來放置一下Flutter已經設計好,不需要自行繪製的部件。
painter裡的值,要放的是繪製的方法,透過繼承了CustomPainter父類別的新類別,來提供繪製的方法。如下列例子:class myPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
throw UnimplementedError();
}
這裡面有兩個必要的建立的方法,先說shouldRepaint(covariant CustomPainter oldDelegate),這地方主要在設定繪圖物件有更新或未更新時,要採取的方式。
第二個paint(Canvas canvas, Size size)有兩個參數,Canvas指的是畫布,而Size指的是上面CustomPaint上設置的child或是size長及寬。
Canvas提供的方法很多,以下介紹幾個。
canvas.saveLayer() 創建另一個圖層
canvas.restore() 放置於canvas.save() canvas.saveLayer() 後,將圖層合成
canvas.translate(double dx, double dy) 畫布平移至某位置
canvas.scale(double sx, [double sy]) 畫布縮放
canvas.rotate(double radians) 旋轉畫布
canvas.skew(double sx, double sy) 斜切
canvas.rotate(double radians) 旋轉畫布
canvas.skew(double sx, double sy) 斜切
繪製部份
(一)畫點
Canvas.drawPoints(PointMode pointMode, List points, Paint paint);參數說明:
PointMode pointMode:繪製模式(有 PointMode.points、PointMode.lines、 PointMode.polygon三種),
List points:位置 ,採用陣列,如以下設定 [Offset(300, 500)],
Paint paint:畫筆設定
canvas.drawPoints(PointMode.lines,[Offset(300, 500),Offset(400, 500)],paint);
(二)畫線
Canvas.drawLine(Offset p1, Offset p2, Paint paint);參數說明:
Offset p1:起點位置
Offset p2:終點位置
Paint paint:畫筆設定
Canvas.drawRect(Rect rect, Paint paint)
參數說明:
Rect rect:矩形的位置及長寬設定
根據四個位置設定矩形 Rect.fromLTRB(this.left, this.top, this.right, this.bottom)
根據左上角位置及寬高設定矩形 Rect.fromLTWH(double left, double top, double width, double height)
根據中心位置及寬高設定矩形 Rect.fromCenter( Offset center ,double width, double height )
根據內接圓 ,生成正方形,設定矩形 Rect.fromCircle(Offset center, double radius )
根據左上角及右下角位置,設定矩形 Rect.fromPoints(Offset a, Offset b)
Paint paint:畫筆設定
(四)畫圓形
Canvas.drawCircle(Offset c, double radius, Paint paint),參數說明:
Offset c:圓心位置
double radius:圓半徑
Paint paint:畫筆設定
(五)繪製橢圓
drawOval(Rect rect, Paint paint)參數說明:
Rect rect:矩形設定(可見上面第三項)
Paint paint:畫筆設定
(六)繪製圓弧
drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)參數說明:
Rect rect:矩形設定(可見上面第三項)double startAngle:開始角度,以x軸為0起算的弧度制,弧度制的算法 (角的度數 x pi/180)
double sweepAngle:圓環的角度,弧度制
bool useCenter:終點是否和圓心連接
Paint paint:畫筆設定
Flutter Canvas學習之繪圖篇 | IT人 (iter01.com)
https://juejin.cn/post/7061893652242989064
http://soiiy.com/flutter/11823.html
https://zhuanlan.zhihu.com/p/424768534
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '畫圖練習',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: '繪圖練習'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
//利用custompaint繪圖
body:CustomPaint(
//繪製圖的大小
size: Size(200.0,200.0),
//圖的前景畫法
painter: DrawPainter(),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class DrawPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint();
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 10;
canvas.drawRRect(RRect.fromRectAndRadius(const Rect.fromLTWH(0, 0, 200, 150), const Radius.circular(10)), paint);
canvas.drawPoints(
ui.PointMode.points,
[
Offset(100, 100),
Offset(250, 180),
Offset(200, 300),
],
paint);
}
沒有留言:
張貼留言