flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用

news2024/11/29 18:38:22

flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用

最近开发过程中用到了SVGA进行播放动画,这里记录一下svgaplayer_flutter使用过程。svga可以做一些非常精美的动画,包括直播的刷礼物(火箭、跑车特效动画)等等。

效果图如下

在这里插入图片描述

一、SVGA与SVGAPlayer

  • SVGA是什么呢?

SVGA 是一种同时兼容 iOS、Android、Flutter、Web 多个平台的动画格式。

官网地址:https://svga.io/

  • SVGAPlayer是什么呢?

SVGAPlayer是一个轻量的动画渲染库。你可以使用工具从Adobe Animate CC 或者Adobe After Effects 中导出动画文件,然后使用 SVGAPlayer 在移动设备上渲染并播放。

二、svgaplayer_flutter

svgaplayer_flutter通过CustomPainter进行渲染动画。

2.1、引入svgaplayer_flutter

在工程中的pubspec.yaml中引入svgaplayer_flutter

  # svg
  svgaplayer_flutter: ^2.2.0

2.2、使用SVGASimpleImage

class MyWidget extends Widget {

  
  Widget build(BuildContext context) {
    return Container(
      child: SVGASimpleImage(
          resUrl: "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true"),
    );
  }

}

2.3、使用SVGAAnimationController

若要控制动画渲染,需要像Flutter常规动画一样创建SVGAAnimationController实例。分配给SVGAImage,使用SVGAParser加载和解码资源,然后使用SVGAAnimationController按需执行操作。

i

mport 'package:flutter/material.dart';
import 'package:svgaplayer_flutter/svgaplayer_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  SVGAAnimationController animationController;

  
  void initState() {
    this.animationController = SVGAAnimationController(vsync: this);
    this.loadAnimation();
    super.initState();
  }

  
  void dispose() {
    this.animationController.dispose();
    super.dispose();
  }

  void loadAnimation() async {
    final videoItem = await SVGAParser.shared.decodeFromURL(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
    this.animationController.videoItem = videoItem;
    this
        .animationController
        .repeat() // Try to use .forward() .reverse()
        .whenComplete(() => this.animationController.videoItem = null);
  }

  
  Widget build(BuildContext context) {
    return Container(
      child: SVGAImage(this.animationController),
    );
  }
}

2.4、MovieEntity重用

AnimationController的dispose调用后,MovieEntity也将被dispose。在dispose后,MovieEntity不能再使用。
如果要重用MovieEntity,需要设置autorelease为false

final videoItem = await SVGAParser.shared.decodeFromURL(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
videoItem.autorelease = false;

最后在不需要使用videoItem,调用dispose即可

2.5、使用位图替换元素

在我参照H5时候看到代码,可以使用setImage替换元素

var player = new SVGA.Player("#pCanvas");
var parser = new SVGA.Parser('#pCanvas'); 
parser.load('https://github.com/yyued/SVGA-Samples/blob/master/angel.svga', function(item) {
    player.loops = 1;
    player.clearsAfterStop = false;
    player.setImage("imageUrl", "imageKey");
    player.setVideoItem(item);
    player.startAnimation();
    player.onFrame(function (i) {    });
});

之后找到在svgaplayer_flutter也可以使用位图替换指定元素,需要使用的是SVGADynamicEntity
setImage、setImageWithUrl

void setImage(ui.Image image, String forKey) {
    this.dynamicImages[forKey] = image;
  }

  Future<void> setImageWithUrl(String url, String forKey) async {
    this.dynamicImages[forKey] =
        await decodeImageFromList((await get(Uri.parse(url))).bodyBytes);
  }

具体实现如下

Future<void> startSVGAAnim() async {
    animationController = SVGAAnimationController(vsync: this);
    var file = await CustomCacheManager().getSingleFile(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
    var bodyBytes = await file.readAsBytes();
    final videoItem = await SVGAParser.shared.decodeFromBuffer(bodyBytes);
    animationController?.videoItem = videoItem;
    animationController?.videoItem?.dynamicItem.setImageWithUrl("图片地址", "img_key");
    animationController?.forward().whenComplete(() {
      
    });

    if (mounted) {
      setState(() {});
    }
  }

imageKey为SVGA动画中的图层png的文件名,图层png的文件名为abc.png,那么imageKey则为abc。

2.6、使用文本替换元素

在上面使用位图替换指定元素,也可以使用文本替换元素。

在SVGADynamicEntity,可以找到方法

void setText(TextPainter textPainter, String forKey) {
    if (textPainter.textDirection == null) {
      textPainter.textDirection = TextDirection.ltr;
      textPainter.layout();
    }
    this.dynamicText[forKey] = textPainter;
  }

具体文本替换元素的代码

Future<void> startSVGAAnim() async {
    animationController = SVGAAnimationController(vsync: this);
    var file = await CustomCacheManager().getSingleFile(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
    var bodyBytes = await file.readAsBytes();
    final videoItem = await SVGAParser.shared.decodeFromBuffer(bodyBytes);
    animationController?.videoItem = videoItem;
    animationController?.videoItem?.dynamicItem.setText(
        TextPainter(
            text: TextSpan(
                text: "Flutter!",
                style: TextStyle(
                  fontSize: 20,
                  color: Colors.red,
                  fontWeight: FontWeight.bold,
                ))),
        "imageKey");
    animationController?.forward().whenComplete(() {
      
    });

    if (mounted) {
      setState(() {});
    }
  }

imageKey为SVGA动画中的图层png的文件名,图层png的文件名为abc.png,那么imageKey则为abc。

2.7、隐藏显示指定元素

在SVGADynamicEntity也可以隐藏显示指定元素。

SVGADynamicEntity类中找到方法

void setHidden(bool value, String forKey) {
    this.dynamicHidden[forKey] = value;
  }

具体隐藏显示指定元素的代码

Future<void> startSVGAAnim() async {
    animationController = SVGAAnimationController(vsync: this);
    var file = await CustomCacheManager().getSingleFile(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
    var bodyBytes = await file.readAsBytes();
    final videoItem = await SVGAParser.shared.decodeFromBuffer(bodyBytes);
    animationController?.videoItem = videoItem;
    animationController?.videoItem?.dynamicItem.setHidden(true, "imageKey"); // true隐藏元素,false显示元素
    animationController?.forward().whenComplete(() {
      
    });

    if (mounted) {
      setState(() {});
    }
  }

imageKey为SVGA动画中的图层png的文件名,图层png的文件名为abc.png,那么imageKey则为abc。

2.8、指定元素动态绘制

在SVGADynamicEntity可以在指定元素动态绘制图形。

SVGADynamicEntity类中找到方法

void setDynamicDrawer(SVGACustomDrawer drawer, String forKey) {
    this.dynamicDrawer[forKey] = drawer;
  }

具体在指定元素动态绘制图形的代码

Future<void> startSVGAAnim() async {
    animationController = SVGAAnimationController(vsync: this);
    var file = await CustomCacheManager().getSingleFile(
        "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
    var bodyBytes = await file.readAsBytes();
    final videoItem = await SVGAParser.shared.decodeFromBuffer(bodyBytes);
    animationController?.videoItem = videoItem;
    animationController?.videoItem?.dynamicItem.setDynamicDrawer((canvas, frameIndex) {
      canvas.drawRect(Rect.fromLTWH(50, 50, 100, 100), Paint()..color = Colors.blue);
    }, "forKey");
    animationController?.forward().whenComplete(() {
      
    });

    if (mounted) {
      setState(() {});
    }
  }

forKey为SVGA动画中的图层png的文件名,图层png的文件名为abc.png,那么imageKey则为abc。

三、小结

flutter开发实战-svga播放svgaplayer_flutter使用,svgaplayer_flutter播放SVGA,替换指定元素。

学习记录,每天不停进步。

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

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

相关文章

ACL2023论文-系列1

文章目录 Prompt——1.Generated Knowledge Prompting for Commonsense Reasoning核心论文贡献方法效果的影响因素方法实现 Contrastive learning——A Contrastive Framework for Learning Sentence Representations from Pairwise and Triple-wise Perspective in Angular Sp…

【深度学习笔记】梯度消失与梯度爆炸

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

labview 子画面插入面板

1.前言 在前面一篇文章中描述了弹框式显示子画面&#xff0c; labview 弹窗(子vi)_weixin_39926429的博客-CSDN博客 本文介绍插入式显示子画面。 本文的主题在以前的文章中介绍过&#xff0c; labview 插入子面板_labview插入子面板_weixin_39926429的博客-CSDN博客 借用…

JVM学习笔记总结

目录 JVM内存区域划分 1、堆&#xff08;线程共享&#xff09; 2、方法区&#xff08;线程共享&#xff09; 3、栈&#xff08;线程私有&#xff09; 4、程序计数器&#xff08;线程私有&#xff09; JVM类加载机制 加载 验证 准备 解析 初始化 双亲委派模型 JVM垃…

入门力扣自学笔记276 C++ (题目编号:874)

874. 模拟行走机器人 题目&#xff1a; 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以接收以下三种类型的命令 commands &#xff1a; -2 &#xff1a;向左转 90 度 -1 &#xff1a;向右转 90 度 1 < …

【数据库高阶语句】

文章目录 MySQL高阶语句一、常用查询1、按关键字排序 二、实操1.创建表2.排序查询&#xff08;默认不指定是升序排序&#xff0c;后面跟desc是降序排序&#xff09;3.order by还可以结合where进行条件过滤&#xff0c;筛选地址是杭州的学生按分数降序排列4.查询学生信息先按兴趣…

走访慰问空巢老人,连接传递浓浓温情

为了弘扬中华民族尊老、敬老、爱老的优良传统&#xff0c;让老人们感受到政府和社会的温暖&#xff0c;在“端午”来临之际&#xff0c;思南县青年志愿者协会联合思南县民慈社会工作服务中心、思南县小荧星幼儿园、思南县小英豪幼儿园到大河坝镇天坝村开展“走访慰问空巢老人&a…

阿里云短信服务API怎么调用

今天来搞一下阿里云短信服务来实现发送短信功能&#xff0c;其实能提供短信发送服务的平台有很多&#xff0c;但这里我选择的是阿里云&#xff0c;因为阿里云的示例还有代码封装的很简洁&#xff0c;使用起来非常简单&#xff0c;上手非常快&#xff0c;那么费话不多说我们直接…

Python案例|使用卷积网络对星系图片进行分类

星系动物园&#xff08;galaxy zoo&#xff09;是由牛津大学等研究机构组织并邀请公众协助的志愿者科学计划&#xff0c;目的是为超过100万个星系图像进行分类。这是天文学中一次规模浩大的公众星空普查活动&#xff0c;大众参与热情高涨&#xff0c;在近十万名志愿者的积极参与…

libevent:windows环境配置+QT使用

目录 libevent是什么 编译 QT使用 测试代码 libevent是什么 Fast portable non-blocking network programming with Libevent http://www.wangafu.net/~nickm/libevent-book/TOC.html 这篇文档讲的很清楚&#xff0c;尤其是Chapter 1: A tiny introduction to asynchro…

c++11 标准模板(STL)(std::basic_istream)(十二)

定义于头文件 <istream> template< class CharT, class Traits std::char_traits<CharT> > class basic_istream : virtual public std::basic_ios<CharT, Traits> 类模板 basic_istream 提供字符流上的高层输入支持。受支持操作包含带格式的…

【C++】vector 模拟笔记

文章目录 成员变量和迭代器reserve()函数易错点迭代器区间初始化易错点迭代器失效整体代码 成员变量和迭代器 下面有vector 存储示意图&#xff1a;vector 是一个左闭又开的空间&#xff0c;_finish 不能存储有效数据。vector 的 iterator 是T 类型的指针&#xff0c;不要认为 …

Python自动获取字母站视频

如果有疑问的话可以在我的谈论群&#xff1a;706128290 来找我 目录 前言 二、编写代码 1.引入库 2.编写主类 3. 自动获取cookies值和生成headers 4.获取命令行参数 运行效果 前言 browser_cookie3 第三方模块 browser_cookie3是browser_cookie模块的分支&#xff0c;…

Asymmetric Gained Deep Image Compression With Continuous Rate Adaptation文献复现

前言 相关论文阅读自行解决,这里主要是记录代码的学习与实验的复现 github地址 此代码非官方部署代码,而是私人实现的。 本博客仅做学习记录。 1 代码学习 1.1 主要框架部分 这里的主编解码器与高斯建模的方式,采用的是同joint上下联合自回归一样的方式,主要的改动在增益…

【Linux】使用云服务器搭建Linux环境

目录 1.Linux是什么 2.Linux的环境搭建 3.使用Xshell登录主机 1.Linux是什么 Linux&#xff0c;全称GNU/Linux&#xff0c;是一套免费使用和自由传播的类Unix操作系统&#xff0c;是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。 简单来说&#xff0c;Lin…

图文详解Java参数传递类型

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

Linux用户和用户组

Linux是多用户、多任务操作系统 一般来说&#xff0c;一个服务分配一个用户&#xff0c;这个用户只拥有这个服务相关文件的相关权限&#xff0c;如果用户不需要登陆&#xff0c;连密码都可以不分配&#xff0c;一般来说&#xff0c;非法分子都是获取当前进程的的权限来攻击服务…

自然语言处理: 第五章Attention注意力机制

自然语言处理: 第五章Attention注意力机制 理论基础 Attention&#xff08;来自2017年google发表的[1706.03762] Attention Is All You Need (arxiv.org) &#xff09;&#xff0c;顾名思义是注意力机制&#xff0c;字面意思就是你所关注的东西&#xff0c;比如我们看到一个非…

vue3中echarts的使用

效果&#xff1a; 代码&#xff1a; <div class"outcharbox"><a-row :gutter"10"><a-col :span"8" v-for" (item, index) in linesobjdata" :key"item.MonitorItemId"><monitoringItemsChart :colorI…

49天精通Java,第40天,jd-gui反编译class文件,解决jd-gui中文乱码问题

目录 专栏导读一、添加局部变量二、反编译class文件三、解决乱码问题四、产品经理就业实战1、内容简介2、作者简介 专栏导读 本专栏收录于《49天精通Java从入门到就业》&#xff0c;本专栏专门针对零基础和需要进阶提升的同学所准备的一套完整教学&#xff0c;从0开始&#xf…