UNPKG

rot-js

Version:

A roguelike toolkit in JavaScript

79 lines (78 loc) 3.2 kB
import Canvas from "./canvas.js"; /** * @class Tile backend * @private */ export default class Tile extends Canvas { constructor() { super(); this._colorCanvas = document.createElement("canvas"); } draw(data, clearBefore) { let [x, y, ch, fg, bg] = data; let tileWidth = this._options.tileWidth; let tileHeight = this._options.tileHeight; if (clearBefore) { if (this._options.tileColorize) { this._ctx.clearRect(x * tileWidth, y * tileHeight, tileWidth, tileHeight); } else { this._ctx.fillStyle = bg; this._ctx.fillRect(x * tileWidth, y * tileHeight, tileWidth, tileHeight); } } if (!ch) { return; } let chars = [].concat(ch); let fgs = [].concat(fg); let bgs = [].concat(bg); for (let i = 0; i < chars.length; i++) { let tile = this._options.tileMap[chars[i]]; if (!tile) { throw new Error(`Char "${chars[i]}" not found in tileMap`); } if (this._options.tileColorize) { // apply colorization let canvas = this._colorCanvas; let context = canvas.getContext("2d"); context.globalCompositeOperation = "source-over"; context.clearRect(0, 0, tileWidth, tileHeight); let fg = fgs[i]; let bg = bgs[i]; context.drawImage(this._options.tileSet, tile[0], tile[1], tileWidth, tileHeight, 0, 0, tileWidth, tileHeight); if (fg != "transparent") { context.fillStyle = fg; context.globalCompositeOperation = "source-atop"; context.fillRect(0, 0, tileWidth, tileHeight); } if (bg != "transparent") { context.fillStyle = bg; context.globalCompositeOperation = "destination-over"; context.fillRect(0, 0, tileWidth, tileHeight); } this._ctx.drawImage(canvas, x * tileWidth, y * tileHeight, tileWidth, tileHeight); } else { // no colorizing, easy this._ctx.drawImage(this._options.tileSet, tile[0], tile[1], tileWidth, tileHeight, x * tileWidth, y * tileHeight, tileWidth, tileHeight); } } } computeSize(availWidth, availHeight) { let width = Math.floor(availWidth / this._options.tileWidth); let height = Math.floor(availHeight / this._options.tileHeight); return [width, height]; } computeFontSize() { throw new Error("Tile backend does not understand font size"); } _normalizedEventToPosition(x, y) { return [Math.floor(x / this._options.tileWidth), Math.floor(y / this._options.tileHeight)]; } _updateSize() { const opts = this._options; this._ctx.canvas.width = opts.width * opts.tileWidth; this._ctx.canvas.height = opts.height * opts.tileHeight; this._colorCanvas.width = opts.tileWidth; this._colorCanvas.height = opts.tileHeight; } }