Skip to content

Instantly share code, notes, and snippets.

@Danetag
Last active May 13, 2024 17:28
Show Gist options
  • Save Danetag/86495bb11ed2faba9fe0f5ba60e13d57 to your computer and use it in GitHub Desktop.
Save Danetag/86495bb11ed2faba9fe0f5ba60e13d57 to your computer and use it in GitHub Desktop.
Simple class to play a PNG sequence into a canvas
// Here is a simple class that contains loading methods.
// Nothing fancy, but the idea is simply to return a Promise
import { loadImg } from './load';
class Sprite {
/*
@Example
import Sprite from './Sprite';
import dataFrame from 'path/to/data-frame.json'
const sprite = new Sprite();
const container = document.getElementById('container');
sprite.init({
src: 'path/to/texture.png',
dataFrames,
container
});
// Later
sprite.play();
*/
/* JSON generated by Texture Packer */
/* https://www.codeandweb.com/texturepacker */
dataFrames = null;
/* SRC of the sprite */
src = null;
/* Container for the Canvas */
container = null;
canvas = null;
frameHeight = 0;
frameHeight = 0;
dataArray = [];
FPS = 60;
isPlaying = false;
currentIndex = 0;
currentDate = new Date();
raf = null;
init(props) {
this.dataFrames = props.dataFrames;
this.src = props.src;
this.container = props.container || document.createElement('div');
this.frameHeight = this.config.frames[0].frame.h;
this.frameWidth = this.config.frames[0].frame.w;
this.loadImage();
}
loadImage() {
loadImg(this.src).then((img) => {
// has disposed before the end of the loading
if (!this.dataFrames) return;
this.createCanvas(img);
this.bindEvents();
})
}
createCanvas(img) {
this.canvas = document.createElement('canvas');
this.canvas.width = this.frameWidth;
this.canvas.height = this.frameHeight;
this.container.appendChild(this.canvas);
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
var canvasPaste = canvas.cloneNode(false);
canvasPaste.width = this.frameWidth;
canvasPaste.height = this.frameHeight;
let canvasPasteTemp, imgData;
for (let i = 0; i < this.dataFrames.frames.length; i++) {
const frame = this.dataFrames.frames[i];
// Store the image data of each tile in the array.
canvasPasteTemp = canvasPaste.cloneNode(false);
imgData = ctx.getImageData(frame.frame.x, frame.frame.y, frame.frame.w, frame.frame.h);
this.dataArray.push(imgData);
}
}
bindEvents() {
this.onUpdate();
}
unbindEvents() {
if (this.raf) window.cancelAnimationFrame(this.raf);
}
onUpdate = () => {
if (this.isPlaying && this.canvas) {
const date = new Date();
const minDelta = (1 / this.FPS) * 1000;
if (date - this.currentDate >= minDelta) {
this.currentDate = date;
const imgData = this.dataArray[this.currentIndex];
this.canvas.getContext('2d').putImageData(imgData, 0, 0);
this.currentIndex++;
if (this.currentIndex >= this.dataArray.length) {
this.isPlaying = false;
this.currentIndex = 0;
}
}
}
this.raf = window.requestAnimationFrame(this.onUpdate);
}
play() {
this.isPlaying = true;
}
dispose() {
this.dataFrames = null;
this.src = null;
this.container = null;
this.isPlaying = false;
this.currentIndex = 0;
this.canvas = null;
this.dataArray.length = 0;
this.dataArray = [];
this.unbindEvents();
}
}
export default Sprite;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment