SVGA动画介绍
SVGA 是一种跨平台的开源动画格式,同时兼容 iOS / Android / Web。SVGA 除了使用简单,性能卓越,同时让动画开发分工明确,各自专注各自的领域,大大减少动画交互的沟通成本,提升开发效率。动画设计师专注动画设计,通过工具输出 svga 动画文件,提供给开发工程师在集成 svga player 之后直接使用。动画开发从未如此简单!
SVGA 除了使用简单,性能卓越,同时让动画开发分工明确,各自专注各自的领域,大大减少动画交互的沟通成本,提升开发效率。
动画设计师专注动画设计,通过工具输出 svga 动画文件,提供给开发工程师在集成 SVGAPlayer 之后直接使用。
SVGA在动画播放前,会一次性地上传所有图片信息到GPU,在播放的过程中,这些图片信息会被重复使用。CPU与GPU 交换的次数大大减少,图片信息数目也在可控范围。内存、CPU、GPU 占用能达到最优状态,一个10几MB大的序列帧效果,用svga格式可以只要几百K甚至几十KSVGA 动画的性能可以得到极大的保障。SVGA官方也给出几点SVGA动画的优势:
使用:直播礼物使用了SVGA动画、页面上banner里动画
使用 CocoaPods 集成源码,将以下依赖:
pod 'SVGAPlayer'
添加至 Podfile 文件。
使用代码或 IB 添加 SVGAPlayer 至 View 中,具体方法参见:
https://github.com/svga/SVGAPlayer-iOS
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
compile 'com.github.svga:SVGAPlayer-Android:2.0.0'
根据需要修改版本号,要获取最新的版本请点入:
https://jitpack.io/#svga/SVGAPlayer-Android
使用代码或 XML 添加 SVGAImageView 至 View 中,具体方法参见:
https://github.com/svga/SVGAPlayer-Android
直接在:https://github.com/svga/SVGAPlayer-Web下载 build/svga.min.js,
并添加至目标页面。
或使用 npm install svgaplayerweb —save
添加依赖,
并在需要使用的 js 中添加 require('svgaplayerweb')
添加 Div 容器,并加载动画,
具体方法参见:https://github.com/svga/SVGAPlayer-Web。
我们还提供了体积更小的轻量版:SVGA.Lite。
在线播放器:https://svga.io/svga-preview.html
转换svga为png序列或svg动画:https://www.nangonghan.com/svga/
var player = new SVGA.Player('#demoCanvas'); var parser = new SVGA.Parser(); parser.load('img/bb.svga', function(videoItem) { player.setVideoItem(videoItem); player.startAnimation(); player.onFrame(function (i) {}) });
React组件封装:
import React from "react"; import SVGA, { Player, Parser, VideoEntity } from "svgaplayerweb"; interface Props { delay?: number; onFrame?: () => void; getInstance?: (e: any) => void; width: number; height: number; url: string; onl oad?: () => void; } interface State {} class SvgaPlayer extends React.Component<Props, State> { private player: Player; private parser: Parser; private svgaRef: React.RefObject<HTMLDivElement>; static defaultProps: Partial<Props>; constructor(props: Props) { super(props); this.player = null; this.parser = null; this.svgaRef = React.createRef(); this.init = this.init.bind(this); this.onAnimationLoaded = this.onAnimationLoaded.bind(this); } componentDidMount() { this.init(this.props.url); } componentWillReceiveProps(nextProps: Props) { if (nextProps.url !== this.props.url) { this.init(nextProps.url); } } componentWillUnmount() { if (this.parser) { this.parser = null; this.player.stopAnimation(); } } render() { const { width, height } = this.props; return ( <div style={{ width, height }} className="svga-wraper" > <div ref={this.svgaRef} className="svga-con"> {/* <canvas width="573" height="471" style="background-color: transparent;"></canvas> */} </div> </div> ); } init(svgaUrl: string) { this.player = new SVGA.Player(this.svgaRef.current); // this.player.loops = 0; // this.player.clearsAfterStop = false; this.parser = new SVGA.Parser(); this.parser.load(svgaUrl, this.onAnimationLoaded); this.player.onFrame(this.props.onFrame); } onAnimationLoaded = (videoItem: VideoEntity) => { this.player.setVideoItem(videoItem); const me = this; setTimeout(function () { me.props.onLoad(); me.player.startAnimation(); }, this.props.delay); }; } SvgaPlayer.defaultProps = { height: 0, width: 0, delay: 0, url: "", //getInstance: function (e) { // return e; //}, onl oad: () => {}, onFrame: () => {}, }; export default SvgaPlayer;
样式:
.svga-wraper { padding: 0; position: relative; margin: auto; } .svga-con { position: absolute; top: 0; left: 0; bottom: 0; right: 0; }
最近遇到一个bug,封装了一个播放svga的组件,之前使用正常,最近使用发现svga动画不播放了:
如上第一张图片:svga根本不播放,第二张svga播放,但是当点击下面的按钮弹出弹窗后如第三章图片,此后svga动画就会停止不在播放。
原因是项目中为了兼容处理了requestAnimationFrame这个API:
window.requestAnimationFrame = () => { return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (e) { window.setTimeout(e, 1e3 / 60); } ); };
svgaplayerweb库源码中使用了requestAnimationFrame这个api绘制动画,new SVGA.Player(container)就是在contanner中创建canvas标签插入,之后根据父元素或svga动画本身尺寸以及页面的dpr等设置ctx.setTransform以及canvas画布的width和height,之后根据svga中图片序列帧图片遍历处理这些图片使用canvas一帧帧绘制出来,之后使用第三方动画库等绘制出动画。