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

如何为Flutter Flame中的RiveComponent添加圆角矩形边框

给Flame中的Rive动画组件添加圆角矩形边框的解决方案

我开发的Flutter应用包含一个搭载Rive动画的Flame界面,相关代码如下:

class HorizontalAnimComponent extends RiveComponent
    with HasGameRef<Aviator>, TapCallbacks {
  HorizontalAnimComponent(Artboard artboard) : super(artboard: artboard);

  late OneShotAnimation horizController;
 
  @override
  FutureOr<void> onLoad() {
    debugMode = true;
    super.onLoad();
    final screenWidth = gameRef.size[0];
    final screenHeight = gameRef.size[1];
    log(screenWidth.toString());
    log(screenHeight.toString());
    //para manter a proporção da animação : 1200x280
    size = Vector2(screenWidth, screenWidth / 4.2);
    x = 0;
    y = 0;

    anchor = Anchor.topLeft;
    
    horizController = OneShotAnimation('Timeline 1', autoplay: true);
    // horizController = OneShotAnimation('Animation 1', autoplay: true);
    artboard.addController(horizController);
  }

  @override
  void onTapDown(TapDownEvent event) {
    super.onTapDown(event);
    horizController.isActive = !horizController.isActive;
  }
}

class Aviator extends FlameGame {
  late RiveComponent horizontalAnimComponent;

  @override
  Color backgroundColor() {
    super.backgroundColor();
    return Colors.amber;
  }

  @override
  Future<FutureOr<void>> onLoad() async {
    Artboard horizontArtboard =
        await loadArtboard(RiveFile.asset('assets/new_file.riv'));

    add(HorizontalAnimComponent(horizontArtboard));
    // add(Stripes());
    await super.onLoad();
  }
}

目前Rive动画的Artboard是矩形样式,想为其设置圆角矩形边框,以下是几种可行方案:

方案一:用Flutter的ClipRRect包裹GameWidget

如果你的Flame游戏通过GameWidget嵌入Flutter界面,直接用Flutter裁剪组件包裹,简单高效:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: ClipRRect(
        borderRadius: BorderRadius.circular(16), // 自定义圆角大小
        child: GameWidget<Aviator>(
          game: Aviator(),
        ),
      ),
    ),
  );
}

方案二:在Flame组件内部通过Canvas裁剪

如果仅需对单个Rive组件做圆角裁剪,重写组件的render方法,利用Canvas裁剪功能:

class HorizontalAnimComponent extends RiveComponent
    with HasGameRef<Aviator>, TapCallbacks {
  HorizontalAnimComponent(Artboard artboard) : super(artboard: artboard);

  late OneShotAnimation horizController;
  final double _borderRadius = 16; // 自定义圆角半径
 
  @override
  FutureOr<void> onLoad() {
    // 保留原有的onLoad逻辑
    debugMode = true;
    super.onLoad();
    final screenWidth = gameRef.size[0];
    size = Vector2(screenWidth, screenWidth / 4.2);
    x = 0;
    y = 0;
    anchor = Anchor.topLeft;
    
    horizController = OneShotAnimation('Timeline 1', autoplay: true);
    artboard.addController(horizController);
  }

  @override
  void render(Canvas canvas) {
    // 保存当前画布状态
    canvas.save();
    // 创建圆角矩形路径
    final rect = Rect.fromLTWH(0, 0, size.x, size.y);
    final clipPath = Path()
      ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(_borderRadius)));
    // 应用裁剪
    canvas.clipPath(clipPath);
    // 渲染Rive动画
    super.render(canvas);
    // 恢复画布状态
    canvas.restore();
  }

  @override
  void onTapDown(TapDownEvent event) {
    super.onTapDown(event);
    horizController.isActive = !horizController.isActive;
  }
}

方案三:添加圆角边框(裁剪+绘制边框)

如果不仅需要圆角裁剪,还要显示边框,在裁剪后额外绘制圆角边框:

@override
void render(Canvas canvas) {
  canvas.save();
  final rect = Rect.fromLTWH(0, 0, size.x, size.y);
  final clipPath = Path()
    ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(_borderRadius)));
  canvas.clipPath(clipPath);
  super.render(canvas);
  canvas.restore();

  // 绘制圆角边框
  final borderPaint = Paint()
    ..color = Colors.black // 边框颜色
    ..style = PaintingStyle.stroke
    ..strokeWidth = 2; // 边框宽度
  canvas.drawRRect(RRect.fromRectAndRadius(rect, Radius.circular(_borderRadius)), borderPaint);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:39:59