Last active
February 24, 2022 06:57
-
-
Save mauriciomassaia/2343d4e45d046077e8f902e029167cdf to your computer and use it in GitHub Desktop.
Spritesheet Animation class with Typescript and TexturePacker
This file contains hidden or 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
// Generic JSON data spritesheet | |
export interface Rect { | |
x: number | |
y: number | |
w: number | |
h: number | |
} | |
export interface Frame { | |
filename: string | |
frame: Rect | |
rotated: boolean | |
trimmed: boolean | |
spriteSourceSize: Rect | |
sourceSize: Size | |
} | |
export interface Size { | |
w: number | |
h: number | |
} | |
export interface Meta { | |
app: string | |
version: string | |
image: string | |
format: string | |
size: Size | |
scale: string | |
smartupdate: string | |
} | |
export interface SpritesheetData { | |
frames: Frame[] | |
meta: Meta | |
} |
This file contains hidden or 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
import { SpritesheetData } from './interfaces' | |
// generate a spritesheet (png + json) using TexturePacker data file format JSON (Array) | |
export class SpritesheetAnimation { | |
canvas: HTMLCanvasElement | |
protected image = new Image() | |
protected ctx: CanvasRenderingContext2D | |
private playing = false | |
private frameIndex = 10 | |
protected data: SpritesheetData | |
constructor () { | |
this.update = this.update.bind(this) | |
this.image.src = './spritesheets/animation.png' | |
this.canvas = document.createElement('canvas') | |
this.canvas.width = 1000 | |
this.canvas.height = 200 | |
const ctx = this.canvas.getContext('2d') | |
if (ctx === null) { | |
throw new Error('Animation - Invalid 2d context') | |
} | |
this.ctx = ctx | |
this.loadData() | |
.catch(console.error) | |
} | |
private async loadData (): Promise<void> { | |
const response = await fetch('./spritesheets/animation.json') | |
this.data = await response.json() as SpritesheetData | |
this.open() | |
} | |
open (): void { | |
// add fade in | |
if (this.playing) return | |
this.playing = true | |
this.update() | |
} | |
close (): void { | |
// add fade out | |
if (!this.playing) return | |
this.playing = false | |
} | |
private drawFrame (): void { | |
const index = Math.floor(this.frameIndex) | |
const { frame, spriteSourceSize } = this.data.frames[index] | |
this.ctx.clearRect(0, 0, 1000, 200) | |
this.ctx.fillStyle = 'rgba(0, 0, 0,0)' | |
this.ctx.drawImage( | |
this.image, | |
frame.x, | |
frame.y, | |
frame.w, | |
frame.h, | |
spriteSourceSize.x, | |
spriteSourceSize.y, | |
spriteSourceSize.w, | |
spriteSourceSize.h | |
) | |
} | |
private update (): void { | |
this.frameIndex += 1 | |
this.frameIndex %= this.data.frames.length | |
this.drawFrame() | |
if (this.playing) { | |
window.requestAnimationFrame(this.update) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment