日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Flutter 34: 图解自定义 View 之 Canvas (一)

發(fā)布時(shí)間:2024/4/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flutter 34: 图解自定义 View 之 Canvas (一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

??????小菜最近在學(xué)習(xí)自定義 View,剛了解了一下 Paint 畫筆的神奇之處,現(xiàn)在學(xué)習(xí)一下 Canvas 畫布的神秘之處。Flutter 提供了眾多的繪制方法,小菜接觸不深,盡量都嘗試一下。

Canvas 畫布

drawColor 繪制背景色

??????drawColor 需要傳入兩個(gè)參數(shù),第一個(gè)為色值,第二個(gè)為混合模式,有眾多混合模式供選擇,但注意使用混合模式后會(huì)與繪制其上的其他 View 顏色混合像素。

canvas.drawColor(Colors.pinkAccent, BlendMode.srcIn);
drawPoints 繪制點(diǎn)/線

??????drawPoints 不僅可以繪制點(diǎn),還可以繪制點(diǎn)與點(diǎn)的連線;PointMode 包括 points 點(diǎn) / lines 線 / polygon 多邊形;注意 lines 為每?jī)牲c(diǎn)之間的連線,若為奇數(shù)個(gè)點(diǎn),最后一個(gè)沒有與之相連的點(diǎn)。

// 繪制點(diǎn) canvas.drawPoints(PointMode.points,[Offset(30.0, 30.0), Offset(60.0, 30.0),Offset(90.0, 30.0), Offset(90.0, 60.0),Offset(60.0, 60.0), Offset(30.0, 60.0)],Paint()..strokeWidth = 4.0); canvas.drawPoints(PointMode.points,[Offset(160.0, 30.0), Offset(190.0, 30.0),Offset(220.0, 30.0), Offset(220.0, 60.0),Offset(190.0, 60.0), Offset(160.0, 60.0)],Paint()..strokeWidth = 4.0..strokeCap = StrokeCap.round); // 繪制線 canvas.drawPoints(PointMode.lines,[Offset(30.0, 100.0), Offset(60.0, 100.0),Offset(90.0, 100.0), Offset(90.0, 130.0),Offset(60.0, 130.0), Offset(30.0, 130.0)],Paint()..strokeWidth = 4.0..strokeCap = StrokeCap.round); // 繪制多邊形 canvas.drawPoints(PointMode.polygon,[Offset(160.0, 100.0), Offset(190.0, 100.0),Offset(220.0, 100.0), Offset(220.0, 130.0),Offset(190.0, 130.0), Offset(160.0, 130.0)],Paint()..strokeWidth = 4.0..strokeCap = StrokeCap.round);

drawLine 繪制線
canvas.drawLine(Offset(30.0, 90.0), Offset(Screen.width - 30.0, 90.0),Paint()..strokeWidth = 4.0); canvas.drawLine(Offset(30.0, 120.0), Offset(Screen.width - 30.0, 120.0),Paint()..strokeWidth = 4.0..strokeCap = StrokeCap.round); canvas.drawLine(Offset(30.0, 150.0), Offset(Screen.width - 30.0, 150.0),Paint()..strokeWidth = 4.0..strokeCap = StrokeCap.square);
drawArc 繪制弧/餅

??????drawArc 可以用來繪制圓弧甚至配合 Paint 繪制餅狀圖;drawArc 的第一個(gè)參數(shù)為矩形范圍,即圓弧所在的圓的范圍,若非正方形則圓弧所在的圓會(huì)拉伸;第二個(gè)參數(shù)為起始角度,0.0 為坐標(biāo)系 x 軸正向方形;第三個(gè)參數(shù)為終止角度,若超過 2*PI,則為一個(gè)圓;第四個(gè)參數(shù)為是否由中心出發(fā),false 時(shí)只繪制圓弧,true 時(shí)繪制圓餅;第五個(gè)參數(shù)即 Paint 畫筆,可通過 PaintingStyle 屬性繪制是否填充等;

const PI = 3.1415926; canvas.drawArc(Rect.fromCircle(center: Offset(60.0, 60.0), radius: 80.0),0.0, PI / 2, false,Paint()..color = Colors.white..strokeCap = StrokeCap.round..strokeWidth = 4.0..style = PaintingStyle.stroke); canvas.drawArc(Rect.fromCircle(center: Offset(200.0, 60.0), radius: 80.0),0.0, PI / 2, false,Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.fill); canvas.drawArc(Rect.fromCircle(center: Offset(90.0, 160.0), radius: 80.0),0.0, PI * 2 / 3, true,Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); canvas.drawArc(Rect.fromCircle(center: Offset(250.0, 160.0), radius: 80.0),0.0, PI * 2 / 3, true,Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.fill); canvas.drawArc(Rect.fromLTWH(30.0, 300.0, 200.0, 100.0),0.0, 5.0, true,Paint()..color = Colors.white..style = PaintingStyle.fill); canvas.drawArc(Rect.fromPoints(Offset(260.0, 260.0), Offset(320.0, 420.0)),0.0, 5.0, true,Paint()..color = Colors.white..style = PaintingStyle.fill);

drawRect 繪制矩形

??????drawRect 用來繪制矩形,Flutter 提供了多種繪制矩形方法:

  • Rect.fromPoints 根據(jù)兩個(gè)點(diǎn)(左上角點(diǎn)/右下角點(diǎn))來繪制;
  • Rect.fromLTRB 根據(jù)以屏幕左上角為坐標(biāo)系圓點(diǎn),分別設(shè)置上下左右四個(gè)方向距離;
  • Rect.fromLTWH 根據(jù)設(shè)置左上角的點(diǎn)與矩形寬高來繪制;
  • Rect.fromCircle 最特殊,根據(jù)圓形繪制正方形;
  • canvas.drawRect(Rect.fromPoints(Offset(30.0, 30.0), Offset(150.0, 100.0)),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); canvas.drawRect(Rect.fromPoints(Offset(210.0, 30.0), Offset(330.0, 100.0)),Paint()..color = Colors.white..style = PaintingStyle.fill); canvas.drawRect(Rect.fromLTRB(30.0, 140.0, 150.0, 210.0),Paint()..color = Colors.white); canvas.drawRect(Rect.fromLTWH(210.0, 140.0, 120.0, 70.0),Paint()..color = Colors.white); canvas.drawRect(Rect.fromCircle(center: Offset(90.0, 300.0), radius: 60.0),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke);

    drawRRect 繪制圓角矩形

    ??????drawRRect 繪制圓角矩形,Flutter 提供了多種繪制方法:

  • RRect.fromLTRBXY 前四個(gè)參數(shù)用來繪制矩形位置,剩余兩個(gè)參數(shù)繪制固定 x/y 弧度;
  • RRect.fromLTRBR 前四個(gè)參數(shù)用來繪制矩形位置,最后一個(gè)參數(shù)繪制 Radius 弧度;
  • RRect.fromLTRBAndCorners 前四個(gè)參數(shù)用來繪制矩形位置,剩余四個(gè)可選擇參數(shù),根據(jù)需求設(shè)置四個(gè)角 Radius 弧度,可不同;
  • RRect.fromRectXY 第一個(gè)參數(shù)繪制矩形,可以用上面介紹的多種矩形繪制方式,剩余兩個(gè)參數(shù)繪制固定 x/y 弧度;
  • RRect.fromRectAndRadius 第一個(gè)參數(shù)繪制矩形,可以用上面介紹的多種矩形繪制方式,最后一個(gè)參數(shù)繪制 Radius 弧度;
  • RRect.fromRectAndCorners第一個(gè)參數(shù)繪制矩形,可以用上面介紹的多種矩形繪制方式,剩余四個(gè)可選擇參數(shù),根據(jù)需求設(shè)置四個(gè)角 Radius 弧度,最為靈活。
  • // RRect.fromLTRBXY 方式 canvas.drawRRect(RRect.fromLTRBXY(30.0, 30.0, 150.0, 100.0, 8.0, 8.0),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); canvas.drawRRect(RRect.fromLTRBXY(210.0, 30.0, 330.0, 100.0, 8.0, 18.0),Paint()..color = Colors.white..style = PaintingStyle.fill); // RRect.fromLTRBR 方式 canvas.drawRRect(RRect.fromLTRBR(30.0, 140.0, 150.0, 210.0, Radius.circular(8.0)),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); // RRect.fromLTRBAndCorners 方式 canvas.drawRRect(RRect.fromLTRBAndCorners(210.0, 140.0, 330.0, 210.0,topLeft: Radius.circular(5.0),topRight: Radius.circular(20.0),bottomRight: Radius.circular(5.0),bottomLeft: Radius.circular(20.0)),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); // RRect.fromRectAndCorners 方式 canvas.drawRRect(RRect.fromRectAndCorners(Rect.fromLTWH(30.0, 260.0, 120.0, 70.0),topLeft: Radius.circular(5.0),topRight: Radius.circular(20.0),bottomRight: Radius.circular(5.0),bottomLeft: Radius.circular(20.0)),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); // RRect.fromRectAndRadius 方式 canvas.drawRRect(RRect.fromRectAndRadius(Rect.fromLTWH(210.0, 260.0, 120.0, 70.0),Radius.elliptical(8.0, 18.0)),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke); // RRect.fromRectXY 方式 canvas.drawRRect(RRect.fromRectXY(Rect.fromCircle(center: Offset(90.0, 420.0), radius: 60.0),8.0, 8.0),Paint()..color = Colors.white..strokeWidth = 4.0..style = PaintingStyle.stroke);

    drawDRRect 繪制嵌套矩形

    ??????drawDRRect 繪制嵌套矩形,第一個(gè)參數(shù)為外部矩形,第二個(gè)參數(shù)為內(nèi)部矩形,可用上述多種設(shè)置圓角矩形方式;最后一個(gè)參數(shù)為 Paint 畫筆,且 PaintingStylefill 時(shí)填充的是兩個(gè)矩形之間的范圍。

    canvas.drawDRRect(RRect.fromRectXY(Rect.fromCircle(center: Offset(90.0, 420.0), radius: 60.0), 8.0, 8.0),RRect.fromRectXY(Rect.fromCircle(center: Offset(90.0, 420.0), radius: 54.0), 8.0, 8.0),Paint()..color = Colors.whit..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawDRRect(RRect.fromRectXY(Rect.fromCircle(center: Offset(270.0, 420.0), radius: 60.0), 8.0, 8.0),RRect.fromRectXY(Rect.fromCircle(center: Offset(270.0, 420.0), radius: 54.0), 8.0, 8.0),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.fill);

    drawCircle 繪制圓形

    ??????drawCircle 繪制圓形,僅需設(shè)置原點(diǎn)及半徑即可;

    canvas.drawCircle(Offset(90.0, 420.0), 60.0,Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawCircle(Offset(270.0, 420.0), 60.0,Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.fill);

    drawOval 繪制橢圓

    ??????drawOval 繪制橢圓方式很簡(jiǎn)單,主要繪制一個(gè)矩形即可;

    canvas.drawOval(Rect.fromLTRB(30.0, 30.0, 150.0, 100.0),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawOval(Rect.fromLTRB(210.0, 30.0, 330.0, 100.0),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.fill);

    drawPath 繪制路徑

    ??????drawPath 用來繪制路徑,Flutter 提供了眾多路徑方法,小菜嘗試幾種常用的方法:

  • moveTo() 即從當(dāng)前坐標(biāo)點(diǎn)開始,不設(shè)置時(shí)默認(rèn)為屏幕左上角位置;
  • lineTo() 即從起點(diǎn)繪制到設(shè)置的新的點(diǎn)位;
  • close() 即最后的點(diǎn)到起始點(diǎn)連接,但對(duì)于中間繪制矩形/弧等時(shí)最后不會(huì)相連;
  • reset() 即清空連線;
  • addRect() 添加矩形連線;
  • addOval() 添加弧線,即貝塞爾(二階)曲線;
  • cubicTo() 添加弧線,即貝塞爾(三階)曲線;
  • relativeMoveTo() 相對(duì)于移動(dòng)到當(dāng)前點(diǎn)位,小菜認(rèn)為與 moveTo 相比整個(gè)坐標(biāo)系移動(dòng);
  • relativeLineTo() 相對(duì)連接到當(dāng)前點(diǎn)位,并將坐標(biāo)系移動(dòng)到當(dāng)前點(diǎn)位;
  • canvas.drawPath(Path()..moveTo(30.0, 100.0)..lineTo(120.0, 100.0)..lineTo(90.0, 130.0)..lineTo(180.0, 130.0)..close(),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawPath(Path()..moveTo(200.0, 100.0)..lineTo(290.0, 100.0)..lineTo(260.0, 130.0)..lineTo(350.0, 130.0)..close(),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.fill); canvas.drawPath(Path()..moveTo(30.0, 170.0)..lineTo(120.0, 170.0)..lineTo(90.0, 210.0)..lineTo(180.0, 210.0)..addRect(Rect.fromLTWH(180.0, 210.0, 120.0, 70.0))..addOval(Rect.fromLTWH(180.0, 210.0, 120.0, 70.0))..moveTo(230.0, 170.0)..lineTo(320.0, 170.0)..close(),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawPath(Path()..arcTo(Rect.fromCircle(center: Offset(60, 300), radius: 80), -PI / 6,PI * 2 / 3, false),Paint()..color = Colors.white..strokeWidth = 3.0..style = PaintingStyle.stroke); canvas.drawPath(Path()..moveTo(210.0, 300.0)..cubicTo(210.0, 390.0, 270.0, 330.0, 330.0, 300.0),Paint()..color = Colors.black..strokeWidth = 3.0..style = PaintingStyle.stroke);

    ??????小菜繪制了一個(gè)基本的坐標(biāo)系來比較一下 moveTo()/lineTo()relativeMoveTo()/relativeLineTo() 的區(qū)別:

    canvas.drawPath(Path()..relativeMoveTo(30.0, 30.0)..relativeLineTo(120.0, 30.0)..relativeLineTo(90.0, 60.0)..relativeLineTo(180.0, 60.0),Paint()..color = Colors.blue..strokeWidth = 6.0..style = PaintingStyle.stroke); canvas.drawPath(Path()..moveTo(30.0, 30.0)..lineTo(120.0, 30.0)..lineTo(90.0, 60.0)..lineTo(180.0, 60.0),Paint()..color = Colors.orange..strokeWidth = 6.0..style = PaintingStyle.stroke);


    ??????小菜對(duì)自定義 View 研究還不深入,有很多方法還沒有嘗試,有錯(cuò)誤的地方希望多多指導(dǎo)!

    總結(jié)

    以上是生活随笔為你收集整理的Flutter 34: 图解自定义 View 之 Canvas (一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。