Last active
May 13, 2024 17:28
-
-
Save Danetag/86495bb11ed2faba9fe0f5ba60e13d57 to your computer and use it in GitHub Desktop.
Simple class to play a PNG sequence into a canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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