Autor: JD Logística Shen Mingliang
No processo de desenvolvimento do aplicativo, se você deseja obter efeitos de animação, pode dividi-lo aproximadamente em duas maneiras. Uma é escrever diretamente no código. Efeitos de animação simples, como translação e rotação, podem ser feitos dessa maneira. Se for um pouco mais complicado, terá altos requisitos para as habilidades matemáticas e gráficas do engenheiro de desenvolvimento.
Outra maneira é permitir que os alunos da IU cooperem para produzir várias imagens ao mesmo tempo ou produzir diretamente uma imagem GIF e realizar efeitos de animação complexos girando imagens rapidamente em um curto período de tempo. Existem muitos problemas, como falta de controle sobre o processo de animação, adaptação do tamanho da imagem e assim por diante. Então, existe uma solução melhor?
Sim, Rive.
Introdução
O Rive foi especialmente projetado para simplificar a realização da animação. Os designers podem arrastar e soltar vários efeitos de animação complexos em seu site oficial. Após a conclusão do design, exporte o arquivo de animação. Os engenheiros podem importar este arquivo diretamente no aplicativo e cooperar com o SDK correspondente para pode alcançar.
Seu site oficial possui documentos de desenvolvimento detalhados e também possui seus próprios recursos da comunidade. Podemos baixar diretamente efeitos de animação projetados por outras pessoas da comunidade para aprendizado. Além disso, é particularmente importante que o Rive suporte plataforma cruzada e suporte Android, iOS, Flutter, JS, React, C++, etc. Este artigo usa a implementação do Flutter como um exemplo a ser apresentado.
um exemplo completo
- Faça login no site oficial do Rive para projetar e exportar os arquivos de animação correspondentes. Os arquivos de animação do Rive terminam com .riv.
O exemplo neste artigo é um efeito dinâmico favorito encontrado na comunidade do site oficial.
- Execute os seguintes comandos em sequência para importar rive sdk.
- Coloque o arquivo .riv exportado no diretório de recursos e modifique o arquivo pubspec.yaml.
- O código principal para carregar arquivos de animação e exibi-los:
Existem tantos códigos principais, vamos explicar as anotações no código em detalhes:
- O local marcado como 1 é usado principalmente para obter o controlador da máquina de estado. O método fromArtboard tem dois parâmetros. O segundo parâmetro é o nome da máquina de estado. Esse nome precisa ser negociado com os alunos da interface do usuário. Uma vez determinado o nome, o os alunos de design não podem alterar, correspondendo ao canto inferior esquerdo da interface do painel de design, conforme mostrado abaixo:
- 标注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方法进行加载。更多的使用示例可以参考:
github.com/rive-app/ri…
本文正在参加「金石计划」