首页 > 其他分享 >App复杂动画实现——Rive保姆级教程

App复杂动画实现——Rive保姆级教程

时间:2023-04-23 16:01:53浏览次数:45  
标签:Rive 动画 const App timer controller 动画文件

作者:京东物流 沈明亮

在App开发过程中,如果想实现动画效果,可以粗略分为两种方式。一种是直接用代码编写,像平移、旋转等简单的动画效果,都可以这么干,如果稍微复杂点,就会对开发工程师的数学功底、图形图像学功底有很高的要求。

另一种方式,可以让UI同学配合,一次性出多张图片或者直接出一张GIF图,通过短时间内快速轮播图片的方式来实现复杂动画效果,这种方式真正实现起来还是有挺多问题的,比如缺少对动画过程的控制、图片尺寸的适配等等。那么,有没有更好的解决方案呢?

有的,Rive。

简介

Rive是专门为简化动画的实现而生的,设计师可以在其官网通过拖拉拽实现各种复杂动画效果,设计完毕后导出动画文件,工程师可以在App里直接导入此文件,配合相应的SDK即可实现。

其官网有详细的开发文档,同时也有自己的社区资源,我们可以直接从社区里下载别人设计好的动画效果进行学习。另外特别重要的是,Rive支持跨平台,同时支持Android、iOS、Flutter、JS、React、C++等等,本文以Flutter的实现为例介绍。

一个完整的例子

  1. 登陆Rive官网进行设计,并导出相应的动画文件,Rive的动画文件是以.riv结尾。

本文示例是从官网的社区里找的一个个人比较喜欢的动效。

  1. 依次运行下面的命令,引入rive sdk。

  1. 将导出的.riv文件放到资源目录下,并修改pubspec.yaml文件。

  1. 加载动画文件并展示的核心代码:

核心代码就这么多,对于代码中的标注详细说明下:

  • 标注1的地方,主要作用是获取状态机控制器,fromArtboard 方法有两个参数,第二个参数是状态机的名称,这个名称需要和UI同学协商好,一旦确定好名称就不允许设计同学再改了,对应于设计面板界面的左下角,如下图:

  • 标注2的地方,本例的动画是根据“数值”的变化而变化的,findInput的入参同样需要和UI同学协商好,一旦设计时把这个名字改了,代码里也别忘了进行相应的修改,也在设计面板的左下角,在状态机名称的右边,如下图:

完整的代码如下,大家可以按步骤自己操作体验下。

class RiveDemo extends StatefulWidget {
  const RiveDemo({Key? key}) : super(key: key);

  @override
  State<RiveDemo> createState() => _RiveDemoState();
}

class _RiveDemoState extends State<RiveDemo> {
  /// 状态机控制器
  StateMachineController? controller;
  /// 控制输入数值
  SMIInput<double>? valueController;
  ///画板,配合Rive widget 使用,展示动画效果。
  Artboard? riveArtboard;
  Timer? timer;

  @override
  void initState() {
    super.initState();
    //加载
    rootBundle.load('asset/rives/rive_demo.riv').then((value) async {
      final file = RiveFile.import(value);
      final artboard = file.mainArtboard;
      //1
      controller = StateMachineController.fromArtboard(artboard, 'TreeMachine');
      if (controller != null) {
        setState(() {
          artboard.addController(controller!);
          //2
          valueController = controller!.findInput('input');
          valueController!.value = -4;
        });
      }

      riveArtboard = artboard;
    });
  }

  @override
  void dispose() {
    controller?.dispose();
    stopAnimation();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Rive Demo'),
      ),
      backgroundColor: Colors.white,
      body: Center(
        child: riveArtboard == null ? const CircularProgressIndicator() : Rive(artboard: riveArtboard!),
      ),
      floatingActionButton: SizedBox(
        height: 50,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            TextButton(
              onPressed: () {
                startAnimation();
              },
              child: const Text('start'),
            ),
            TextButton(
              onPressed: () {
                stopAnimation();
              },
              child: const Text('stop'),
            ),
            TextButton(
              onPressed: () {
                resetAnimation();
              },
              child: const Text('reset'),
            ),
          ],
        ),
      ),
    );
  }

  /// 开始动画
  void startAnimation() {
    if (timer != null) {
      return;
    }
    timer = Timer.periodic(const Duration(milliseconds: 60), (timer) {
      valueController?.value += 0.5;
    });
  }

  /// 停止动画
  void stopAnimation() {
    timer?.cancel();
    timer = null;
  }

  /// 重置动画
  void resetAnimation() {
    stopAnimation();
    valueController?.value = 0;
  }
}

总结

像本例中的动画效果,如果用代码来编写,时间成本会很大很大,如果靠图片的堆积,实现起来也很麻烦,而且由于图片的数量增多,安装包的体积也会增加很多。但是用rive,实现起来却很方便,可能唯一的成本就是设计师同学的学习成本。

Rive不仅支持本地动画文件的加载,还可以将动画文件放到服务器上,利用RiveAnimation.network方法进行加载。更多的使用示例可以参考:
https://github.com/rive-app/rive-flutter/tree/master/example

标签:Rive,动画,const,App,timer,controller,动画文件
From: https://www.cnblogs.com/jingdongkeji/p/17346773.html

相关文章

  • Django全栈进阶之路3 Django4项目APP
    Django4项目APPdjango-adminstartappapp01或pythonmanage.pystartappapp01 #app01是app名称    PyCharm的样子:  ......
  • uniapp directive 在原生 wgt 包不生效 uniapp directive 不生效
    需求根据权限编码禁用按钮阻止当前dom绑定的点击事件,禁用状态(opacity半透明??或者display:none??)尝试开发环境用Chrome跑,一切正常,构建打包后去真机跑,按钮没控制住(用HBX-发行-原生应用app制作wgt包)开发环境:HBX:3.7.9系统:MacOS:13.0.1(Intel)通过direct......
  • vue实现的常见的动画效果
    本文包括的动画:zoom-inzoom-in-leftzoom-in-rightzoom-in-topzoom-in-bottomzoom-in-center-xzoom-in-center-yslideslide-leftslide-rightslide-topslide-bottomzoom-in-left.ivy-zoom-in-left-enter-active,.ivy-zoom-in-left-leave-active{transition:all0.3sease;......
  • uiautomator2+app ui自动化用例报错截图pytest_runtest_makereport
    pytest提供了pytest_runtest_makereport这个方法,可以捕获用例的执行情况。根据官方提供的示例,在conftest.py文件中添加如下代码就可以捕获每个用例的执行结果。那么pytest_runtest_makereport作用:对于给定的测试用例(item)和调用步骤(call),返回一个测试报告对象(_pytest.runne......
  • web3 产品介绍: walletconnect 连接Web3 DApps与用户的移动加密钱包
    WalletConnect是一种去中心化的开源协议,旨在连接Web3DApps与用户的移动加密钱包,提供更安全、更便捷的加密货币交易体验。在本文中,我们将介绍WalletConnect的主要特点、工作原理以及如何使用它来连接DApps和移动钱包。一、WalletConnect的特点去中心化:WalletConnect不依赖于任......
  • Apple设备_Mac键盘快捷键
    0、官方链接Mac键盘快捷键Mac辅助功能快捷键Safari浏览器键盘及其他快捷键1、剪切、拷贝、粘贴和其他常用快捷键Command-X:剪切所选项并拷贝到剪贴板。Command-C:将所选项拷贝到剪贴板。这同样适用于“访达”中的文件。Command-V:将剪贴板的内容粘贴到当前文稿或......
  • Apple设备_MFi认证
    1、MFi认证1.1什么是MFi认证苹果MFi认证,是苹果公司(AppleInc.)对其授权配件厂商生产的外置配件的一种标识使用许可,是Apple公司“MadeforiOS”的英文缩写。市面上认证产品的显著标识就是在包装正面出现如下白底黑字的苹果MFi授权logo,如本文开头图片所示。苹果......
  • Win10 资源管理器导航栏设置:显示库,删除6个文件夹和隐藏OneDrive
    如果你和我一样是刚刚从windows7升级到windows10的,我猜你也会发现资源管理器导航栏里略微恼人的变化:库文件不见了,我的电脑里出现了无法隐藏也无法删除的“我的音乐”之类文件(这一个页面里面显示两边也是醉了!),一个懒得使用的Onedrive占据一方。搞掉他!但是好像不是那么简单。花了点时......
  • 【HMS Core】视频编辑服务报错method not allowed 20124、Parameter error. Error: ap
    【关键字】视频编辑服务、报错 【问题背景】问题1:集成视频剪辑服务,在原子能力SDK的素材管理时,提示Parametererror.Error:appIdisinvalid.问题2:视频编辑sdkdemo的所有功能提示methodnotallowed20124,后台已申请动态照片、一键微笑、AI着色、一键动效、一键染发的功能......
  • 读书笔记(CSAPP)02
    gcc-Og-Smstore.c上述命令行Og意思是优化等级,指生成符合原始C代码整体结构的机器代码的优化等级,S是产生一个汇编文件,就可以查看编译器产生的汇编代码gcc-Og-cmstore.c上述命令行则是生成".o"的目标代码,它是二进制的,是给机器执行的字节序列,也就是对一系列指令......