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

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

dart 复制代码
  # svg
  svgaplayer_flutter: ^2.2.0

2.2、使用SVGASimpleImage

dart 复制代码
class MyWidget extends Widget {

  @override
  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

dart 复制代码
mport 'package:flutter/material.dart';
import 'package:svgaplayer_flutter/svgaplayer_flutter.dart';

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

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

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

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

  @override
  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);
  }

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

2.4、MovieEntity重用

AnimationController的dispose调用后,MovieEntity也将被dispose。在dispose后,MovieEntity不能再使用。

如果要重用MovieEntity,需要设置autorelease为false

dart 复制代码
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替换元素

dart 复制代码
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

dart 复制代码
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);
  }

具体实现如下

dart 复制代码
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,可以找到方法

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

具体文本替换元素的代码

dart 复制代码
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类中找到方法

dart 复制代码
void setHidden(bool value, String forKey) {
    this.dynamicHidden[forKey] = value;
  }

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

dart 复制代码
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类中找到方法

dart 复制代码
void setDynamicDrawer(SVGACustomDrawer drawer, String forKey) {
    this.dynamicDrawer[forKey] = drawer;
  }

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

dart 复制代码
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,替换指定元素。

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

相关推荐
problc7 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人15 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人18 小时前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔1 天前
Flutter启动流程(2)
flutter
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人1 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai1 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人1 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 中的 setState 使用场景与最佳实践
flutter·华为·harmonyos
hello world smile1 天前
Flutter常用命令整理
android·flutter·移动开发·android studio·安卓