You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. export default class SpriteSheet {
  2. constructor(url, tilew, tileh, scale = 1) {
  3. this.url = url;
  4. this.tilew = tilew;
  5. this.tileh = tileh;
  6. this.scale = scale;
  7. this.definitions = {};
  8. this.waiting = [];
  9. this.ready = false;
  10. this.img = new Image();
  11. this.img.src = url;
  12. this.img.onload = () => {
  13. this.ready = true;
  14. this.waiting.forEach(f => f());
  15. };
  16. this.img.onerror = err => {
  17. console.error("Failed to load "+url+".");
  18. };
  19. }
  20. whenReady(fn) {
  21. if (this.ready) return fn();
  22. this.waiting.push(fn);
  23. return this;
  24. }
  25. define(name, x, y, w = this.tilew, h = this.tileh) {
  26. this.definitions[name] = null;
  27. this.whenReady(() => {
  28. let can = document.createElement("canvas");
  29. can.width = w * this.scale;
  30. can.height = h * this.scale;
  31. let ctx = can.getContext("2d");
  32. ctx.mozImageSmoothingEnabled = false;
  33. ctx.webkitImageSmoothingEnabled = false;
  34. ctx.msImageSmoothingEnabled = false;
  35. ctx.imageSmoothingEnabled = false;
  36. ctx.drawImage(
  37. this.img, x, y,
  38. w, h, 0, 0,
  39. w * this.scale, h * this.scale);
  40. this.definitions[name] = can;
  41. });
  42. return this;
  43. }
  44. defineTile(name, tx, ty) {
  45. return this.define(name, tx * this.tilew, ty * this.tileh);
  46. }
  47. draw(ctx, name, x, y, sx = 1, sy = 1) {
  48. let def = this.definitions[name];
  49. if (def === null) return;
  50. if (def === undefined) throw new Error("Undefined sprite: "+name);
  51. ctx.drawImage(
  52. def, x, y,
  53. def.width * sx,
  54. def.height * sy);
  55. return this;
  56. }
  57. drawTile(ctx, name, tx, ty, sx = 1, sy = 1) {
  58. this.draw(
  59. ctx, name,
  60. tx * this.tilew * this.scale, ty * this.tileh * this.scale,
  61. sx, sy);
  62. return this;
  63. }
  64. get tileWidth() {
  65. return this.tilew * this.scale;
  66. }
  67. get tileHeight() {
  68. return this.tileh * this.scale;
  69. }
  70. }