如何在flutter中使用Canvas绘制水平圆角菱形(菱形)?

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

我想要我的钻石小部件有边框/角半径。

像这样:

BorderRadius.all(Radius.circular(cornerRadius))

我可能应该使用 Path 的 arcToPoint、arcTo 或quadraticBezierTo 函数,但找不到任何好的文档/示例。

import 'package:flutter/material.dart';

/// Diamond Widget
class Diamond extends StatelessWidget {
  /// Constructor
  const Diamond({
    required this.width,
    required this.height,
    this.lineColor = Colors.black,
    this.cornerRadius = 8.0,
    super.key,
  });

  /// Width of the diamond
  final double width;

  /// Height of the diamond
  final double height;

  /// Outline's color of the diamond
  final Color lineColor;

  /// Corner radius of the diamond
  final double cornerRadius;

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(width, height),
      painter: _DiamondPainter(
        lineColor: lineColor,
        cornerRadius: cornerRadius,
      ),
    );
  }
}

/// Custom painter for drawing a diamond
class _DiamondPainter extends CustomPainter {
  _DiamondPainter({required this.lineColor, required this.cornerRadius});

  final Color lineColor;
  final double cornerRadius;

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..style = PaintingStyle.stroke
      ..color = lineColor
      ..strokeWidth = 2.0;

    final Path path = Path()
      ..moveTo(size.width / 2, 0) // Top center
      ..lineTo(size.width, size.height / 2) // Right center
      ..lineTo(size.width / 2, size.height) // Bottom center
      ..lineTo(0, size.height / 2) // Left center
      ..close();

    canvas.drawPath(path, paint); // Draw the outlined diamond
  }

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

这是正确绘制菱形但没有圆角的不完整示例代码。我想完成这段代码并在实现中使用

cornerRadius

我尝试使用 RRect 和 Clips,但它们也不起作用。

flutter dart canvas path paint
1个回答
0
投票

我发现你关于使用贝塞尔曲线的想法很有趣,并决定尝试一下。我不确定这是否是最有效的实现,但它的工作原理如您所描述的那样。如果我没猜错的话,当然可以! :)

我稍微修改了你的画家的

paint
。在这里:

  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..style = PaintingStyle.stroke
      ..color = lineColor
      ..strokeWidth = 2.0;

    final Path path = Path()
      ..moveTo(size.width / 2 + cornerRadius, 0 + cornerRadius) // Top center
      ..lineTo(size.width - cornerRadius,
          size.height / 2 - cornerRadius) // Right center
      ..quadraticBezierTo(size.width, size.height / 2,
          size.width - cornerRadius, size.height / 2 + cornerRadius)
      ..lineTo(size.width / 2 + cornerRadius,
          size.height - cornerRadius) // Bottom center
      ..quadraticBezierTo(size.width / 2, size.height,
          size.width / 2 - cornerRadius, size.height - cornerRadius)
      ..lineTo(0 + cornerRadius, size.height / 2 + cornerRadius) // Left center
      ..quadraticBezierTo(
          0, size.height / 2, 0 + cornerRadius, size.height / 2 - cornerRadius)
      ..lineTo(size.width / 2 - cornerRadius, 0 + cornerRadius)
      ..quadraticBezierTo(
          size.width / 2, 0, size.width / 2 + cornerRadius, 0 + cornerRadius);
    canvas.drawPath(path, paint); // Draw the outlined diamond
  }

这里的关键概念是为每条线提供偏移量,这将创建“空角”。然后,我们用贝塞尔曲线填充这些间隙以实现圆角。

另外,我相信您应该以某种方式验证

cornerRadius
参数,因为它不能大于钻石大小的一半。而且,我的实现仅适用于方形钻石:(但我仍然认为这是解决您的问题的良好起点

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