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

如何在Flutter中实现带动态参数的类游戏风格信封开启动画

实现动态参数信封开启动画的可行思路

方案一:优化Rive动画实现(适配动态参数)

针对你用Rive遇到的动态参数问题,核心是把动态属性和Rive状态机绑定,同时将难动态替换的内容(卡片文本、图片)放到Flutter层处理:

  • 动态颜色绑定:
    在Rive编辑器中给信封、背景的填充层添加Color类型的State Machine输入(命名如envelopColor、bgColor)。在Flutter代码中通过控制器获取这些输入并赋值:

    final artboard = riveFile.mainArtboard;
    final controller = StateMachineController.fromArtboard(artboard, 'EnvelopeMachine');
    if (controller != null) {
      artboard.addController(controller);
      // 设置信封颜色
      final envColorInput = controller.findInput<ColorInput>('envelopColor');
      if (envColorInput != null) {
        // Rive的Color值为ARGB格式int,需转换
        envColorInput.value = envelopColor.value;
      }
      // 设置背景颜色同理
      final bgColorInput = controller.findInput<ColorInput>('bgColor');
      if (bgColorInput != null) {
        bgColorInput.value = backgroundColor.value;
      }
    }
    
  • 卡片内容动态化:
    不在Rive中制作卡片的文本和图片,直接用Flutter的Text、Image组件,通过Stack叠在Rive动画上方。监听Rive动画进度,当信封打开到指定阶段(比如进度>0.6)时,触发卡片的淡入、平移动画:

    bool _hasTriggeredCardAnim = false;
    controller.addListener(() {
      final progress = controller.progress;
      if (progress > 0.6 && !_hasTriggeredCardAnim) {
        _cardAnimController.forward();
        _hasTriggeredCardAnim = true;
      }
    });
    

    卡片动画可通过AnimatedBuilder结合Tween实现平移+透明度变化。

  • 信封阴影动态生成:
    不在Rive内做阴影,给Rive动画外层套一个Container,根据信封颜色生成阴影色:

    Color generateShadow(Color base) {
      final hsl = HSLColor.fromColor(base);
      // 降低亮度并添加透明度生成阴影
      return hsl.withLightness(hsl.lightness * 0.7).withAlpha(0.4).toColor();
    }
    
    // 使用示例
    Container(
      decoration: BoxDecoration(
        boxShadow: [
          BoxShadow(
            color: generateShadow(envelopColor),
            blurRadius: 12,
            offset: Offset(0, 6),
          )
        ],
      ),
      child: RiveAnimation.asset(...),
    )
    

方案二:纯Flutter自定义动画(完全可控)

如果Rive的动态绑定仍有局限,可采用纯Flutter实现,灵活性更高:

  • 核心动画控制:
    用AnimationController管理整体动画进度,配合Tween定义信封盖的旋转角度、卡片的平移距离和透明度:

    final _animController = AnimationController(
      duration: Duration(milliseconds: 1500),
      vsync: this,
    );
    final _envelopeCoverRotate = Tween<double>(begin: 0, end: pi / 2).animate(
      CurvedAnimation(parent: _animController, curve: Curves.easeInOut),
    );
    final _cardTranslate = Tween<Offset>(begin: Offset(0, 20), end: Offset(0, 0)).animate(
      CurvedAnimation(parent: _animController, curve: Curves.easeOut),
    );
    final _cardOpacity = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: _animController, curve: Interval(0.5, 1)),
    );
    
  • 自定义信封绘制:
    用CustomPainter绘制信封的身和盖,接收envelopColor参数,根据_envelopeCoverRotate的值更新盖的角度:

    class EnvelopePainter extends CustomPainter {
      final Color color;
      final double coverRotation;
    
      EnvelopePainter(this.color, this.coverRotation);
    
      @override
      void paint(Canvas canvas, Size size) {
        // 绘制信封身(矩形)
        final bodyPaint = Paint()..color = color;
        canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), bodyPaint);
        // 绘制信封盖(多边形,结合旋转角度变换顶点位置)
        final coverPath = Path();
        coverPath.moveTo(size.width / 2, 0);
        coverPath.lineTo(size.width, size.height / 2);
        coverPath.lineTo(size.width / 2, size.height);
        coverPath.lineTo(0, size.height / 2);
        coverPath.close();
        canvas.save();
        canvas.translate(size.width / 2, size.height / 2);
        canvas.rotate(coverRotation);
        canvas.translate(-size.width / 2, -size.height / 2);
        canvas.drawPath(coverPath, bodyPaint);
        canvas.restore();
      }
    
      @override
      bool shouldRepaint(covariant EnvelopePainter oldDelegate) {
        return oldDelegate.color != color || oldDelegate.coverRotation != coverRotation;
      }
    }
    
  • 动态参数整合:
    背景色直接用外层Container的color属性;卡片文本、图片直接传入Text、Image.network组件;阴影同样用BoxShadow结合颜色生成函数实现。

  • 交互触发:
    用户点击时调用_animController.forward()触发动画,如需重置可调用_animController.reset()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:37:18