export default class SpriteSheet { constructor(url, tilew, tileh, scale = 1) { this.url = url; this.tilew = tilew; this.tileh = tileh; this.scale = scale; this.definitions = {}; this.waiting = []; this.ready = false; this.img = new Image(); this.img.src = url; this.img.onload = () => { this.ready = true; this.waiting.forEach(f => f()); }; this.img.onerror = err => { console.error("Failed to load "+url+"."); }; } whenReady(fn) { if (this.ready) return fn(); this.waiting.push(fn); return this; } define(name, x, y, w = this.tilew, h = this.tileh) { this.definitions[name] = null; this.whenReady(() => { let can = document.createElement("canvas"); can.width = w * this.scale; can.height = h * this.scale; let ctx = can.getContext("2d"); ctx.mozImageSmoothingEnabled = false; ctx.webkitImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false; ctx.drawImage( this.img, x, y, w, h, 0, 0, w * this.scale, h * this.scale); this.definitions[name] = can; }); return this; } defineTile(name, tx, ty) { return this.define(name, tx * this.tilew, ty * this.tileh); } draw(ctx, name, x, y, sx = 1, sy = 1) { let def = this.definitions[name]; if (def === null) return; if (def === undefined) throw new Error("Undefined sprite: "+name); ctx.drawImage( def, x, y, def.width * sx, def.height * sy); return this; } drawTile(ctx, name, tx, ty, sx = 1, sy = 1) { this.draw( ctx, name, tx * this.tilew * this.scale, ty * this.tileh * this.scale, sx, sy); return this; } get tileWidth() { return this.tilew * this.scale; } get tileHeight() { return this.tileh * this.scale; } }