使用apng-js,apng动画连续播放,取代gif

通过使用apng-js可以控制播放图片,或者点击按钮达到播放多次动画的效果,在动画播放结束页可以执行一些操作。

废话不多说,直接上代码

1、npm install apng-js

2、新建apng.js文件,里面做了一些通用封装

javascript 复制代码
import parseAPNG from 'apng-js';
/**
 * 获取图片ArrayBuffer
 * @param url 图片地址
 * @returns {Promise<ArrayBuffer>}
 */
export function getImgBuffer(url) {
  return new Promise(async (resolve) => {
   const blob = await fetch(url).then((res) => res.blob());
   const reader = new FileReader();
   reader.readAsArrayBuffer(blob);
   reader.onload = () => {
    resolve(reader.result);
   };
  });
}

/**
 * 获取apng图片的控制实例
 * @param url 图片地址
 * @param options apng配置参数
 * @returns {Promise<APNG>}
 */
export async function getApng(url, options = {}) {
  const imgBuffer = await getImgBuffer(url);
  const apng = parseAPNG(imgBuffer);
  Object.keys(options).forEach((key) => {
   apng[key] = options[key];
  });
  return apng;
}


/**
 * 播放anpng
 * @param apngFile apng图片
 * @param canvasClass className
 * @param canvasWidth canvasWidth
 * @param canvasWidth canvasWidth
 * @param appendParent 需要追加到 父组件id
 */
export async function playApng(apngFile, canvasClass,appendParent, canvasWidth=375,canvasHeight=375,canvasStyles) {
  let apngObj = null
  let apngPlayer = null
  await getApng(apngFile).then(res => {
    apngObj = res
  })
  if (!apngObj) {
    return
  }
  const container = document.getElementById(appendParent); // 放到 某个 模块下
  let canvas = document.createElement('canvas');// 每次新建canvas,可以达到类似于敲木鱼多次播放的效果(播放结束后该canvas自动隐藏)
  canvas.width = canvasWidth;
  canvas.height = canvasHeight;
  canvas.setAttribute('class', canvasClass);
  Object.assign(canvas.style, canvasStyles);
  container.appendChild(canvas);
  // willReadFrequently: true可以提升 canvas 渲染速度
  apngObj.getPlayer(canvas.getContext('2d', { willReadFrequently: true })).then(res => {
    apngPlayer = res
    // 开始播放apng动画
    apngPlayer.play()
    // 添加动画播放结束监听事件
    apngPlayer.on('end', () => {
      // 动画播放结束,当前的canvas隐藏(或者做其他动作)
      canvas.style.display = 'none';
    })
  })
}
export default {
  getImgBuffer,
  getApng,
  playApng
};

3、对应页面引入上面定义好的apng.js,具体路径根据自己项目定

javascript 复制代码
import Apng from '@/utils/apng.js'
import pngSrc from '@/static/makeCake/xxx.png'

4、传入具体的apng图片(本地地址)、canvas命名和apng要插入的某个父容器id

javascript 复制代码
const canvasPlay = () => {
  let apngWidth = 300 //宽和高是必须要的
  let apngHeight = 300
  let apngFile = pngSrc
// canvasStyle 按需设置,看自己需要放置的位置
  let canvasStyle = {
    position: 'absolute',
    bottom: '0',
    zIndex: '12',
    left: '50%',
    transform: 'translateX(-50%)'
  }
  Apng.playApng(pngSrc, 'canvasName', 'canvasParent', apngWidth, apngHeight, canvasStyle)
}

canvasPlay () // 执行
相关推荐
EasyNTS2 分钟前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
Theodore_10222 分钟前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
活宝小娜1 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点2 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow2 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o2 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
----云烟----2 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024062 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic2 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā3 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue