Flutter -居中CustomPaint形状

62lalag4  于 2023-03-24  发布在  Flutter
关注(0)|答案(1)|浏览(102)

我正在构建一个CustomPaint心脏形状,在大小上有动画。最佳状态是下面的圆形GIF。然而,到目前为止,我能够实现的是下面的心脏GIF。
下面是我的CustomPaint代码:

class MyPainter extends CustomPainter {
  // The color of the heart
  final Color color;

  ///[double] minimum radius of the painter
  final double minRadius;

  ///[int] number of wave count in the animation
  final int wavesCount;

  ///[Color] of the painter
  final Animation<double>? _animation;

  MyPainter(
    this.color,
    this.minRadius,
    this.wavesCount,
    this._animation,
  ) : super(repaint: _animation);

  @override
  void paint(Canvas canvas, Size size) {
    for (int wave = 0; wave <= wavesCount; wave++) {
      heart(
        canvas,
        size,
        minRadius,
        wave,
        _animation!.value,
        wavesCount,
        color,
      );
    }
  }

  void heart(
    Canvas canvas,
    Size size,
    double minRadius,
    int wave,
    double anim,
    int? length,
    Color heartColor,
  ) {
    Color color = heartColor;

    if (wave != 0) {
      final double opacity =
          (1 - ((wave - 1) / length!) - anim).clamp(0.0, 1.0);
      color = color.withOpacity(opacity);

      final Paint body = Paint();
      body
        ..color = color
        ..style = PaintingStyle.fill
        ..strokeWidth = 0;

      final double width = size.width * (1 + (wave * anim)) * anim;
      final double height = size.height * (1 + (wave * anim)) * anim;

      final Path path = Path();
      path.moveTo(0.5 * width, height * 0.4);
      path.cubicTo(0.2 * width, height * 0.1, -0.25 * width, height * 0.6,
          0.5 * width, height);
      path.moveTo(0.5 * width, height * 0.4);
      path.cubicTo(0.8 * width, height * 0.1, 1.25 * width, height * 0.6,
          0.5 * width, height);

      canvas.drawPath(path, body);
    }
  }

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

CustomPaint类的用法如下:

class MyRippleState extends State<MyRipple> with TickerProviderStateMixin {
  AnimationController? _controller;

  @override
  void initState() {
    _controller = AnimationController(
      duration: widget.duration,
      vsync: this,
    );

    // repeating or just forwarding the animation once.
    Timer(widget.delay, () {
      widget.repeat ? _controller?.repeat() : _controller?.forward();
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: const Size(150, 150),
      painter: MyPainter(
        vybPrimary,
        widget.minRadius,
        widget.ripplesCount + 2,
        _controller,
      ),
    );
  }

  @override
  void dispose() {
    _controller!.dispose();
    super.dispose();
  }
}

任何帮助/指针,以帮助我在页面中间的心脏形状,就像在圆圈?

yptwkmov

yptwkmov1#

将您的路径替换为:

final Path path = Path();
  final startX =(size.width/2) - (width/2);
  final startY =(size.height/2) - height * 0.6;
  path.moveTo(startX + (0.5 * width), startY + (height * 0.4));
  path.cubicTo(startX + (0.2 * width), startY + (height * 0.1), startX +(-0.25 * width), startY + (height * 0.6),
      startX + (0.5 * width), startY + height);
  path.moveTo(startX + (0.5 * width), startY + (height * 0.4));
  path.cubicTo(startX + (0.8 * width), startY + (height * 0.1), startX + (1.25 * width), startY + (height * 0.6),
      startX + (0.5 * width), startY + height);

  canvas.drawPath(path, body);

相关问题