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

作者:京东物流 沈明亮

在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同学协商好,一旦设计时把这个名字改了,代码里也别忘了进行相应的修改,也在设计面板的左下角,在状态机名称的右边,如下图:

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

1class RiveDemo extends StatefulWidget { 2 const RiveDemo({Key? key}) : super(key: key); 3 4 @override 5 State<RiveDemo> createState() => _RiveDemoState(); 6} 7 8class _RiveDemoState extends State<RiveDemo> { 9 /// 状态机控制器 10 StateMachineController? controller; 11 /// 控制输入数值 12 SMIInput<double>? valueController; 13 ///画板,配合Rive widget 使用,展示动画效果。 14 Artboard? riveArtboard; 15 Timer? timer; 16 17 @override 18 void initState() { 19 super.initState(); 20 //加载 21 rootBundle.load('asset/rives/rive_demo.riv').then((value) async { 22 final file = RiveFile.import(value); 23 final artboard = file.mainArtboard; 24 //1 25 controller = StateMachineController.fromArtboard(artboard, 'TreeMachine'); 26 if (controller != null) { 27 setState(() { 28 artboard.addController(controller!); 29 //2 30 valueController = controller!.findInput('input'); 31 valueController!.value = -4; 32 }); 33 } 34 35 riveArtboard = artboard; 36 }); 37 } 38 39 @override 40 void dispose() { 41 controller?.dispose(); 42 stopAnimation(); 43 super.dispose(); 44 } 45 46 @override 47 Widget build(BuildContext context) { 48 return Scaffold( 49 appBar: AppBar( 50 title: const Text('Rive Demo'), 51 ), 52 backgroundColor: Colors.white, 53 body: Center( 54 child: riveArtboard == null ? const CircularProgressIndicator() : Rive(artboard: riveArtboard!), 55 ), 56 floatingActionButton: SizedBox( 57 height: 50, 58 child: Row( 59 mainAxisAlignment: MainAxisAlignment.end, 60 children: [ 61 TextButton( 62 onPressed: () { 63 startAnimation(); 64 }, 65 child: const Text('start'), 66 ), 67 TextButton( 68 onPressed: () { 69 stopAnimation(); 70 }, 71 child: const Text('stop'), 72 ), 73 TextButton( 74 onPressed: () { 75 resetAnimation(); 76 }, 77 child: const Text('reset'), 78 ), 79 ], 80 ), 81 ), 82 ); 83 } 84 85 /// 开始动画 86 void startAnimation() { 87 if (timer != null) { 88 return; 89 } 90 timer = Timer.periodic(const Duration(milliseconds: 60), (timer) { 91 valueController?.value += 0.5; 92 }); 93 } 94 95 /// 停止动画 96 void stopAnimation() { 97 timer?.cancel(); 98 timer = null; 99 } 100 101 /// 重置动画 102 void resetAnimation() { 103 stopAnimation(); 104 valueController?.value = 0; 105 } 106} 107 108

总结

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

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

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

PPDB:今晚老齐直播

【今晚老齐直播】今晚(本周三晚)20:0021:00小白开始“用”飞桨(https://www.oschina.net/action/visit/ad?id1185)由PPDE(飞桨(https://www.oschina.net/action/visit/ad?id1185)开发者专家计划)成员老齐,为深度学习小白指点迷津。

VBox 启动虚拟机失败

在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern

FLV文件格式

1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.