使用CustomPainter在Flutter中繪圖

介紹 :

在Flutter中,所有內容都圍繞

Widget。Flutter讓你靈活創建一些漂亮的UI小部件,並且該應用程序可以在iOS和Android上使用。因此,將您創建的這些小部件繪製到移動屏幕上,或者我們可以將其稱為繪製在畫布上(Canvas)。那麼我們也可以將其用作繪圖板來繪圖。

使用CustomPainter在Flutter中繪圖


我們將使用custom painter在畫布上繪畫,我們將提供更改畫筆的大小,不透明度和顏色的選項。

該代碼位於https://github.com/sharansingh00002/draw

現在讓我們來看看這是如何完成的:)

Code Time

我們需要具備的第一個信息是用戶與之交互的畫布上的點的座標,我們可以使用Gesture Detector輕鬆獲得該信息。我們將使用手勢檢測器的onPanUpdate,onPanStartonPanEnd屬性。當用戶單擊屏幕時使用onPanStart,這樣我們可以繪製一個點,但是如果用戶拖動,則使用onPanUpdate可以獲取連續點,並且OnPanEnd通知用戶已停止繪製。

我們將這些點存儲在列表中,其中每個元素將具有座標以及與該點關聯的繪製屬性。

<code>class DrawingPoints {
Paint paint;
Offset points;
DrawingPoints({this.points, this.paint});
}
/<code>

在手勢檢測器中,onPanUpdate函數看起來像

<code>onPanUpdate: (details) {
setState(() {
RenderBox renderBox = context.findRenderObject();
points.add(DrawingPoints(
points: renderBox.globalToLocal(details.globalPosition),
paint: Paint()
..strokeCap = strokeCap
..isAntiAlias = true
..color = selectedColor.withOpacity(opacity)
..strokeWidth = strokeWidth));
});
},
onPanStart: (details) {
setState(() {
RenderBox renderBox = context.findRenderObject();
points.add(DrawingPoints(
points: renderBox.globalToLocal(details.globalPosition),
paint: Paint()
..strokeCap = strokeCap
..isAntiAlias = true
..color = selectedColor.withOpacity(opacity)
..strokeWidth = strokeWidth));
});
},
onPanEnd: (details) {
setState(() {
points.add(null);
});
},
/<code>

因此,我們使用渲染框獲取要在其上進行繪製的渲染對象,並將該框的全局座標系點轉換為局部座標系。我們將在末尾添加null以標記繪圖的結束。

現在讓我們看一下自定義的CustomPainter類,該類負責在屏幕上繪製。

<code>class DrawingPainter extends CustomPainter {
DrawingPainter({this.pointsList});
List<drawingpoints> pointsList;
List<offset> offsetPoints = List();
@override
void paint(Canvas canvas, Size size) {
for (int i = 0; i < pointsList.length - 1; i++) {
if (pointsList[i] != null && pointsList[i + 1] != null) {
canvas.drawLine(pointsList[i].points, pointsList[i +1].points ,
pointsList[i].paint);
} else if (pointsList[i] != null && pointsList[i + 1] == null) {
offsetPoints.clear();
offsetPoints.add(pointsList[i].points);
offsetPoints.add(Offset(
pointsList[i].points.dx + 0.1, pointsList[i].points.dy + 0.1));
canvas.drawPoints(PointMode.points, offsetPoints, pointsList[i].paint);
}
}
}
@override
bool shouldRepaint(DrawingPainter oldDelegate) => oldDelegate.pointsList!=pointsList;
}
/<offset>/<drawingpoints>/<code>

我們使用Canvas.drawLine函數繪製線條,但是如果用戶剛剛在屏幕上輕擊,則使用Canvas.drawPoint繪製該點。

我們正在檢查是否為null,因為在用戶停止繪圖時我們將添加null,以便如果他再次開始繪圖,則最後一個繪圖的最後一點和新繪圖的起點不應該連接。

要清除屏幕,只需清除pointsList。

定製:

因此,我們可以添加許多自定義項,到目前為止,我已經添加了更改筆觸寬度,筆刷的不透明度和顏色的選項。

因此,對於strokeWidth不透明度Opacity,我們可以簡單地使用Slider來更改值,對於Color,我們提供一些預定義的最常用的顏色,以及使用顏色選擇器選擇其選擇的顏色的選項。

這些更改的值存儲在與每個繪圖點關聯的Paint對象中,以便每個點可以具有自己的特徵。

使用CustomPainter在Flutter中繪圖


<code>Slider(
value: (selectedMode == SelectedMode.StrokeWidth)
? strokeWidth
: opacity,
max: (selectedMode == SelectedMode.StrokeWidth)
? 50.0
: 1.0,
min: 0.0,
onChanged: (val) {
setState(() {
if (selectedMode == SelectedMode.StrokeWidth)
strokeWidth = val;
else
opacity = val;
});
}),
/<code>
使用CustomPainter在Flutter中繪圖


對於顏色選擇器,我們使用fuyumi的flutter_colorpicker庫https://pub.dartlang.org/packages/flutter_colorpicker

這個項目的代碼可以在github上找到:

https://github.com/sharansingh00002/draw

翻譯自:https://medium.com/flutter-community/drawing-in-flutter-using-custompainter-307a9f1c21f8


分享到:


相關文章: