记一次使用apng动画两种方式

2023-10-11 03:59

本文主要是介绍记一次使用apng动画两种方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. apng-canvas
  2. apng-js

1. 使用apng-canvas做apng动画

使用起来代码简单,容易理解;但是监听动画的过程。

APNG

APNG 全称是 Animated Portable Network Graphics , 是 PNG 格式的动画扩展。APNG 的第1帧为标准PNG图像,剩余的动画和帧速等数据放在PNG扩展数据块里。这里有点类似于视频的关键帧,关键帧有完整的图像信息,而两个关键帧之间只保留了变化的信息。
简单来说,APNG 支持全彩和透明,无杂边问题.

但并不是所有软件都支持APNG。

Android上有APNG View等,iOS上有APNGKit

而Web上,Firfox和Safari是支持APNG,Chrome是支持WebP的。

所以我们要在Web上使用APNG可以使用Canvas

Canvas & APNG

我们可以使用 apng-canvas库。

举例
APNG.ifNeeded().then(function() {var images = document.querySelectorAll(".apng-image");for (var i = 0; i < images.length; i++) APNG.animateImage(images[i]);
});

APNG这个对象是apng-canvas这个库提供的,ifNeeded()函数是用来判断浏览器是否支持APNG。

APNG.animateImage()是需要传入一个 Image Element,之后就交给Canvas去处理了。

2. 使用apng-js做apng动画

注:底部有作者 apng.vue的组件源码作参考

apng-js

apng-js 官方demo

使用方式
import parseAPNG from 'apng-js';const apng = parseAPNG(buffer);
if (apng instanceof Error) {// handle error
}
// work with apng object

parseAPNG的参数是一个ArrayBuffer类型,比起apng-canvas的使用要较为复杂一些。
在这里我就举一下我之前的做法:

我们需要的是加载本地和远端的apng图片来进行动画操作.

因为最终参数需要一个ArrayBuffer类型的,而我们只有一张图片的url,因此需要进行转换。
经过测试得出转换步骤如下:

  1. 先去请求这张图片以返回类型设为blob类型
// 加载图片资源,得到blob类型的值
loaderURL(url) {function createXmlHttpRequest() {if (window.ActiveXObject) {return new ActiveXObject('Microsoft.XMLHTTP');} else if (window.XMLHttpRequest) {return new XMLHttpRequest();}}return new Promise((resolve) => {let xhr = createXmlHttpRequest();xhr.open("get", url, true);xhr.responseType = "blob";xhr.onload = function (res) {if (this.status == 200) {var blob = this.response;resolve(blob);}}xhr.send();})
}
  1. 将blob转换成ArrayBuffer类型
// 将blob转换成buffer
blobToArrayBuffer(blob) {return new Promise((resolve) => {// Blob 转 ArrayBufferlet reader = new FileReader();reader.readAsArrayBuffer(blob);reader.onload = function() {console.log(reader.result)resolve(reader.result)}})
}
  1. 可以使用apng-js的parseAPNG得到apng对象,通过该对象可以获得动画播放器player
var apng = parseAPNG(buffer);
apng.getPlayer(canvas.getContent('2d')).then(player => {// 调用播放动画player.play();
})

player对象中有

  • play – playback started;
  • frame – frame played (frame number passed as event parameter);
  • pause – playback paused;
  • stop – playback stopped;
  • end – playback ended (for APNG with finite count of plays).
    通过官方文档可看出,我们可以监听整个动画的事件。
    官方demo中监听代码片段
    img

作者apng.vue源码

<template lang="pug">.apng-div(ref="apng-div" v-if="src")canvas(ref="apng-canvas")
</template><script>
// require('./../libs/apng-canvas.min.js')
import commonMixin from '@/mixins/commonMixin'
import parseAPNG from 'apng-js'export default {mixins: [commonMixin],data() {return {}},props: {width: {type: String | Number,required: true},height: {type: String | Number,required: true},src: {type: String,required: true}},mounted() {let canvas = this.$refs['apng-canvas'];this.loaderURL(this.src).then(blob => {console.log(blob)this.blobToArrayBuffer(blob).then(arrayBuffer => {let apng = parseAPNG(arrayBuffer);canvas.width = apng.width;canvas.height = apng.height;let scale = this.width * this.remVal / apng.widthcanvas.style = 'zoom: ' + scale;apng.getPlayer(canvas.getContext('2d')).then(player => {player.play();})})})},methods: {calc(val) {return this.remVal * val;},blobToArrayBuffer(blob) {return new Promise((resolve) => {// Blob 转 ArrayBufferlet reader = new FileReader();reader.readAsArrayBuffer(blob);reader.onload = function() {console.log(reader.result)resolve(reader.result)}})},loaderURL(url) {function createXmlHttpRequest() {if (window.ActiveXObject) {return new ActiveXObject('Microsoft.XMLHTTP');} else if (window.XMLHttpRequest) {return new XMLHttpRequest();}}return new Promise((resolve) => {let xhr = createXmlHttpRequest();xhr.open("get", url, true);xhr.responseType = "blob";xhr.onload = function (res) {if (this.status == 200) {var blob = this.response;resolve(blob);}}xhr.send();})}}
}
</script><style lang="less" scoped></style>

这篇关于记一次使用apng动画两种方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/185368

相关文章

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

SpringValidation数据校验之约束注解与分组校验方式

《SpringValidation数据校验之约束注解与分组校验方式》本文将深入探讨SpringValidation的核心功能,帮助开发者掌握约束注解的使用技巧和分组校验的高级应用,从而构建更加健壮和可... 目录引言一、Spring Validation基础架构1.1 jsR-380标准与Spring整合1

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3

Python Transformer 库安装配置及使用方法

《PythonTransformer库安装配置及使用方法》HuggingFaceTransformers是自然语言处理(NLP)领域最流行的开源库之一,支持基于Transformer架构的预训练模... 目录python 中的 Transformer 库及使用方法一、库的概述二、安装与配置三、基础使用:Pi

关于pandas的read_csv方法使用解读

《关于pandas的read_csv方法使用解读》:本文主要介绍关于pandas的read_csv方法使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录pandas的read_csv方法解读read_csv中的参数基本参数通用解析参数空值处理相关参数时间处理相关

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例