前端动画展示方案

前端动画展示方案

在开发过程中我们通常需要一些动画特效使页面变得更加精致,通常我们会使用cssanimationsvg等来实现这些效果,但对于一些复杂的效果就不适合了。我们业务使用的uniapp,所以需要进行跨端,为了解决这些问题我们可以使用以下方案。

GIF.gif

一:Gif/WebP

好处在于作为图片使用即可,缺点是体积占用大、播放资源占用高更是因为内容不可动态化

二:SVGA(推荐)

在具体中会产生一个canvas,所以在其中可以进行它的播放,插入文字等操作。

2.1 下载

官网:svga.io/

npm:www.npmjs.com/package/svg…

小程序解决方案:github.com/yyued/SVGAP…

npm i svgaplayerweb
 

2.2 使用

我们需要兼容H5小程序,以下会存在兼容性写法

开启一个资源服务器并将svga文件放在服务器中:

cd resource
serve . --cros
 

业务代码:

<template>
<!-- #ifdef H5 -->
<div ref="demoCanvas" id="demoCanvas"></div>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<canvas type="2d" style="width: 300px; height:300px; background-color: black" 			       id="myCanvas"></canvas>
<!-- #endif -->
</template>
<script>
// #ifdef H5
import SVGA from 'svgaplayerweb'
// #endif
// #ifdef MP-WEIXIN
import SVGA from '../../../static/svga.min.js'
const parser = new SVGA.Parser() // 放在这里是因为小程序,如果没有事先 new parser 会报requestAnimationFrame 错误
// #endif
export default {
onLoad() {
// #ifdef H5
var player = new SVGA.Player('#demoCanvas')
var parser = new SVGA.Parser('#demoCanvas')
parser.load('http://localhost:5000/test.svga', function(videoItem) {
player.setVideoItem(videoItem);
player.startAnimation();
player.setText('123', 'img_12') // 可以根据 ued 提供的 key(图层) 替换相应的内容
})
// #endif
// #ifdef MP-WEIXIN
let player = new SVGA.Player("#myCanvas")
parser.load("http://localhost:5000/test.svga", function (videoItem) {
player.setVideoItem(videoItem);
player.startAnimation();
})
// #endif
}
}
</script>

2.3 查看svgakey

这里官网提供了一个在线的解析网址:svga.io/svga-previe…

拖拽svga后选择浏览素材,可以查看到能够设置的key

image-20210325104154955.png

2.4 转换为svg

同样,官网也提供了一个在线转换的地址:www.nangonghan.com/svga/

三:Lottie(推荐)

lottie是一个不太占体积,还原度高,对于初学者友好的库。设计师制作好动画,并且利用Bodymovin插件导出Json文件。而前端直接引用lottie-web库即可,它默认的渲染方式是svg,原理就是用JS操作Svg API。但是前端完全不需要关心动画的过程,Json文件里有每一帧动画的信息,而库会帮我们执行每一帧。

3.1 下载

官网:airbnb.design/lottie/

npm:www.npmjs.com/package/lot…

运行时 api 库:www.npmjs.com/package/lot…

小程序解决方案:developers.weixin.qq.com/miniprogram…

中文文档:www.yuque.com/lottie/docu…

npm i lottie-web // web 包
npm i lottie-api // 运行时 api 库
npm i lottie-miniprogram // 小程序包

3.2 使用

<template>
<!-- #ifdef H5 -->
<view id="lottie"></view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<canvas id="canvas" type="2d"></canvas>
<!-- #endif -->
</template>
<script>
// #ifdef H5
import lottie from 'lottie-web'
// #endif
// #ifdef MP-WEIXIN
import lottie from 'lottie-miniprogram'
// #endif
import lottieApi from 'lottie-api'
export default {
name: 'animateLottie',
props: {
options: {
type: Object,
default: () => ({
loop: false,
autoplay: true,
// animationData: require('@/static/data.json')
})
},
baseStyle: {
type: Object,
default: () => ({})
}
},
mounted () {
let anim
// #ifdef H5
anim = lottie.loadAnimation({
container: document.getElementById('lottie'),
renderer: 'svg',
...this.options
})
anim.addEventListener('DOMLoaded', () => {
const api = lottieApi.createAnimationApi(anim)
this.$emit('ready', {
anim,
api
})
})
// #endif
// #ifdef MP-WEIXIN
wx.createSelectorQuery().in(this).select('#canvas').node(res => {
const canvas = res.node
const context = canvas.getContext('2d')
canvas.width = 750
canvas.height = 1340
lottie.setup(canvas)
anim = lottie.loadAnimation({
rendererSettings: {
context
},
renderer: 'canvas',
...this.options
})
}).exec()
// #endif
}
}
</script>

调用:

animateReady ({anim, api}) {
const elements = api.getKeyPath("1.88") // 图层中的 nm,使用逗号逐级向下寻找
elements.getElements()[0].setText('1.88') // 设置文字
console.log(elements.getElements())
console.log(anim)
anim.addEventListener('enterFrame', (e) => {
console.log(e)
})
//if (anim.renderer.rendererType === 'canvas') {
// canvas 模式下的图片替换
//  anim.renderer.elements[0].elements[8].img.src = 「'https://gw.alipayobjects.com/mdn/rms_91e1e4/afts/img/A*2mfsTo-gbDgAAAAAAAAAAABkARQnAQ';
//} else {
// svg 模式下的图片替换,前两个参数为固定值
//  anim.renderer.elements[0].elements[8].innerElem.setAttributeNS(
//    'http://www.w3.org/1999/xlink',
//    'href', 
//    'https://gw.alipayobjects.com/mdn/rms_91e1e4/afts/img/A*2mfsTo-gbDgAAAAAAAAAAABkARQnAQ'
//  );
//}  
// anim.addEventListener('loopComplete', (e) => {
//   console.log(e)
// })
}

注意:

  • 在案例中,我们把ready事件暴露出来可以在其中很方便的绑定相关api和执行各种操作
  • web 端可以通过api设置相关文字、图片等,小程序是不可以的。甚至ued添加了文字都会直接报错,因为小程序包也仅仅是支持了播放图片相关,而动态文字等是不行的。

原创文章,作者:我心飞翔,如若转载,请注明出处:https://www.pipipi.net/12578.html

发表评论

登录后才能评论