SVG 概念
原文地址:https://jfson.github.io/2018/06/21/49-svga/
* SVG 实际上指的是设计软件中的概念:SVG图片格式,一种矢量图形。
* 另一个角度来讲一张图或者一个动画,是由很多上下层级的图层构成。
比如当前的简单的图,看到的是一张图,但在设计工具中是三个图层构成,有着不同的上下层级顺序。
SVGA成本
* SVGA目不支持种类:
* 不支持复杂的矢量形状图层
* AE自带的渐变、生成、描边、擦除…
* 对设计工具原生动画不友好,对图片动画友好(适合映客礼物场景)
* 导出工具[开源](https://github.com/yyued/SVGA-FLConverter)
开发成本
* 1.优点
* 资源包小
* 测试工具齐全
* 三端可用
* 回调完整
* Protobuf 序列化结构数据格式,序列化的数据体更小,传递效率比xml,json 更高。
* 2.缺点
* 每个礼物播放时都去重新解压,需要改一套缓存策略
* svga 用zlib打包(字节流数据压缩程序库),不方便解压和追踪包内容。
* 4.插入动画头像功能
* 支持,需定义一套专属的头像配置的协议。
SVGA 动画库源码思路
* 通过设置帧率,来生成一个配置文件,使得每一帧都有一个配置,每一帧都是关键帧,
* 通过帧率去刷每一帧的画面,这个思路跟gif很像,但是通过配置使得动画过程中图片都可以得到复用。性能就提升上来了。并且不用解析高阶插值(二次线性方程,贝塞尔曲线方程)
源码类图
![image](https://github.com/jfson/ImgResource/blob/master/35.png?raw=true)
* 版本2.1.2(应该是这个版本...)
* 小解
SVGAImageView imageView = new SVGAImageView(this);
parser = new SVGAParser(this);
parser.parse(new URL("http://legox.yy.com/svga/svga-me/angel.svga"), new SVGAParser.ParseCompletion() { // -----> 下文 1
@Override
public void onComplete(@NotNull SVGAVideoEntity videoItem) {
SVGADrawable drawable = new SVGADrawable(videoItem);
imageView.setImageDrawable(drawable); // -----> 下文 2
imageView.startAnimation();// -----> 下文 3
}
@Override
public void onError() {
}
});
* 1.解析 SVGAParser
* a. AE导出动画文件,在解析出的SVGAVideoEntity为动画数据源,在使用时调用 SVGAParser(this).parse(url) 最后返回SVGAVideoEntity。
* b.parse中是一整套的网络下载,根据下载url作为缓存KEY值,缓存动画文件,如果已经下载过的文件,直接去读取文件流并解析。可以看到关键源码如下。PS:这里引申出一个问题,数据源SVGAVideoEntity并没有做缓存,所以每次播放之时,即便是动画文件已经download下来,还是要重新去解析,这是可以跟需要改进的地方。
open fun parse(url: URL, callback: ParseCompletion) {
if (cacheDir(cacheKey(url)).exists()) {
parseWithCacheKey(cacheKey(url))?.let {
Handler(context.mainLooper).post {
callback.onComplete(it)
}
return
}
}
fileDownloader.resume(url, {
val videoItem = parse(it, cacheKey(url)) ?: return@resume (Handler(context.mainLooper).post { callback.onError() } as? Unit ?: Unit)
Handler(context.mainLooper).post {
callback.onComplete(videoItem)
}
}, {
Handler(context.mainLooper).post {
callback.onError()
}
})
}
open fun parseWithCacheKey(cacheKey: String): SVGAVideoEntity? {
synchronized(sharedLock, {
try {
val cacheDir = File(context.cacheDi