App杂乱动画完成——Rive保姆级教程
作者:京东物流 沈亮堂
在App开发进程中,假如想完成动画作用,能够大略分为两种办法。一种是直接用代码编写,像平移、旋转等简略的动画作用,都能够这么干,假如略微杂乱点,就会对开发工程师的数学功底、图形图像学功底有很高的要求。
另一种办法,能够让UI同学合作,一次性出多张图片或许直接出一张GIF图,经过短时刻内快速轮播图片的办法来完成杂乱动画作用,这种办法真实完成起来仍是有挺多问题的,比方短少对动画进程的操控、图片尺寸的适配等等。那么,有没有更好的解决方案呢?
有的,Rive。
简介
Rive是专门为简化动画的完成而生的,规划师能够在其官网经过迁延拽完成各种杂乱动画作用,规划结束后导出动画文件,工程师能够在App里直接导入此文件,合作相应的SDK即可完成。
其官网有具体的开发文档,一起也有自己的社区资源,咱们能够直接从社区里下载他人规划好的动画作用进行学习。别的特别重要的是,Rive支撑跨渠道,一起支撑Android、iOS、Flutter、JS、React、C++等等,本文以Flutter的完成为例介绍。
一个完好的比如
- 登陆Rive官网进行规划,并导出相应的动画文件,Rive的动画文件是以.riv结束。
本文示例是从官网的社区里找的一个个人比较喜爱的动效。
- 顺次运转下面的指令,引进rive sdk。
- 将导出的.riv文件放到资源目录下,并修正pubspec.yaml文件。
- 加载动画文件并展现的中心代码:
中心代码就这么多,关于代码中的标示具体阐明下:
- 标示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