锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Flutter 绘图

时间:2023-02-03 13:00:00 高压电阻器5w500m

文章目录

  • Flutter 绘图
    • 概述
    • 绘制线
    • 绘制点
    • 绘制矩形
    • 画圆角矩形
    • 绘制圆形
    • 绘制椭圆
    • 绘制弧
    • 绘制路径
    • 绘制文本
    • 绘制图片

Flutter 绘图

概述

  • Canvas(画布)用于在上面画图形,如画点、线、矩形、圆形、路径、图像等。
  • Paint(画笔)用于设置画布上画图的颜色、厚度、抗锯齿等绘图风格。
  • 在Flutter需要使用绘图CustomPaintCustomPainterCustomPaint用来承载画布的画板,CustomPainter可理解为画布,承载绘制内容。

绘制线

在这里插入图片描述

Container(     width: MediaQuery.of(context).size.width,     height: 200,     color: Colors.white,     child: CustomPaint(         //定义画板大小         size: const Size(200, 200),         ///配置画布         painter: LinePainter(),         //子节点,RepaintBoundary创建新的图层layer,避免重复绘制         child: const RepaintBoundary(             child: Center(child: Text("hello world")),         ),     ), ) 
class LinePainter extends CustomPainter {     //定义画笔:画笔颜色,画笔宽度     final Paint _paint = Paint()         ..color = Colors.blue         ..strokeWidth = 4;      /// 绘制流程     @override     void paint(Canvas canvas, Size size) {         canvas.drawLine(const Offset(20, 20), const Offset(100, 100), _paint);     }      /// 刷新是否重绘     @override     bool shouldRepaint(covariant CustomPainter oldDelegate) {         return false;     } } 

绘制点

Container(     width: MediaQuery.of(context).size.width,     height: 200,     color: Colors.white,     child: CustomPaint(         size: const Size(200, 200),         painter: PointPainter(),     ), ) 
class PointPainter extends CustomPainter {     final Paint _paint = Paint()         ///画笔颜色         ..color = Colors.blue         ///画笔笔头风格         ..strokeCap = StrokeCap.round         //抗锯齿         ..isAntiAlias = true         //填充样式         ..style = PaintingStyle.fill         ///画笔宽度         ..strokeWidth = 20;      @override     void paint(Canvas canvas, Size size) {         canvas.drawPoints(             ui.PointMode.points,             [                 const Offset(50, 50),                 const Offset(100, 150),                 const Offset(150, 150),             ],             _paint);     }      @override     bool shouldRepaint(covariant CustomPainter oldDelegate) {         return true;     } } 

绘制矩形

Container(     width: MediaQuery.of(context).size.width,     height: 200,     color: Colors.white,     child: CustomPaint(         size: const Size(200, 200),         painter: RectPainter(),     ), ) 
class RectPainter extends CustomPainter {     final Paint _paint = Paint()         ..color = Colors.blueAccent         ..strokeCap = StrokeCap.round         ..isAntiAlias = true         ..style = PaintingStyle.fill         ..strokeWidth = 2;      @override     void paint(Canvas canvas, Size size) {         //方法1:左上右下设置4个顶点         // Rect rect = const Rect.fromLTRB(20, 40, 150, 100);         //方二:设置2左上两个顶点和宽度         // Rect rect = const Rect.fromLTWH(20, 40, 150, 100);         //方法三:设置中心和半径         // Rect rect = Rect.fromCircle(center: const Offset(100, 100), radius: 50);         //方法四:设置圆心和宽高         Rect rect = Rect.fromCenter(center: const Offset(100, 100), width: 100, height: 100);         canvas.drawRect(rect, _paint);     }      @override     bool shouldRepaint(covariant CustomPainter oldDelegate) {         return true;     } } 

画圆角矩形

Container(     width: MediaQuery.of(context).size.width,     height: 200,     color: Colors.white,     child: CustomPaint(         size: const Size(200, 200),         painter: RRectPainter(),     ), ) 
class RRectPainter extends CustomPainter {     final Paint _paint = Paint()         ..color = Colors.blueAccent         ..strokeCap = StrokeCap.round         ..isAntiAlias = true         ..style = PaintingStyle.fill         ..strokeWidth = 2;     @override
    void paint(Canvas canvas, Size size) {
        Rect rect = Rect.fromCenter(center: const Offset(100, 100), width: 100, height: 100);
        RRect rRect = RRect.fromRectAndRadius(rect, const Radius.circular(20));
        canvas.drawRRect(rRect, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制圆形

Container(
    width: MediaQuery.of(context).size.width,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: CirclePainter(),
    ),
)
class CirclePainter extends CustomPainter {
    final Paint _paint = Paint()
        ..color = Colors.blueAccent
        ..strokeCap = StrokeCap.round
        ..isAntiAlias = true
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2;

    @override
    void paint(Canvas canvas, Size size) {
        canvas.drawCircle(const Offset(100, 100), 40, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制椭圆

Container(
    width: MediaQuery.of(context).size.width,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: OvalPainter(),
    ),
)
class OvalPainter extends CustomPainter {
    final Paint _paint = Paint()
        ..color = Colors.blueAccent
        ..strokeCap = StrokeCap.round
        ..isAntiAlias = true
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2;

    @override
    void paint(Canvas canvas, Size size) {
        Rect rect = Rect.fromCenter(center: const Offset(150, 100), width: 200, height: 100);
        canvas.drawOval(rect, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制弧

Container(
    width: MediaQuery.of(context).size.width,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: ArcPainter(),
    ),
)
class ArcPainter extends CustomPainter {
    final Paint _paint = Paint()
        ..color = Colors.blueAccent
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2;

    @override
    void paint(Canvas canvas, Size size) {
        const Rect rect = Rect.fromLTRB(50, 50, 150, 150);
        //参数依次是:矩形范围、开始弧度、结束弧度、是否连接圆心、画笔
        canvas.drawArc(rect, 0, 2, false, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制路径

Container(
    width: double.infinity,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: PathPainter(),
    ),
)
class PathPainter extends CustomPainter {
    final Paint _paint = Paint()
        ..color = Colors.black
        ..strokeCap = StrokeCap.round
        ..strokeJoin = StrokeJoin.round
        ..isAntiAlias = true
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2;

    @override
    void paint(Canvas canvas, Size size) {
        final Path path = Path();
        path.moveTo(100, 80);
        path.lineTo(100, 150);
        path.lineTo(160, 150);
        path.close();
        canvas.drawPath(path, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

Container(
    width: MediaQuery.of(context).size.width,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: PathPainter2(),
    ),
)
class PathPainter2 extends CustomPainter {
    final Paint _paint = Paint()
        ..color = Colors.black
        ..strokeCap = StrokeCap.round
        ..strokeJoin = StrokeJoin.round
        ..isAntiAlias = true
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2;

    @override
    void paint(Canvas canvas, Size size) {
        final Path path = Path();
        path.moveTo(100, 80);
        path.lineTo(200, 80);
        path.addArc(
            Rect.fromCenter(center: const Offset(150, 80), width: 100, height: 100),
            0,
            0.5 * pi,
        );
        canvas.drawPath(path, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制文本

Container(
    width: MediaQuery.of(context).size.width,
    height: 200,
    color: Colors.white,
    child: CustomPaint(
        size: const Size(200, 200),
        painter: TextPainter(),
    ),
)
class TextPainter extends CustomPainter {
    @override
    void paint(Canvas canvas, Size size) {
        ui.ParagraphBuilder builder = ui.ParagraphBuilder(
            ui.ParagraphStyle(
                //文字方向
                textDirection: TextDirection.ltr,
                //最大行数
                maxLines: 2,
                //文本居中
                textAlign: TextAlign.center,
                //字体加粗
                fontWeight: FontWeight.bold,
                //字体样式
                fontStyle: FontStyle.normal,
                //字体大小
                fontSize: 24,
                //超出范围显示内容
                ellipsis: "...",
                //行间距
                height: 1.2,
                textHeightBehavior: const TextHeightBehavior(
                    applyHeightToFirstAscent: true,
                    applyHeightToLastDescent: true,
                ),
            ),
        );
        //设置文字样式
        builder.pushStyle(ui.TextStyle(
            color: Colors.red,
            fontSize: 20,
            height: 1,
            fontWeight: FontWeight.w500,
        ));
        String text = "床前明月光,疑是地上霜;举头望明月,低头思故乡。";
        builder.addText(text);
        //文本绘制最大宽度
        ui.ParagraphConstraints constraints = const ui.ParagraphConstraints(width: 300);
        ui.Paragraph paragraph = builder.build()..layout(constraints);
        //绘制文字
        canvas.drawParagraph(paragraph, const Offset(40, 40));
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}

绘制图片

class ImagePaintPage extends StatefulWidget {
    const ImagePaintPage({Key? key}) : super(key: key);

    @override
    State createState() => _ImagePaintPageState();
}

class _ImagePaintPageState extends State {
    ui.Image? _image;

    @override
    void initState() {
        super.initState();
        loadImage();
    }

    loadImage() async {
        // _image = await loadImageByAssets();
        _image = await loadImageByNet();
        if (!mounted) return;
        setState(() {});
    }

    @override
    Widget build(BuildContext context) {
        return Column(
            children: [
                const Text("绘制图片"),
                Container(
                    width: MediaQuery.of(context).size.width,
                    height: 200,
                    color: Colors.white,
                    child: Center(
                        child: Stack(
                            children: [
                                _image == null
                                ? const CircularProgressIndicator()
                                : CustomPaint(
                                    size: const Size(200, 200),
                                    painter: ImagePainter(_image!),
                                ),
                            ],
                        ),
                    ),
                ),
            ],
        );
    }

    /// 加载Assets图片
    Future loadImageByAssets() async {
        AssetImage assetImage = const AssetImage("assets/images/bird.jpg");
        Completer completer = Completer();
        ImageStream imageStream = assetImage.resolve(ImageConfiguration.empty);
        late ImageStreamListener listener;
        listener = ImageStreamListener((ImageInfo imageInfo, bool synchronousCall) {
            final ui.Image image = imageInfo.image;
            completer.complete(image);
            imageStream.removeListener(listener);
        });
        imageStream.addListener(listener);
        return completer.future;
    }

    /// 加载网络图片
    Future loadImageByNet() async {
        String imageUrl = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png";
        NetworkImage networkImage = NetworkImage(imageUrl);
        Completer completer = Completer();
        ImageStream imageStream = networkImage.resolve(ImageConfiguration.empty);
        late ImageStreamListener listener;
        listener = ImageStreamListener((ImageInfo imageInfo, bool synchronousCall) {
            final ui.Image image = imageInfo.image;
            completer.complete(image);
            imageStream.removeListener(listener);
        });
        imageStream.addListener(listener); //添加监听
        return completer.future;
    }
}

class ImagePainter extends CustomPainter {
    final Paint _paint = Paint()..isAntiAlias = true;

    final ui.Image _image;

    ImagePainter(this._image);

    @override
    void paint(Canvas canvas, Size size) {
        //原图区域,一般传原图的宽高
        Rect src = const Offset(0.0, 0.0) & Size(_image.width.toDouble(), _image.height.toDouble());
        //目标显示区域
        Rect dst = const Offset(0.0, 0.0) & const Size(200, 200);
        canvas.drawImageRect(_image, src, dst, _paint);
    }

    @override
    bool shouldRepaint(covariant CustomPainter oldDelegate) {
        return true;
    }
}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章