用颤动绘制虚线弧

问题描述 投票:1回答:1

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

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

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

dashed-arc

dart flutter
1个回答
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;
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.