In the recent requirements, the designer gave me two GIfs in APNG format, which required that the first GIF should be played once and the second one should be played in a loop, with natural connection and transition in the middle.
The GIF format of APNG was the first one I used, and my knowledge of it was limited to “moving PNG images”. Later, after several searches, finally is a number of APNG knowledge points to complete. There is so much information on APNG on the web that I won’t cover it here.
By default, browsers do not provide apis to manipulate APNG, so we cannot directly listen to apNG playback events, let alone control its playback actions. What to do? Thanks to NPM, a direct search for APNG turns up a library named APnG-JS that meets our needs.
Apng-js is written succinct, and its core principle is to parse apNG image data according to APNG specifications, and then draw them to canvas. It also provides apis that allow us to control the playback, pausing, and resetting of APNG images, and to listen for events that occur during the playback of these images, giving us complete control over THE APNG. Without further ado, let’s look at an example of how APNG-JS fulfils our requirements.
- Let’s do it in HTML first
<canvas>
The element is ready, and the apNG-JS library is introduced to initialize the canvas size and image resources.
<canvas id="canvas"></canvas>
Copy the code
// js file
import parseAPNG from "https://cdn.skypack.dev/[email protected]";
const img1Src = 'https://official-account-web-1251316161.cos.ap-guangzhou.myqcloud.com/mqq-static/open-platform-animate-1-new.png'
const img2Src = 'https://official-account-web-1251316161.cos.ap-guangzhou.myqcloud.com/mqq-static/open-platform-animate-2-new.png'
const canvas = document.querySelector('#canvas')
canvas.width = 640;
canvas.height = 540;
canvas.style = Zoom: 0.75 ';
const ctx = canvas.getContext('2d');
Copy the code
- Since APNG-JS only accepts
ArrayBuffer
So we need to write our own function to convert apNG to ArrayBuffer.
// js file
// Get the image and convert it to an ArrayBuffer
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);
};
});
}
Copy the code
- Once you have the APNG image resources in ArrayBuffer format, you can use apNG-JS to parse and use them. So here I’ve created a name called
createApngPlayer()
Public function, output apng-js player instance, convenient for our subsequent use.
async function createApngPlayer(url, ctx, options = {}) {
const imgBuffer = await getImgBuffer(url);
const apng = parseAPNG(imgBuffer);
Object.keys(options).forEach(key= > {
apng[key] = options[key];
});
const player = await apng.getPlayer(ctx);
return player;
}
Copy the code
- Once you have a player instance, you can use it to control apNG playback.
; (async() = > {const player1 = await createApngPlayer(img1Src, ctx, { numPlays: 1 }); // Set numPlays in Figure 1 to 1 so that it plays only once
const player2 = await createApngPlayer(img2Src, ctx);
player1.play(); // Figure 1
player1.on('end'.() = > { // Listen for figure 1 and start figure 2 as soon as it finishes playingplayer2.play(); }); }) ()Copy the code
Codepen. IO /jrainlau/ PE…
And you’re done!