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里动画
使用:
iOS
- 使用 CocoaPods 集成源码,将以下依赖:
pod 'SVGAPlayer'
- 添加至 Podfile 文件。
- 使用代码或 IB 添加 SVGAPlayer 至 View 中,具体方法参见:
https://github.com/svga/SVGAPlayer-iOS
Android
- 使用 Gradle 集成源码,添加 JitPack.io 到 root build.gradle 中
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
Web
- 直接在: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/
web案例:
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;
onLoad?: () => 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;
//},
onLoad: () => {},
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一帧帧绘制出来,之后使用第三方动画库等绘制出动画。