YY-SVGA动画框架
写在个人微信订阅号:https://mp.weixin.qq.com/s/mBxwTQjRdQaRqR_43aMhYg
YY最近开源了一个动画框架,可以直接把设计师做好的动画源文件转换成特定格式,并且在Android,iOS,Web三端进行播放,集成很方便,所以尝试了一下,效果很酷炫,记录一下心得体验。
demo地址:https://github.com/LittleNum/SVGA-Samples.git
框架地址:https://github.com/yyued/SVGAPlayer-Android
动画源文件转换工具:
AE——https://github.com/yyued/SVGA-AEConverter
Flash——https://github.com/yyued/SVGA-FLConverter
框架的起源和过程可以看这两篇文章:
https://mp.weixin.qq.com/s/f_ldQtMpA7GdQWDP40V45w
https://mp.weixin.qq.com/s/CUUrJGLObtE6yX8NGDveGw
使用方法:
动画制作:
可以尝试使用AdobeAfter Effects CC 2017制作简单的动画
并利用提供的转换工具,得到.svga文件
播放:
添加依赖,播放.svga文件
add JitPack.io repo build.gradle
allprojects {repositories {…maven {url ‘https://jitpack.io‘}}
}
add dependency to build.gradle
compile ‘com.github.yyued:SVGAPlayer-Android:2.0.3’
解决的问题:
传统的帧动画,属性动画,gif或者webP无法满足使用需求 ;
增强动画显示效果,减轻程序员的代码量,做到直接展示设计效果;
提升性能,减小动画文件大小,动态更新动画。
使用场景:
直接使用SVGAImageView
<com.opensource.svgaplayer.SVGAImageViewandroid:id="@+id/imageView"android:layout_width="0dp"android:layout_height="200dp"android:background="@color/colorPrimary"android:scaleType="fitCenter"app:antiAlias="true"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:source="angel.svga"/>
网络下载:
URL url = null;try {url = new URL(img);
} catch (MalformedURLException e) {e.printStackTrace();
}
parser.parse(url, new SVGAParser.ParseCompletion() { @Overridepublic void onComplete(SVGAVideoEntity mSVGAVideoEntity) {SVGADrawable drawable = new SVGADrawable(mSVGAVideoEntity);mSVGAImageView.setImageDrawable(drawable);mSVGAImageView.startAnimation();} @Overridepublic void onError() {Toast.makeText(PreviewActivity.this, "parse error!", Toast.LENGTH_SHORT).show();}
});
动态图像或文本
parser.parse(img, new SVGAParser.ParseCompletion() { @Overridepublic void onComplete(SVGAVideoEntity mSVGAVideoEntity) {SVGADynamicEntity dynamicItem = new SVGADynamicEntity();SVGADrawable drawable = new SVGADrawable(mSVGAVideoEntity, dynamicItem);TextPaint textPaint = new TextPaint();textPaint.setTextSize(30);textPaint.setFakeBoldText(true);textPaint.setARGB(0xff, 0x00, 0x00, 0x00);textPaint.setShadowLayer((float) 1.0, (float) 0.0, (float) 1.0, Color.BLACK); // 各种配置//解压.svga可以看到所有的图片,填入图片名称dynamicItem.setDynamicText("TEXT!", textPaint, "yu11");mSVGAImageView.setImageDrawable(drawable);mSVGAImageView.startAnimation();} @Overridepublic void onError() {Toast.makeText(PreviewActivity.this, "parse error!", Toast.LENGTH_SHORT).show();}
});
原理:矢量动画的原理
导出动画时间轴,包含位图,关键帧,矢量路径,样式
根据关键帧进行动画还原,播放器负责插值计算和绘制
播放器过于复杂,需要处理高阶插值计算,如二阶方程,贝塞尔曲线
把所有的动画帧在导出时计算完成,播放器只负责绘制
播放器实现简单,同时对不同的动画格式支持好,只要提供对应的转换器即可
SVGA采用了第二种方法,这样可以减少播放器的工作量,同时框架的通用性得到了提高,只要提供不同动画格式的转换工具都可以使用这个框架进行播放
动画层次结构
绘制过程
绘制位图
private fun drawImage(sprite: SVGADrawerSprite, scaleType: ImageView.ScaleType) {val canvas = this.canvas ?: return(dynamicItem.dynamicImage[sprite.imageKey] ?: videoItem.images[sprite.imageKey])?.let {sharedPaint.reset()sharedContentTransform.reset()sharedPaint.isAntiAlias = videoItem.antiAliassharedPaint.alpha = (sprite.frameEntity.alpha * 255).toInt()performScaleType(scaleType)sharedContentTransform.preConcat(sprite.frameEntity.transform)sharedContentTransform.preScale((sprite.frameEntity.layout.width / it.width).toFloat(),(sprite.frameEntity.layout.width / it.width).toFloat()) if (sprite.frameEntity.maskPath != null) {val maskPath = sprite.frameEntity.maskPath ?: return@letcanvas.save()sharedPath.reset()maskPath.buildPath(sharedPath)sharedPath.transform(sharedContentTransform)canvas.clipPath(sharedPath)canvas.drawBitmap(it, sharedContentTransform, sharedPaint)canvas.restore()} else {canvas.drawBitmap(it, sharedContentTransform, sharedPaint)}drawText(it, sprite)}
}
绘制矢量图形
private fun drawShape(sprite: SVGADrawerSprite, scaleType: ImageView.ScaleType) {val canvas = this.canvas ?: returnsharedContentTransform.reset()performScaleType(scaleType)sharedContentTransform.preConcat(sprite.frameEntity.transform)sprite.frameEntity.shapes.forEach { shape ->sharedPath.reset()shape.buildPath()shape.shapePath?.let {sharedPath.addPath(it)} if (!sharedPath.isEmpty) {val thisTransform = Matrix()shape.transform?.let {thisTransform.postConcat(it)}thisTransform.postConcat(sharedContentTransform)sharedPath.transform(thisTransform)shape.styles?.fill?.let { if (it != 0x00000000) {sharedPaint.reset()sharedPaint.color = itsharedPaint.alpha = (sprite.frameEntity.alpha * 255).toInt()sharedPaint.isAntiAlias = trueif (sprite.frameEntity.maskPath !== null) canvas.save()sprite.frameEntity.maskPath?.let { maskPath ->sharedPath2.reset()maskPath.buildPath(sharedPath2)sharedPath2.transform(this.sharedContentTransform)canvas.clipPath(sharedPath2)}canvas.drawPath(sharedPath, sharedPaint) if (sprite.frameEntity.maskPath !== null) canvas.restore()}}shape.styles?.strokeWidth?.let { if (it > 0) {sharedPaint.reset()sharedPaint.alpha = (sprite.frameEntity.alpha * 255).toInt()resetShapeStrokePaint(shape) if (sprite.frameEntity.maskPath !== null) canvas.save()sprite.frameEntity.maskPath?.let { maskPath ->sharedPath2.reset()maskPath.buildPath(sharedPath2)sharedPath2.transform(this.sharedContentTransform)canvas.clipPath(sharedPath2)}canvas.drawPath(sharedPath, sharedPaint) if (sprite.frameEntity.maskPath !== null) canvas.restore()}}}}
}
缺点
对AE动画支持有限的效果和类型
TEXT不支持
AE插件不支持,粒子效果
复杂动画转换较慢
不适合交互的场景
性能
以全屏的angel.svga为例,通过Android Profiler查看cpu和内存信息
动画文件大小: 299k
CPU:解析50%,播放5%左右
内存:dump内存,总内存在9M左右,整个库的对象大小,实际包含其他对象,内存要大于9M
所以性能上面应该说还有优化的空间,解析的过程会造成卡顿
YY-SVGA动画框架相关推荐
- react加载svga动画
react加载svga动画 svga动画优点: 高效,终端只需要继承这套方案框架,把动画实现交给动画设计师即可. 高性能,在实现酷炫动画的基础上,播放性能表现优于Gif和WebP. 动画文件小,同样的 ...
- Qt动画框架The Animation Framework
一个网友翻译的,没有翻译完,我把剩下的那部分翻译出来贴出来 动画框架是Kinetic(运动)项目的一部分,它的目标是提供一中简单的方法创建动画的和流畅的GUI.借助Qt动画属性,可以提供非常自由的动画 ...
- Qt动画框架Animation Framework
Qt动画框架 Qt动画框架 动画架构 动画框架中的类 动画Qt属性 动画和图形视图框架 缓和曲线 将动画放在一起 Qt动画框架 动画框架旨在为创建动画和平滑的GUI提供一种简便的方法.通过对Qt属性进 ...
- Android 动画框架详解,第 1 部分
2019独角兽企业重金招聘Python工程师标准>>> Android 平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android 的动画框 ...
- 构造函数 + 原型链继承 + 临摹面向对象模式的canvas动画框架
感谢谢帅shawn分享的canvas动画框架,我再来分一次 //动画框架 http://neekey.net/blog/2011/05/11/canvas-%E7%AE%80%E5%8D%95%E5% ...
- 10个顶级的CSS和Javascript动画框架推荐
在网站中嵌入动画已成为近年来的一个设计趋势,许多公司都已开始转向并拥抱HTML5.CSS3和JavaScript这个技术"三人组".尽管这些技术还不能制作一些非常复杂的动画(像fl ...
- android动画框架,GitHub - azhengyongqin/CustomAnimationFramework: Android自定义曲线路径动画框架...
Android自定义曲线路径动画框架 最近在一个项目中需要一个像QQ打开个人爱好那样的动画效果如下图: 可以看出每个小球都是以顺时针旋转出来的,说明像这样的曲线动画用Android中自带的平移动画是很 ...
- CSS3动画框架 Animate.css
CSS3的动画应用越来越多了,Animate.css一个从名字上就知道干什么的动画框架. github上的访问地址:http://daneden.github.io/animate.css/ 使用方法 ...
- 顶级的CSS和Javascript动画框架
CodePen 是一个在线的前端代码编辑和展示网站,能够编写代码并即时预览效果.可以欣赏到世界各地的优秀开发者在网页中实现的各种令人惊奇的效果 1. jQuery Transit 该jQuery插件扩 ...
最新文章
- MyBatis(二)——多对一、一对多
- 沉淀2017,勇闯2018
- PAT1050 螺旋矩阵 (25 分)【全部通过 关于段错误的原因 以及测试点7】
- java bitset_Java BitSet cardinality()方法与示例
- c语言实验报告熟悉vc,C语言实验报告源代码
- 编写一个程序,对一个整型数组的元素求和,结果使用全局变量sum存储,另外对数组元素中的奇数求和,结果使用局部变量sum存储,在主程序将两个结果输出。
- 想加入IT行业为何建议你学Python,不要错过时机哦
- cmd输入pip报错_安装虚拟环境+pip安装XXX包的常见操作与报错解决
- Perl中删除或替换字符串中特殊字符(如空格)的方法
- 计算器的二进制功能java_Java二进制文字– Java 7功能
- 手把手教你Windows环境下配置Git环境
- “一夜成名”需要多久?他花了20年!
- 明明是OS问题,却认为是CPU,这个教训是什么
- sql语句分析是否走索引_Mysql中SQL语句不使用索引的情况
- 诺基亚10.22变革影响的分析(转)
- 开机启动时间计算机,Windows系统更改开机启动时间三种方法
- 不知何时开学,接下来计划(罗勇军的浅谈程序设计竞赛的算法知识)
- 我校全力开展抗洪救灾工作
- 【干货】人工智能专业重要词汇表(红宝书)
- 海南大学838信号与系统专业课的感悟
热门文章
- jQuery使用ajaxSubmit()提交表单以及AjaxSubmit的一些用法
- YUV数据格式与YUV_420_888
- 字典特征提取,文本特征提取。
- matlab模块封装端口位置,simulink模块端口位置
- find、文件后缀及linux与Windows互传
- Gmail附件大小及格式限制全面解析
- js中字符串截取函数及其方法
- 数据库与MPP数仓(十五):MPP的架构与选型
- Scaled-YOLOv4: Scaling Cross Stage Partial Network 论文翻译
- PCA(主成分分析)