用颤动画虚线

时间:2019-04-25 23:32:02

标签: dart flutter

有什么办法在Flutter中绘制虚线弧吗?

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

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

dashed-arc

1 个答案:

答案 0 :(得分: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;
  }
}