SVGA源码

本文探讨SVG的概念,是一种矢量图形格式。文章分析了SVGA动画库的开发成本,包括资源包小、测试工具齐全等优点,以及需要改进的缓存策略。通过SVGAParser解析AE导出的动画文件,SVGADrawable负责绘制和播放动画。通过帧率驱动,SVGADrawable不断刷新画面,实现性能提升,避免高阶插值解析。
摘要由CSDN通过智能技术生成


  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
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值