From 6ea74c268a12325296a1d2e7fc31b02030ddb8bc Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 12 May 2023 17:42:09 -0300 Subject: use ESM module syntax & minor cleanups The biggest change here is moving various element classes under more scope-specific directories, which helps to avoid circular dependencies and is just cleaner to navigate and expand in the future. Otherwise this is a largely uncritical port to ESM module syntax! There are probably a number of changes and other cleanups that remain much needed. Whenever I make changes to tui-lib it's hard to believe it's already been years since the previous time. First commits are from January 2017, and the code originates a month earlier in KAaRMNoD! --- ui/presentation/Sprite.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 ui/presentation/Sprite.js (limited to 'ui/presentation/Sprite.js') diff --git a/ui/presentation/Sprite.js b/ui/presentation/Sprite.js new file mode 100644 index 0000000..49ee450 --- /dev/null +++ b/ui/presentation/Sprite.js @@ -0,0 +1,69 @@ +import {DisplayElement} from 'tui-lib/ui/primitives' + +import * as ansi from 'tui-lib/util/ansi' + +export default class Sprite extends DisplayElement { + // "A sprite is a two-dimensional bitmap that is integrated into a larger + // scene." - Wikipedia + // + // Sprites are display objects that have a single texture that will not + // render outside of their parent. + // + // Sprites have a "real" position which overrides their "integer" position. + // This is so that motion can be more fluid (i.e., sprites don't need to + // move a whole number of terminal characters at a time). + + constructor() { + super() + + this.texture = [] + + this.realX = 0 + this.realY = 0 + } + + set x(newX) { this.realX = newX } + set y(newY) { this.realY = newY } + get x() { return Math.round(this.realX) } + get y() { return Math.round(this.realY) } + + drawTo(writable) { + if (this.textureAttributes) { + writable.write(ansi.setAttributes(this.textureAttributes)) + } + + for (let y = 0; y < this.textureHeight; y++) { + // Don't render above or below the parent's content area. + if (this.y + y >= this.parent.contentH || this.y + y < 0) continue + + const right = this.x + this.textureWidth + + const start = (this.x < 0) ? -this.x : 0 + const end = ( + (right > this.parent.contentW) + ? this.parent.contentW - right + : right) + const text = this.texture[y].slice(start, end) + + writable.write(ansi.moveCursor(this.absY + y, this.absX + start)) + writable.write(text) + } + + if (this.textureAttributes) { + writable.write(ansi.resetAttributes()) + } + } + + fixLayout() { + this.w = this.textureWidth + this.h = this.textureHeight + } + + get textureWidth() { + return Math.max(...this.texture.map(row => ansi.measureColumns(row))) + } + + get textureHeight() { + return this.texture.length + } +} -- cgit 1.3.0-6-gf8a5