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
# svgsvgaplayer_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,替换指定元素。
学习记录,每天不停进步。