用颤振绘制虚线



有没有办法在 Flutter 中画一个虚线?

目前我正在使用canvas.drawArc,但我不知道如何获得正确的结果。

    canvas.drawArc(
      rectangle,
      startAngle,
      fullArcRadius,
      false,
      Paint()
        ..color = Colors.black
        ..strokeCap = StrokeCap.round
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2.0,
    );

虚线弧

不幸的是,颤振不能很好地处理破折号。不过有一个插件可以帮助它:path_drawing

使用它,您只需将其包装在 dashPath 函数中即可绘制任何虚线路径。这听起来很简单,但这意味着你不能使用canvas.drawArc方法,这使事情变得有点复杂。你必须改用canvas.drawPath,并弄清楚如何绘制一条与该弧线相同的路径。

这就是我的做法(我已经输入了我用来绘制适合画布的项目的代码,您可以根据需要使用或忽略它(:

import 'package:flutter/material.dart';
import 'package:path_drawing/path_drawing.dart';
class DashedArc extends CustomPainter {
  final Color color;
  DashedArc({Color color}) : color = color ?? Colors.white;
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: remove me. This makes it easier to tell
    // where the canvas should be
    canvas.drawRect(
        Offset.zero & size,
        Paint()
          ..color = Colors.black
          ..style = PaintingStyle.stroke);
    var width = 520, height = 520, scale;
    // this is a simple Boxfit calculation for the `cover` mode. You could
    // use the applyBoxFit function instead, but as it doesn't return a 
    // centered rect it's almost as much work to use it as to just do it
    // manually (unless someone has a better way in which case I'm all ears!)
    double rw = size.width / width;
    double rh = size.height / height;
    double actualWidth, actualHeight, offsetLeft, offsetTop;
    if (rw > rh) {
      // height is constraining attribute so scale to it
      actualWidth = rh * width;
      actualHeight = size.height;
      offsetTop = 0.0;
      offsetLeft = (size.width - actualWidth) / 2.0;
      scale = rh;
    } else {
      // width is constraining attribute so scale to it
      actualHeight = rw * height;
      actualWidth = size.width;
      offsetLeft = 0.0;
      offsetTop = (size.height - actualHeight) / 2.0;
      scale = rw;
    }
    canvas.translate(offsetLeft, offsetTop);
    canvas.scale(scale);
    // parameters from the original drawing (guesstimated a bit using
    // preview...)
    const double startX = 60;
    const double startY = 430; // flutter starts counting from top left
    const double dashSize = 5;
    const double gapSize = 16;
    canvas.drawPath(
        dashPath(
            Path()
              // tell the path where to start
              ..moveTo(startX, startY)
              // the offset tells the arc where to end, the radius is the
              // radius of the circle, and largeArc tells it to use the 
              // big part of the circle rather than the small one. 
              // The implied parameter `clockwise` means that it starts the arc
              // and draw clockwise; setting this to false would result in a large
              // arc below!
              ..arcToPoint(Offset(520 - startX, startY), radius: Radius.circular(260), largeArc: true),
            // dash is `dashSize` long followed by a gap `gapSize` long
            dashArray: CircularIntervalList<double>([dashSize, gapSize]),
            dashOffset: DashOffset.percentage(0.005)),
        Paint()
          ..color = Colors.black
          ..style = PaintingStyle.stroke
          ..strokeWidth = dashSize);
  }
  @override
  bool shouldRepaint(DashedArc oldDelegate) {
    return oldDelegate.color != this.color;
  }
}

最新更新