You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何使CustomPaint绘制的带动画心形居中显示?

解决CustomPaint心形动画居中问题

你的心形偏移核心原因是绘制路径时没有对齐画布中心,默认从左上角(0,0)开始绘制,导致整体偏移。以下是具体修改方案:

修改MyPainter的heart方法

关键是先将画布平移到CustomPaint的中心,再把心形路径的中心调整到原点,这样绘制出的图形自然居中:

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;

    // 保存画布状态,平移到CustomPaint的中心位置
    final Offset canvasCenter = Offset(size.width / 2, size.height / 2);
    canvas.save();
    canvas.translate(canvasCenter.dx, canvasCenter.dy);

    // 调整路径坐标,让心形自身中心对齐原点(0,0)
    final Path path = Path();
    // 原路径基于左上角绘制,转换为以自身中心为原点的相对坐标
    path.moveTo(0, -height * 0.1);
    path.cubicTo(
      -width * 0.3, -height * 0.4,
      -width * 0.75, height * 0.1,
      0, height * 0.5,
    );
    path.moveTo(0, -height * 0.1);
    path.cubicTo(
      width * 0.3, -height * 0.4,
      width * 0.75, height * 0.1,
      0, height * 0.5,
    );

    canvas.drawPath(path, body);
    // 恢复画布状态,避免影响后续波纹的绘制
    canvas.restore();
  }
}

原理说明

  1. 画布平移:通过canvas.translate把绘制原点移到CustomPaint的中心,确保所有波纹从中心向外扩散。
  2. 路径坐标转换:将原本基于左上角的路径坐标,转换为以心形自身中心为原点的相对坐标,平移后心形自然居中。
  3. 状态隔离:用canvas.save()和canvas.restore()隔离每个波纹的画布变换,防止多个波纹的平移叠加导致偏移。

修改后,心形动画就会和圆形示例一致,始终保持在页面中心向外扩散。

内容的提问来源于stack exchange,提问作者iampapagray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:12:24