使用路径在 Flutter 中绘制复杂元素,然后以不同角度重新绘制同一元素

Draw complex element in Flutter with path, then redraw this same element in different angles

我需要在 Flutter 中绘制以下小部件:

我已经有了绘制井字棋的方法:

    var path = Path();
    path.lineTo(size.width * 2, size.height * 0.05);
    path.cubicTo(size.width * 2, size.height * 0.05, size.width,
        size.height * 0.05, size.width, size.height * 0.05);
    path.cubicTo(size.width, size.height * 0.05, size.width, size.height * 1.05,
        size.width, size.height * 1.05);
    path.cubicTo(size.width, size.height * 1.05, size.width * 2,
        size.height * 1.05, size.width * 2, size.height * 1.05);
    path.cubicTo(size.width * 2, size.height * 1.05, size.width * 2,
        size.height * 0.05, size.width * 2, size.height * 0.05);

但是,这个井字棋是水平井字棋。我需要用不同的角度绘制多个。将每个放置在何处的数学是简单的三角函数(具有长度的正弦和余弦)。每一个应该形成的角度就是sine/cosine的角度。然而,用Flutter的裁剪工具绘制其中很多是很难的。

有没有办法在flutter中使用path绘制一个复杂的元素,然后在不同的地方稍微旋转一下重绘?

如果不是,我还应该采用哪种其他技术?

形状是带有圆角边框的矩形。您可以使用自定义画图。请看下面的代码或直接在DartPad here >> https://dartpad.dev/e0792a6ab7c9ff3aa1516bfeb77c3886

上运行
import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(MaterialApp(
    home: MyApp(),
    debugShowCheckedModeBanner: false,
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[200],
      body: Center(
        child: CustomPaint(
          painter: PillPainter(
            circleSize: 100,
            pillWidth: 11,
            pillHeight: 20,
            distanceBetweenPills: 10,
          ),
        ),
      ),
    );
  }
}

class PillPainter extends CustomPainter {
  PillPainter({
    this.circleSize,
    this.pillWidth,
    this.pillHeight,
    this.distanceBetweenPills,
  });
  double circleSize;
  double pillWidth;
  double pillHeight;
  int distanceBetweenPills;

  @override
  void paint(Canvas canvas, Size size) {
    final double rotationFactor = 1.75;
    final double numOfPills = 360 / distanceBetweenPills;

    final Paint innerPaint = Paint()
      ..color = Colors.orange
      ..style = PaintingStyle.fill;

    final Path path = Path();

    final double rotationAngle = rotationFactor * pi;
    final double initialDisplacement = 0.75 * pi;

    for (int i = 0; i < numOfPills; i++) {
      path.addRRect(
        RRect.fromRectXY(
            Rect.fromCenter(
                center: Offset(
                    size.width / 2 +
                        circleSize * cos(initialDisplacement + rotationAngle),
                    size.height / 2 +
                        circleSize * sin(initialDisplacement + rotationAngle)),
                width: pillWidth,
                height: pillHeight),
            20,
            20),
      );
      canvas.rotate((distanceBetweenPills * pi) / 180);
      innerPaint.color = i % 2 == 0 ? Colors.green : Colors.red;
      canvas.drawPath(path, innerPaint);
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}