roguelike-pumpkin-patch
Version:
A roguelike development library in JavaScript.
238 lines • 9.81 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import Tile from './Tile.js';
import css from './DisplayStyle.js';
/** Display class, to create and control a display */
var Display = /** @class */ (function () {
/** Create a new Display
* @param {DisplayParams} parameters - Object of parameters to initialize the display.
*/
function Display(parameters) {
var target = parameters.target, _a = parameters.width, width = _a === void 0 ? 1 : _a, _b = parameters.height, height = _b === void 0 ? 1 : _b, tileWidth = parameters.tileWidth, tileHeight = parameters.tileHeight, rest = __rest(parameters, ["target", "width", "height", "tileWidth", "tileHeight"]);
// Set the target
this.target = target;
if (this.target.className) {
this.target.classList.add("pumpkin-container");
}
else {
this.target.className = "pumpkin-container";
}
// Create the element for the display
this.element = document.createElement('div');
this.element.className = "pumpkin-display";
this.element.setAttribute("aria-hidden", "true");
// Set the display dimensions
this.dimensions = { width: width, height: height };
this.tileSize = {
tileWidth: (tileWidth) ? tileWidth : 16,
tileHeight: (tileHeight) ? tileHeight : (tileWidth) ? tileWidth : 16
};
// Add style to the page for the display
this.applyDefaultStyles();
// Append to the container element
this.target.appendChild(this.element);
}
;
Object.defineProperty(Display.prototype, "tileSize", {
/** Tile size */
get: function () {
return this._tileSize;
},
set: function (newTileSize) {
var _a;
this._tileSize = newTileSize;
this.element.style.fontSize = newTileSize.tileHeight + "px";
(_a = this.tiles) === null || _a === void 0 ? void 0 : _a.forEach(function (tile) {
tile.tileWidth = newTileSize.tileWidth;
tile.tileHeight = newTileSize.tileHeight;
tile.position = tile.position;
});
this.resetSize();
},
enumerable: false,
configurable: true
});
;
;
Object.defineProperty(Display.prototype, "dimensions", {
/** Get or set the display dimensions */
get: function () {
return { width: this._width, height: this._height };
},
set: function (newDimensions) {
if (newDimensions.width !== this._width && newDimensions.height !== this._height) {
this._width = newDimensions.width;
this._height = newDimensions.height;
// Reset the display to accomodate the new size
this.allocateDisplay();
this.resetSize();
this.moveToCenter();
}
},
enumerable: false,
configurable: true
});
;
;
/** Reset display element size */
Display.prototype.resetSize = function () {
if (this._width && this._height && this.tileSize) {
this.element.style.width = this._width * this.tileSize.tileWidth + "px";
this.element.style.height = this._height * this.tileSize.tileHeight + "px";
}
};
/** Position to center the display view on */
Display.prototype.centerDisplay = function (x, y) {
if (typeof x === "undefined" || typeof y === "undefined") {
this.centerPosition = undefined;
}
else {
this.centerPosition = {
x: x,
y: y
};
}
this.moveToCenter();
};
Display.prototype.moveToCenter = function () {
if (this.centerPosition) {
var xPercent = (this.centerPosition.x + 0.5) / this.dimensions.width;
var yPercent = (this.centerPosition.y + 0.5) / this.dimensions.height;
this.element.style.transform = "translate(" + -xPercent * 100 + "%," + -yPercent * 100 + "%)";
}
else {
this.element.style.transform = "";
}
};
/** Build the array of tiles and attach them to the display */
Display.prototype.allocateDisplay = function () {
var _this = this;
// Start a fresh tiles array
if (this.tiles) {
// Empty display if it has contents already
this.tiles.forEach(function (tile) {
_this.element.removeChild(tile.element);
});
}
this.tiles = [];
// Generate tiles
for (var y = 0; y < this._height; y++) {
for (var x = 0; x < this._width; x++) {
// Make a new tile
var newTile = new Tile({
content: '',
}, { x: x, y: y }, this.tileSize);
// Add it to the list of tiles
this.tiles.push(newTile);
// Append to the actual display
this.element.appendChild(newTile.element);
}
}
};
;
/** Get the display tile at the specified position
* @param {number} x - Position from the left side of the display
* @param {number} y - Position from the top of the display
*/
Display.prototype.getTile = function (x, y) {
if (x >= 0 && x < this._width && y >= 0 && y < this._height) {
var index = x + y * this._width;
return this.tiles[index];
}
else {
return undefined;
}
};
;
/** Take input and format into TileOptions */
Display.prototype.formatTileOptions = function (input) {
if (typeof input === "string") {
return { content: input };
}
else if (input instanceof HTMLElement) {
return { content: input };
}
else {
return input;
}
};
/** Set details for the specified tile */
Display.prototype.setTile = function (x, y, newOptions) {
var tile = this.getTile(x, y);
if (tile) {
tile.setOptions(this.formatTileOptions(newOptions));
}
};
;
/** Update details for the specified tile, preserving every unset property. */
Display.prototype.updateTile = function (x, y, newOptions) {
var tile = this.getTile(x, y);
if (tile) {
tile.updateOptions(this.formatTileOptions(newOptions));
}
};
;
/** Given the size of the target container, and the tile size, determine the number of tiles needed. */
Display.prototype.calculateDimensions = function (clientRect) {
if (clientRect === void 0) { clientRect = this.target.getBoundingClientRect(); }
var clientWidth = Math.abs(clientRect.right - clientRect.left);
var clientHeight = Math.abs(clientRect.bottom - clientRect.top);
// Round down; we do not want partial tiles
return {
width: Math.floor(clientWidth / this.tileSize.tileWidth),
height: Math.floor(clientHeight / this.tileSize.tileHeight)
};
};
;
/** Given the size of the target container, and the number of tiles, determine the tile size needed
* This assumes square tiles are desired.
*/
Display.prototype.calculateTileSize = function (clientRect) {
if (clientRect === void 0) { clientRect = this.target.getBoundingClientRect(); }
var clientWidth = Math.abs(clientRect.right - clientRect.left);
var clientHeight = Math.abs(clientRect.bottom - clientRect.top);
// This could potentially give absurd results, so get the "naive first-guess" here
var size = {
tileWidth: clientWidth / this.dimensions.width,
tileHeight: clientHeight / this.dimensions.height
};
// Choose the lowest of the two. This is the maximum square tile size that will fit the given dimensions
var maxTileSize = Math.min(size.tileWidth, size.tileHeight);
// Don't bother rounding; fonts can be precise numbers
return {
tileWidth: maxTileSize,
tileHeight: maxTileSize
};
};
;
/** Add the default styles to the head of the page. */
Display.prototype.applyDefaultStyles = function () {
var stylesId = "pumpkin-default-styles";
// Check to make sure the styles aren't already present
if (!document.getElementById(stylesId)) {
// Create the style element
var styles = document.createElement("style");
styles.id = stylesId;
styles.type = "text/css";
styles.appendChild(document.createTextNode(css));
// Get the head of the page
var head = document.head;
// Find the first style or link element, and insert in front of it
var firstStyle = document.querySelector("style, link");
head.insertBefore(styles, firstStyle);
}
};
return Display;
}());
export default Display;
;
//# sourceMappingURL=Display.js.map