Sprite.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import {DisplayElement} from 'tui-lib/ui/primitives'
  2. import * as ansi from 'tui-lib/util/ansi'
  3. export default class Sprite extends DisplayElement {
  4. // "A sprite is a two-dimensional bitmap that is integrated into a larger
  5. // scene." - Wikipedia
  6. //
  7. // Sprites are display objects that have a single texture that will not
  8. // render outside of their parent.
  9. //
  10. // Sprites have a "real" position which overrides their "integer" position.
  11. // This is so that motion can be more fluid (i.e., sprites don't need to
  12. // move a whole number of terminal characters at a time).
  13. constructor() {
  14. super()
  15. this.texture = []
  16. this.realX = 0
  17. this.realY = 0
  18. }
  19. set x(newX) { this.realX = newX }
  20. set y(newY) { this.realY = newY }
  21. get x() { return Math.round(this.realX) }
  22. get y() { return Math.round(this.realY) }
  23. drawTo(writable) {
  24. if (this.textureAttributes) {
  25. writable.write(ansi.setAttributes(this.textureAttributes))
  26. }
  27. for (let y = 0; y < this.textureHeight; y++) {
  28. // Don't render above or below the parent's content area.
  29. if (this.y + y >= this.parent.contentH || this.y + y < 0) continue
  30. const right = this.x + this.textureWidth
  31. const start = (this.x < 0) ? -this.x : 0
  32. const end = (
  33. (right > this.parent.contentW)
  34. ? this.parent.contentW - right
  35. : right)
  36. const text = this.texture[y].slice(start, end)
  37. writable.write(ansi.moveCursor(this.absY + y, this.absX + start))
  38. writable.write(text)
  39. }
  40. if (this.textureAttributes) {
  41. writable.write(ansi.resetAttributes())
  42. }
  43. }
  44. fixLayout() {
  45. this.w = this.textureWidth
  46. this.h = this.textureHeight
  47. }
  48. get textureWidth() {
  49. return Math.max(...this.texture.map(row => ansi.measureColumns(row)))
  50. }
  51. get textureHeight() {
  52. return this.texture.length
  53. }
  54. }