美文网首页Flutter
FlutterUI(二)Canvas 与 Paint

FlutterUI(二)Canvas 与 Paint

作者: 天色将变 | 来源:发表于2019-08-08 09:00 被阅读0次
Flutter自定义控件分为三大类:
  • 组合控件,通过组合其他widget成为一个新的widget。
  • 自绘控件,通过使用canvas与paint来完全绘制。
  • 继承widget,使用RenderObject来绘制,但最终还是使用canvas来绘制。
本文重点

着重介绍自绘控件,因为所有的widget归根结底都是使用canvas和paint来绘制的,理解了二者,对于其他的widget原理有溯源的功效。

  • Canvas:画布
  • Paint:画笔
    怎么做?
  • 继承CustomPainter
  • 重写paint方法与shouldRepaint方法
  • paint提供来canvas和size,canvas用于绘制,size用于确定大小
  • shouldRepaint用于确认是否每次都重新绘制
画矩形canvas.drawRect();
void drawRect(Rect rect, Paint paint)

rect 矩形的描述

  • Rect.fromCenter({ Offset center, double width, double height }),根据中心点和宽高,定义一个矩形。
  • Rect.fromCircle({ Offset center, double radius }),根据中心点和半径定义一个矩形
  • Rect.fromLTRB(this.left, this.top, this.right, this.bottom),left左边框距离左边的距离,top上边框距离上边的距离,right右边框距离左边的距离,bottom下边框距离上边的距离。根据这四个值定义一个矩形。
  • Rect.fromLTWH(double left, double top, double width, double height),根据左上角顶点和宽高定义一个矩形。
  • Rect.fromPoints(Offset a, Offset b),根据左上角顶点和右下角顶点定义一个矩形。
    示例:


    image.png
class _MyHomePageState extends State<MyHomePage> {
  bool flag = true;

  void change(bool value) {
    setState(() {
      flag = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: CustomPaint(
          size: Size(380, 560),
          painter: MyPainter(),
        ),
      ),
    );
  }
}

class MyPainter extends CustomPainter{

  @override
  void paint(Canvas canvas, Size size) {
    test01(canvas, size);
  }

  void test00(Canvas canvas, Size size) {
    var paint = new Paint()
        ..color = Colors.orange[200]
        ..style = PaintingStyle.fill
        ..isAntiAlias = true;
    // 画矩形
    canvas.drawRect(Offset.zero & size, paint);
    paint
    ..color = Colors.green;
    canvas.drawRect(Rect.fromCenter(width: 200,height: 200,center: Offset(150, 150)), paint);

    paint
      ..color = Colors.blue;
    canvas.drawRect(Rect.fromCircle(radius: 50,center: Offset(150, 150)), paint);

    paint
      ..color = Colors.redAccent;
    canvas.drawRect(Rect.fromLTRB(10,10,200,100), paint);

    paint
      ..color = Colors.pink;
    canvas.drawRect(Rect.fromLTWH(10,250,100,100), paint);

    paint
      ..color = Colors.grey;
    canvas.drawRect(Rect.fromPoints(Offset(250, 250),Offset(350, 300)), paint);
  }


  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

}
画圆角矩形canvas.drawRRect
image.png
void test01(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形

    Rect rect = Rect.fromCircle(
        center: Offset(200, 200), radius: 150);
    RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(30));
    canvas.drawRRect(rRect, paint);
  }
画环形圆角矩形canvas.drawDRRect
image.png
void test011(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    Rect rect1 = Rect.fromCircle(
        center: Offset(200, 200), radius: 140);
    Rect rect2 = Rect.fromCircle(
        center: Offset(200, 200), radius: 160);
    RRect rRect1 = RRect.fromRectAndRadius(rect1, Radius.circular(20));
    RRect rRect2 = RRect.fromRectAndRadius(rect2, Radius.circular(20));
    canvas.drawDRRect(rRect2, rRect1, paint);
  }
画圆canvas.drawCircle
drawCircle(Offset c, double radius, Paint paint)
  • c 中心点
  • radius 圆半径
  • paint 画笔

示例:


image.png
void test02(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    canvas.drawRect(Offset.zero & size, paint);

    paint ..color = Colors.blue[200];
    canvas.drawCircle(Offset(200, 200), 100, paint);
  }
画椭圆canvas.drawOval
image.png
void test022(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    canvas.drawRect(Offset.zero & size, paint);

    paint..color = Colors.blue[200];
    canvas.drawOval(
        Rect.fromCenter(width: 200, height: 300, center: Offset(150, 250)),
        paint);
  }
画线canvas.drawLine
void drawLine(Offset p1, Offset p2, Paint paint)
  • p1 线的起点
  • p2 线的终点

注意:

  • 画笔的style 更改为PaintingStyle.stroke
  • 可以调整线的粗细 strokeWidth = 3

示例:


image.png
void test03(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    canvas.drawRect(Offset.zero & size, paint);

    paint
      ..color = Colors.black
      ..strokeWidth = 3
      ..style = PaintingStyle.stroke;
    canvas.drawLine(Offset(100, 150), Offset(250, 150), paint);

  }
画颜色canvas.drawColor
void drawColor(Color color, BlendMode blendMode)
  • blendMode 是颜色的混合模式


    image.png
void test04(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形

    canvas.drawColor(Colors.blue[200], BlendMode.srcIn);
    canvas.drawRect(Offset.zero & size/2, paint);

  }
画点drawPoints
image.png

参数PointModel:

  • ui.PointMode.points,// 单独的点
  • ui.PointMode.polygon,// 所有的点按给定顺序连成线
  • ui.PointMode.lines,//画一条线,起始点为给定数组的前两个点
void test06(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    canvas.drawRect(Offset.zero & size, paint);
    paint
      ..style = PaintingStyle.stroke
      ..strokeWidth = 15
      ..strokeCap = StrokeCap.round
      ..color = Colors.black;
    canvas.drawPoints(
//        ui.PointMode.points,// 单独的点
//    ui.PointMode.polygon,// 所有的点按给定顺序连成线
    ui.PointMode.lines,//画一条线,起始点为给定数组的前两个点
        [Offset(100, 100), Offset(300, 100), Offset(200, 300)], paint);
  }
画路径canvas.drawPath

paint ..color = PaintingStyle.fill;


image.png
void test07(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    // 画矩形
    Path path = Path();
    path.moveTo(100, 100);
    path.lineTo(100, 200);
    path.lineTo(200, 100);
    path.lineTo(200, 200);
    canvas.drawPath(path, paint);
  }

paint ..color = PaintingStyle.stroke;


image.png
void test07(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
//      ..style = PaintingStyle.fill
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5
      ..isAntiAlias = true;
    // 画矩形
    Path path = Path();
    path.moveTo(100, 100);
    path.lineTo(100, 200);
    path.lineTo(200, 100);
    path.lineTo(200, 200);
    canvas.drawPath(path, paint);
  }

path.close()


image.png
void test07(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
//      ..style = PaintingStyle.fill
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5
      ..isAntiAlias = true;
    // 画矩形
    Path path = Path();
    path.moveTo(100, 100);
    path.lineTo(100, 200);
    path.lineTo(200, 100);
    path.lineTo(200, 200);
    path.close();
    canvas.drawPath(path, paint);
  }
画弧型
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)
  • rect 弧所属椭圆的外接矩形,用于定位该弧的位置
  • startAngle,起始角度,按弧度制,顺时针
  • sweepAngle,画多少弧度,一个圆的弧度是 2PI,也就是2*3.14
  • useCenter,是否将弧与中心连接,形成一个扇形


    image.png
void test08(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
//      ..style = PaintingStyle.fill
      ..style = PaintingStyle.stroke
      ..strokeWidth = 5
      ..isAntiAlias = true;
    Rect rect = Rect.fromCircle(
        center: Offset(200, 200), radius: 100);
    canvas.drawArc(rect, 0, 3.14, false, paint);
  }
画阴影drawShadow
void drawShadow(Path path, Color color, double elevation, bool transparentOccluder)
  • path 阴影区域
  • color 阴影颜色
  • elevation 阴影高度,一般是向右下
  • transparentOccluder 如果阻塞对象不是不透明的,则阻塞“transparentoccluder”参数应为true.百度翻译的,没明白啥意思


    image.png
void test09(Canvas canvas, Size size) {
    var paint = new Paint()
      ..color = Colors.orange[200]
      ..style = PaintingStyle.fill
      ..strokeWidth = 5
      ..isAntiAlias = true;
    Path path = Path();
    path.moveTo(100, 100);
    path.lineTo(100, 200);
    path.lineTo(200, 100);
    path.lineTo(200, 200);
    canvas.drawPath(path, paint);
    canvas.drawShadow(path, Colors.orange, 10, true);
  }
欢迎关注我的公众号:Flutter和Dart开发实践
让我们共同学习进步,每天进步一点点,It is never too late to learn!
image.png

相关文章

网友评论

    本文标题:FlutterUI(二)Canvas 与 Paint

    本文链接:https://www.haomeiwen.com/subject/orfgdctx.html