App复杂动画实现——Rive保姆级教程 | 京东云技术团队

news2024/11/20 7:15:04

作者:京东物流 沈明亮

在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何提升电脑使用体验?试试这5款免费软件吧

今天推荐5款实用的开源软件,它们可以极大地提高你的工作和生活效率,让你办公学习的体验更加舒适。 屏幕截图工具——ShareX ShareX是一款免费的开源软件&#xff0c;可以让你快速地捕捉屏幕上的任何区域&#xff0c;并将其保存为图片或视频文件。你还可以使用ShareX来上传你的…

chatgpt智能提效职场办公-ppt怎么做流程图

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 制作PPT流程图的步骤如下&#xff1a; 打开 PowerPoint&#xff0c;选择自己要制作流程图的PPT页面。 在页面中点击“插入”选项卡&am…

gcc编译的过程

文章目录 前言一、gcc 编译四步骤二、gcc编译常用参数三、文件后缀名对应表四、预处理五、编译六、汇编七、链接1、静态链接2、动态链接 前言 GCC 仅仅是一个编译器&#xff0c;没有界面&#xff0c;必须在命令行模式下使用。通过 gcc 命令就可以将源文件编译成可执行文件。 一…

人机识别技术再升级,AIGC为验证码带来万亿种新变化

网上输入关键词“破解验证码”&#xff0c;会出现1740万个搜索结果。“验证码识别、轻松破解、暴力破解、逻辑漏洞破解、简单破解”等等各类关键词的内容&#xff0c;不一而足&#xff0c;关于“如何用破解某某验证码”的帖子更是多如牛毛。 搜索引擎的相关结果 2017年&#xf…

线程池的构造方式

线程池的构造方式 两类构造方式7种实现方法7种线程池的具体使用FixedThreadPoolCachedThreadPoolSingleThreadExecutorScheduledThreadPoolSingleThreadScheduledExecutornewWorkStealingPoolThreadPoolExecutor 说明总结 两类构造方式 在Java语言中&#xff0c;并发编程都是通…

【重新定义matlab强大系列三】MATLAB清洗离群数据(查找、填充或删除离群值)

&#x1f517; 运行环境&#xff1a;matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

异常详解

一、初识异常 异常概念&#xff1a; 所谓异常指的就是程序在 运行时 出现错误时通知调用者的一种机制。 而运行时指的是程序已经编译通过得到 class 文件了, 再由 JVM 执行过程中出现的错误。 1.除以 0 System.out.println(10 / 0); // 执行结果 Exception in thread "…

02 - 学会提问

学会提问 一、引言 1.1 GPT简介 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一种基于Transformer架构的大型预训练语言模型。 凭借其强大的文本生成、理解和处理能力&#xff0c;GPT已在诸如自然语言处理、机器翻译、文本摘要等多个领域取得了显著的…

python+vue 高校资助系统

其中各子模块的主要功能如下&#xff1a; 1、用户登录&#xff1a;用户进入系统先输入用户名与密码&#xff0c;选择权限登录&#xff0c;用户登录成功&#xff0c;要记录登录的用户名和登录类型。 2、学生注册&#xff1a;学生注册填写学号、密码、确认密码、学生姓名、邮箱、…

Python小姿势 - Python操作MongoDB数据库

Python操作MongoDB数据库 MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。 现在&a…

Leetcode力扣秋招刷题路-0295

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 295. 数据流的中位数 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 …

springboot,Flowable 流程实例的激活与挂起(二)

一.简介 接上一篇 springboot&#xff0c;Flowable 流程实例的激活与挂起&#xff08;一&#xff09; 二.流程实例的挂起与激活 1.流程实例的挂起 挂起一个流程实例的代码如下&#xff1a; Test void test08() {List<ProcessDefinition> list repositoryService.cr…

Cycling 74 Max for Mac:音乐可视化编程软件

Cycling 74 Max是一款音乐、视觉、互动艺术等领域中广泛使用的编程语言和应用软件&#xff0c;它允许用户创作和控制实时音频和视频效果、交互式应用程序和媒体艺术品等。 Max将程序设计和可视化编程相结合&#xff0c;通过简单的拖拽和连接方式&#xff0c;用户可以将各种功能…

cuda编码例程(转载借鉴)

内容出处&#xff1a;https://mp.csdn.net/mp_blog/creation/editor 1. 前言 这是一份简单的CUDA编程入门&#xff0c;主要参考英伟达的官方文档进行学习&#xff0c;本人也是刚开始学习&#xff0c;如有表述错误&#xff0c;还请指出。官方文档链接如下&#xff1a; An Eve…

第2章-类加载子系统

1、本系列博客&#xff0c;主要是面向Java8的虚拟机。如有特殊说明&#xff0c;会进行标注。 2、本系列博客主要参考尚硅谷的JVM视频教程&#xff0c;整理不易&#xff0c;所以图片打上了一些水印&#xff0c;还请读者见谅。后续可能会加上一些补充的东西。 3、尚硅谷的有些视频…

vue 实现el-select组件 配合 el-tabs 完成动态tabs然后有勾选 全选,还有模拟提交,回显数据

cv即可使用 <!DOCTYPE html> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" conten…

Python读取DataFrame的某行或某列

行索引、列索引、loc和iloc import pandas as pd import numpy as np # 准备数据 df pd.DataFrame(np.arange(12).reshape(3,4),indexlist("abc"),columnslist("WXYZ"))行索引(index)&#xff1a;对应最左边那一竖列 列索引(columns)&#xff1a;对应最…

使用手机在网状态查询 API 有效防止虚假注册的设计思路

引言 随着移动互联网的普及&#xff0c;手机在网状态成为重要的数据指标。在网状态反映了手机用户的实际使用情况&#xff0c;对于各类企业和机构具有重要意义。 本文将为大家介绍手机在网状态 API 的主要特点和优势&#xff0c;并且探讨手机在网状态 API 的应用场景和效果展…

【小DS】ABC250 E - Prefix Equality

一开始看题解把我CPU干烧了 后来豁然开朗 E - Prefix Equality (atcoder.jp) 题意&#xff1a; 给定两个数组a,b&#xff0c;每次询问两个位置x和y&#xff0c;问a数组前x个构成的集合和b数组前y个构成的集合是不是一样 思路&#xff1a; 一开始纯暴力RE了 #include <…

IDEA 重磅插件 - Bito – GPT-4

笔者会陆续在个人主页 “AI” 专栏推荐优质 AI 软件、插件、网站… 而不是一股脑地抛给你一堆自行筛选&#xff0c;每一款都是笔者亲自体验感觉还不错的。 如果对你有帮助记得一键三连获取最新优质文章&#xff01; 1.介绍 Bito – GPT-4 Bito – GPT-4 & ChatGPT to writ…