Draw dashed arc with flutter

匆匆过客 提交于 2021-02-10 14:36:34

问题


Is there some way to draw a dashed arc in Flutter?

At the moment I'm using canvas.drawArc but I don't know how to get the correct result.

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

dashed-arc


回答1:


Unfortunately, flutter doesn't handle dashes all that well. There is a plugin that helps with it though: path_drawing

Using that, you can draw any path dashed simply by wrapping it in the dashPath function. That sounds simple enough, but it means that you can't use the canvas.drawArc method which complicates things a little. You have to use canvas.drawPath instead and figure out how to draw a path which is the same as that arc.

This is how I'd do it (and I've put in the code I use to draw the item fit to the canvas which you can use or ignore as you see fit):

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;
  }
}



来源:https://stackoverflow.com/questions/55858914/draw-dashed-arc-with-flutter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!