如何为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
相关产品推荐
相关产品推荐

