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,替换指定元素。

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

相关推荐
Eric_HYD2 小时前
Flutter 字体字生效原理解析
flutter
maaath2 小时前
【无标题】Flutter for OpenHarmony 的文具手账应用开发实践
flutter·华为·harmonyos
里欧跑得慢2 小时前
Flutter 主题管理:构建一致的用户界面
前端·css·flutter·web
liulian091617 小时前
Flutter for OpenHarmony 跨平台开发:单位转换功能实战指南
flutter
千码君201618 小时前
Trae:一些关于flutter和 go前后端开发构建的分享
android·flutter·gradle·android-studio·trae·vibe code
maaath19 小时前
【maaath】Flutter for OpenHarmony 手表配饰应用实战开发
flutter·华为·harmonyos
maaath20 小时前
【maaath】Flutter for OpenHarmony 跨平台计算器应用开发实践
flutter·华为·harmonyos
maaath1 天前
【maaath】Flutter for OpenHarmony 闹钟时钟应用开发实战
flutter·华为·harmonyos
maaath1 天前
【maaath】Flutter for OpenHarmony 短信管理应用实战
flutter·华为·harmonyos
maaath1 天前
【maaath】Flutter for OpenHarmony打造跨平台便签备忘录应用
flutter·华为·harmonyos