本文分享基于apng-js
实现前端动画。
主流动画实现方式对比:
APNG(Animated Portable Network Graphics)是一种基于PNG格式的位图动画扩展,旨在提供比传统GIF更好的图像质量和透明度支持。最早由Mozilla公司在2004年提出,目的是为了替代老旧的GIF格式。尽管PNG组织在2007年否决了APNG成为官方标准的提案,但Mozilla社区继续支持APNG的发展。随着时间的推移,越来越多的软件和浏览器开始支持APNG格式。
APNG 通过扩展 PNG 格式实现动画,包含三类关键数据块:
acTL
:动画控制块(帧数/循环次数)fcTL
:帧控制块(尺寸/延迟时间)fdAT
:帧数据块(差异帧优化存储)特性 | APNG | GIF | WebP |
---|---|---|---|
色彩深度 | 24位真彩色 | 8位索引色 | 24位真彩色 |
透明度 | 8位Alpha | 1位布尔 | 8位Alpha |
压缩率 | 中 | 低 | 高 |
兼容性 | 主流浏览器 | 全支持 | 部分浏览器 |
npm i apng-js -S
将其分装成了一个组件,组件代码如下:
<template>
<canvas class="apng" ref="canvas"></canvas>
</template>
<script>
import parseAPNG from 'apng-js'
export default {
props: {
imgUrl: {
type: String,
required: true,
},
autoPlay: {
type: Boolean,
default: true,
},
playbackRate: {
type: Number,
default: 1,
},
playEnd: {
type: Function,
default: () => {},
},
},
data() {
return {
player: null,
}
},
mounted() {
this.initPlayer()
},
methods: {
initPlayer() {
const that = this
fetch(this.imgUrl)
.then(res => res.blob())
.then(blob => {
const reader = new FileReader()
reader.readAsArrayBuffer(blob)
reader.onload = () => {
const apng = parseAPNG(reader.result)
const canvas = that.$refs.canvas
canvas.width = apng.width
canvas.height = apng.height
const ctx = canvas.getContext('2d')
apng.getPlayer(ctx).then(_player => {
that.player = _player
that.player.playbackRate = that.playbackRate // 0-1
that.player.play()
that.player.on('end', that.playEnd)
this.$emit('inited', that.player)
})
}
})
},
},
}
</script>
<style scoped lang="scss">
.apng {
width: 100%;
height: auto;
}
</style>
页面中调用组件的代码如下:
<template>
<div class="container">
<el-button @click="togglePlay">{{ isPlay ? '暂停' : '播放' }}</el-button>
<div class="bg" @mouseover="play" @mouseout="stop">
<div class="text">Hello World</div>
<apng :imgUrl="'/imgs/support.png'" :playEnd="playEnd" @inited="playerInited"></apng>
</div>
</div>
</template>
<script>
import Apng from './components/apng.vue';
let player = null
export default {
components: { Apng },
data() {
return {
isPlay: false,
}
},
methods: {
playEnd() {
this.stop()
},
playerInited(_player) {
player = _player
},
togglePlay() {
this.isPlay ? this.stop() : this.play()
this.isPlay = !this.isPlay
},
play() {
player.play()
this.isPlay = true
},
stop() {
// player.pause()
this.isPlay = false
},
},
}
</script>
<style scoped lang="scss">
.container {
padding: 1rem;
}
.bg {
width: 20rem;
height: auto;
position: relative;
.text {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 1.2rem;
width: 100%;
height: 100%;
}
}
</style>
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有