Flutter學習:認識CustomPaint組件和Paint對象


Flutter學習:認識CustomPaint組件和Paint對象
Flutter學習:使用CustomPaint繪制路徑
Flutter學習:使用CustomPaint繪制圖形
Flutter學習:使用CustomPaint繪制文字
Flutter學習:使用CustomPaint繪制圖片

CustomPaint

CustomPaint是flutter的一個組件,所以我們可以像其他組件一樣使用:

CustomPaint({ 
  Key? key, 
  CustomPainter? painter,  // 繪制在子元素的下層
  CustomPainter? foregroundPainter,  // 繪制在子元素的上層
  Size size = Size.zero,  // 約定的布局大小,有子元素就為子元素大小
  bool isComplex = false,  // 繪制復雜的圖形時應為 true
  bool willChange = false,  // 在下一幀時是否會發生改變
  Widget? child,  // 子元素
})

CustomPaint中,要想自由的繪制內容,需要使用painterforegroundPainter屬性。傳入一個自定義繼承CustomPainter的類。

在繼承CustomPainter后有兩個必須重寫的方法。在paint方法中進行繪制操作,shouldRepaint方法用來描述繪制的內容什么時候應該更新。

class MyCustomPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => this != oldDelegate;
}

前提代碼:

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomPaint(
        painter: MyCustomPainter(),
        // 如果CustomPaint的父元素沒有指定大小
        // CusotmPaint的子元素沒有指定大小
        // CustomPaint的size屬性沒有指定大小
        // 繪畫出來的顯示效果和有指定大小的完全不一樣
        size: Size.infinite,
      ),
    );
  }
}

以下是在頁面中繪制一個寬250,高300的矩形:

image

Paint

Paint相當於一支畫筆,可以自定義畫筆的顏色、粗細等。首先實例化一個Paint對象:

Paint paint = Paint();

Paint類和繪制內容相關的屬性一共有14個:

style

stylePaintStyle?,是否繪制內部形狀,形狀的邊緣,或兩者都繪制

// 填充(默認)
paint.style = PaintingStyle.fill; 
// 描邊
paint.style = PaintingStyle.stroke;

image

Color

colorColor?,描邊或填充形狀時使用的顏色。

// 默認為不透明黑色Colors.black
paint.color = Colors.red;

image

colorFilter

colorFilter ColorFilter?,繪制形狀或合成圖層時應用的顏色過濾器,繪制形狀時, colorFilter會覆蓋colorshader

// 構造一個將 sRGB 伽馬曲線應用於 RGB 通道的濾色器
paint.colorFilter = const ColorFilter.linearToSrgbGamma();
// 創建一個顏色過濾器,將 sRGB 伽馬曲線的倒數應用於 RGB 通道
paint.colorFilter = const ColorFilter.srgbToLinearGamma();
// 構造一個通過 5x5 矩陣轉換顏色的濾色器,其中第五行隱式添加到標識配置中。
// 每個像素的顏色值,表示為<code>R, G, B, A</code> ,乘以矩陣以創建新顏色:
// | R' |   | a00 a01 a02 a03 a04 |   | R |
// | G' |   | a10 a11 a22 a33 a44 |   | G |
// | B' | = | a20 a21 a22 a33 a44 | * | B |
// | A' |   | a30 a31 a22 a33 a44 |   | A |
// | 1  |   |  0   0   0   0   1  |   | 1 |
// 矩陣按行優先順序排列,轉換列在未歸一化的 0...255 空間中指定。
paint.colorFilter = const ColorFilter.matrix([
      1, 0, 0, 0, 0,
      0, 1, 0, 0, 0,
      0, 0, 1, 0, 0,
      0, 0, 0, 1, 0,
]);
// 創建一個顏色過濾器,應用作為第二個參數給出的混合模式
// 源顏色是作為第一個參數給出的顏色,目標顏色是來自正在合成的圖層的顏色
paint.colorFilter = const ColorFilter.mode(Colors.blue, BlendMode.colorBurn);

image

invertColors

invertColorsbool?, 繪制時圖像的顏色是否反轉。 反轉圖像的顏色會應用一個新的濾色器,該濾色器將與任何用戶提供的濾色器組成。

paint.invertColors = true;

image

isAntiAlias

isAntiAliasbool?,是否對畫布上繪制的線條和圖像應用抗鋸齒,使用了抗鋸齒邊緣更平滑。

// 默認值為true
paint.isAntiAlias = true;

image

strokeCap

strokeCapStrokeCap?,當style設置為PaintingStyle.stroke時放置在畫線末端的飾面

// 以平坦邊緣開始和結束輪廓,沒有延伸
paint.strokeCap = StrokeCap.butt;
// 以半圓形延伸開始和結束輪廓
paint.strokeCap = StrokeCap.round;
// 以半方形擴展開始和結束輪廓。這類似於將每個輪廓擴展一半筆畫寬度(由Paint.strokeWidth繪制)
paint.strokeCap = StrokeCap.square;

image

strokeJoin

strokeJoinStrokeJoin?,放置在段之間的連接處的那種飾面,只適用於繪制路徑(即PaintingStyle.stroke)。

// 線段之間的連接將線段對接端的角連接起來,以提供斜切外觀
paint.strokeJoin = StrokeJoin.bevel;
// 線段之間的連接形成尖角
paint.strokeJoin = StrokeJoin.miter;
// 線段之間的連接是半圓形的
paint.strokeJoin = StrokeJoin.round;

image

strokeMiterLimit

strokeMiterLimitdouble?,當連接設置為StrokeJoin.miterstyle設置為PaintingStyle.stroke時,在線段上繪制斜接的限制。如果超出此限制,則會改為繪制StrokeJoin.bevel連接。

關於strokeMiterLimit是什么可以查看以下文章:

// 默認為4.0
paint.strokeWidth = 20;

image

strokeWidth

strokeWidthdouble?,當style設置為PaintingStyle.stroke時繪制邊緣的寬度。

// 默認值為0.0
paint.strokeWidth = 20;

image

shader

shaderShader?,用來描邊或填充形狀時使用的着色器。當它為空時,將使用color。

shader屬性傳遞的值為 Gradient 或 ImageShader對象。

關於shader的使用方法可以查看以下文章:

blendMode

blendModeBlendMode?,在畫布上繪畫時使用的算法。在畫布上繪制形狀或圖像時,可以使用不同的算法來混合像素。

關於BlendMode的相關資料可以查看以下文章:

filterQuality

filterQualityFilterQuality?

用於對圖像進行采樣的ImageFilterShader對象中的圖像采樣以及用於渲染圖像的Canvas操作的質量級別。
當按比例放大時,質量通常是最低的, lowmedium的質量none ,而對於非常大的比例因子(超過 10 倍),質量最高的是high
縮小時, medium提供最佳質量,尤其是在將圖像縮小到小於其大小的一半或在此類縮小之間為比例因子設置動畫時。否則, lowhigh在 50% 和 100% 之間的減少提供類似的效果,但圖像可能會丟失細節並具有低於 50% 的丟失。
為了在放大和縮小圖像或比例未知時獲得高質量, medium通常是一個很好的平衡選擇。

paint.filterQuality = FilterQuality.none;
paint.filterQuality = FilterQuality.low;
paint.filterQuality = FilterQuality.medium;
paint.filterQuality = FilterQuality.high;

imageFilter

imageFilterImageFilter?

設置繪制圖片時的圖像過濾器。imageFilter 一共有3個值用來設置:

ImageFilter.blur

用來設置圖片高斯模糊顯示效果,可以傳入3個參數:

  • double sigmaX:創建 x 軸的高斯模糊度
  • double sigmaY:創建 y 軸的高斯模糊度
  • TileMode tileMode:這個enum用於定義漸變或圖像過濾器應該如何處理定義的內部區域之外的區域
paint.imageFilter = ui.ImageFilter.blur(sigmaX: 50, sigmaY: 50, tileMode: TileMode.clamp);

image

仔細查看圖片的邊緣,會有不同的效果。

ImageFilter.matrix

用來設置圖片變形狀。

該屬性的用法繁多並且復雜,以后有時間再慢慢研究。要想使用簡單的方法實現變形效果,只要在方法后面加上storage即可:

paint.imageFilter = ui.ImageFilter.matrix(Matrix4.skew(.2, .4).storage);

image

ImageFilter.compose

用來組合實現圖片高斯模糊和變形。

ui.ImageFilter outer = ui.ImageFilter.blur(sigmaX: 50, sigmaY: 50, tileMode: TileMode.decal);
ui.ImageFilter inner = ui.ImageFilter.matrix(Matrix4.skew(.2, .4).storage);
paint.imageFilter = ui.ImageFilter.compose(outer: outer, inner: inner);

image

maskFilter

蒙版過濾器(例如,模糊),用於在繪制后但在將其合成到圖像之前應用於形狀。需要傳入2個參數:

  • BlurStyle _style:MaskFilter對象中用於模糊的樣式
  • double _sigma:控制效果的大小。它是要應用的高斯模糊的標准偏差。該值必須大於零。 sigma 大致對應於效果半徑的一半(以像素為單位)
paint.maskFilter = MaskFilter.blur(_style, _sigma); 

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM