前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于 apng-js 的前端动画实现方案

基于 apng-js 的前端动画实现方案

作者头像
牛老师讲GIS
发布于 2025-05-31 07:34:50
发布于 2025-05-31 07:34:50
6800
代码可运行
举报
运行总次数:0
代码可运行

概述

本文分享基于apng-js实现前端动画。

一、前端动画实现方案对比

主流动画实现方式对比:

  • CSS+DOM:适合简单过渡动画,无法精细控制帧动画
  • SVG:矢量特性适合图形类动画,但复杂动画性能较差
  • GIF:256色限制,存在杂边问题,画质较差
  • WebP:高压缩率但兼容性受限,透明度支持有限
  • APNG:支持24位色+8位透明度,画质无损且兼容性良好
  • Canvas:适合复杂动画,需配合JS实现播放控制

apng介绍

1.简介

APNG(Animated Portable Network Graphics)是一种基于PNG格式的位图动画扩展,旨在提供比传统GIF更好的图像质量和透明度支持。最早由Mozilla公司在2004年提出,目的是为了替代老旧的GIF格式。尽管PNG组织在2007年否决了APNG成为官方标准的提案,但Mozilla社区继续支持APNG的发展。随着时间的推移,越来越多的软件和浏览器开始支持APNG格式。

2. 技术原理

APNG 通过扩展 PNG 格式实现动画,包含三类关键数据块:

  • acTL:动画控制块(帧数/循环次数)
  • fcTL:帧控制块(尺寸/延迟时间)
  • fdAT:帧数据块(差异帧优化存储)
2.2 核心优势

特性

APNG

GIF

WebP

色彩深度

24位真彩色

8位索引色

24位真彩色

透明度

8位Alpha

1位布尔

8位Alpha

压缩率

兼容性

主流浏览器

全支持

部分浏览器

实现效果

动画.gif
动画.gif

实现代码

1. 安装依赖
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm i apng-js -S
2. 代码实现

将其分装成了一个组件,组件代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>

页面中调用组件的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 一、前端动画实现方案对比
  • apng介绍
    • 1.简介
    • 2. 技术原理
    • 2.2 核心优势
  • 实现效果
  • 实现代码
    • 1. 安装依赖
    • 2. 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档