ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

flutter 绘画

2022-05-26 14:32:17  阅读:168  来源: 互联网

标签:canvas const color Text 绘画 radius Offset flutter


效果:

 

 

 实现:

import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

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

  @override
  State<CustomPaintPainterPage> createState() => _CustomPaintPainterPageState();
}

class _CustomPaintPainterPageState extends State<CustomPaintPainterPage> {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('基础理解', style: TextStyle(color: Colors.red)),
          const Text("    Paint:在画布上绘制时要使用的样式的描述(可描述为画笔)"),
          const Text("    Canvas:用于记录图形操作的界面(可描述为画布)"),
          const Text(
              "    Path:可以使用Canvas.drawPath在画布上绘制路径。并可用于使用Canvas.clipPath创建剪辑区域"),
          const SizedBox(height: 20),
          const Text("在flutter中并不是直接使用Paint、Canvas,而是使用进一步封装的widget,如下"),
          const Text(
              '官方https://api.flutter.dev/flutter/widgets/CustomPaint-class.html'),
          const Text('CustomPaint:', style: TextStyle(color: Colors.red)),
          const Text('    提供在绘制阶段绘制的画布,并利用CustomPainter来运行绘制指令的组件'),
          const Text('    它通常会将painter和child内嵌在其构造函数内:'),
          const Text('     painter是CustomPainter类的实例'),
          const Text('CustomPainter:', style: TextStyle(color: Colors.red)),
          const Text(
              '    CustomPaint(在widgets库中)和RenderCustomPaint(在渲染库中)使用的接口'),
          const Text('    画布绘制发生的地方'),
          const Text('    CustomPainter基类化,需要重写两个功能paint和shouldRepaint:'),
          const Text('    CustomPainter基类化,需要重写两个功能paint和shouldRepaint:'),
          const Text(
              '    paint方法是用于绘制的,它有两个参数Canvas和Size,所有的绘制指令应在指定大小的范围中发生;shouldRepaint它控制painter重绘的时间'),
          const SizedBox(
            height: 50,
          ),
          CustomPaint(
            foregroundPainter: MyPainter(),
            child: Container(
              color: Colors.blue,
              width: 600,
              height: 200,
            ),
          ),
          const SizedBox(
            height: 50,
          ),
          CustomPaint(
            foregroundPainter: SmilePainter(),
            child: Container(
              color: Colors.blue,
              width: 600,
              height: 200,
            ),
          ),
          const SizedBox(
            height: 50,
          ),
          CustomPaint(
            foregroundPainter: Sky(),
            child: Container(
              color: Colors.white,
              width: 600,
              height: 200,
            ),
          ),
          const SizedBox(
            height: 50,
          ),
          CustomPaint(
            painter: Sky(),
            child: const Center(
              child: Text(
                'Once upon a time...',
                style: TextStyle(
                  fontSize: 40.0,
                  fontWeight: FontWeight.w900,
                  color: Color(0xFFFFFFFF),
                ),
              ),
            ),
          ),
          const SizedBox(
            height: 50,
          ),
          CustomPaint(
            foregroundPainter: Pentagram(Colors.black),
            child: Container(
              color: Colors.blue,
              width: 200,
              height: 200,
            ),
          ),
        ],
      ),
    );
  }
}

class Pentagram extends CustomPainter {
  Pentagram(this.color);
  //画笔的颜色
  final Color color;

  @override
  void paint(Canvas canvas, Size size) {
    Offset getOffsetPosition(int degreen, double radius) {
      //角度转成弧度
      var radian = degreen * pi / 180;
      var dx = sin(radian) * radius;
      var dy = cos(radian) * radius;
      return Offset(dx + radius, dy + radius);
    }

    final paint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.fill;

    var initDegreen = 180;
    double radius = 100;
    // 连接五角星的五个顶点,360/5,每个是72度
    final path = Path();
    var posOne = getOffsetPosition(initDegreen, radius);
    var posTwo = getOffsetPosition(72 + initDegreen, radius);
    var posThree = getOffsetPosition(144 + initDegreen, radius);
    var posfour = getOffsetPosition(216 + initDegreen, radius);
    var posFive = getOffsetPosition(288 + initDegreen, radius);
    path.moveTo(posOne.dx, posOne.dy);
    path.lineTo(posfour.dx, posfour.dy);
    path.lineTo(posTwo.dx, posTwo.dy);
    path.lineTo(posFive.dx, posFive.dy);
    path.lineTo(posThree.dx, posThree.dy);
    //最后用close的方式把path封闭起来
    path.close();
    canvas.drawPath(path, paint);
  }

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

class SmilePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    const radius = 100.0;
    final center = Offset(size.width / 2.0, size.height / 2.0);
    final paint = Paint()..color = Colors.yellow;
    canvas.drawCircle(center, radius, paint);
    final smilePaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 10;
    canvas.drawArc(Rect.fromCircle(center: center, radius: radius / 2), 0, pi,
        false, smilePaint);
    canvas.drawCircle(
        Offset(center.dx - radius / 2.0, center.dy - radius / 2.0),
        10,
        Paint());
    canvas.drawCircle(
        Offset(center.dx + radius / 2.0, center.dy - radius / 2.0),
        10,
        Paint());
  }

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

class Sky extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final Rect rect = Offset.zero & size;
    const RadialGradient gradient = RadialGradient(
      center: Alignment(0.7, -0.6),
      radius: 0.2,
      colors: <Color>[Color(0xFFFFFF00), Color(0xFF0099FF)],
      stops: <double>[0.4, 1.0],
    );
    canvas.drawRect(
      rect,
      Paint()..shader = gradient.createShader(rect),
    );
  }

  @override
  SemanticsBuilderCallback get semanticsBuilder {
    return (Size size) {
      // Annotate a rectangle containing the picture of the sun
      // with the label "Sun". When text to speech feature is enabled on the
      // device, a user will be able to locate the sun on this picture by
      // touch.
      Rect rect = Offset.zero & size;
      final double width = size.shortestSide * 0.4;
      rect = const Alignment(0.8, -0.9).inscribe(Size(width, width), rect);
      return <CustomPainterSemantics>[
        CustomPainterSemantics(
          rect: rect,
          properties: const SemanticsProperties(
            label: 'Sun',
            textDirection: TextDirection.rtl,
          ),
        ),
      ];
    };
  }

  @override
  bool shouldRepaint(Sky oldDelegate) => false;
  @override
  bool shouldRebuildSemantics(Sky oldDelegate) => false;
}

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint onePaint = Paint()
      ..style = PaintingStyle.fill // 是否填充
      ..color = Colors.red
      ..strokeWidth = 3;
    Paint twoPaint = Paint()
      ..style = PaintingStyle.stroke // 是否填充
      ..color = Colors.white
      ..strokeWidth = 3;
    // canvas.drawPaint(newPaint);
    canvas.drawCircle(const Offset(75, 95), 50, onePaint);
    canvas.drawLine(const Offset(70, 30), const Offset(170, 30), onePaint);
    canvas.drawRect(
        Rect.fromPoints(const Offset(140, 80), const Offset(190, 60)),
        onePaint);
    canvas.drawCircle(const Offset(275, 95), 50, twoPaint);
    canvas.drawLine(const Offset(270, 30), const Offset(370, 30), twoPaint);
    canvas.drawRect(
        Rect.fromPoints(const Offset(340, 80), const Offset(390, 60)),
        twoPaint);
  }

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

 

标签:canvas,const,color,Text,绘画,radius,Offset,flutter
来源: https://www.cnblogs.com/lulushen/p/16313336.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有