const Type = { Stroke: 1, Fill: 2, StrokeFill: 3, }; class GuiButton { // x and y are the center of the button constructor(context, text, x, y, type, callback) { this.font = context.font; this.fillStyle = context.fillStyle; this.strokeStyle = context.strokeStyle; this.text = text; this.x = x; this.y = y; this.callback = callback; this.type = type; } } class Gui extends Screen { constructor(canvas) { super(canvas); this.buttons = []; this.addEventListener('touchstart', (event) => { this.onTouchStart(event); }); } textToString(text) { if (typeof text === 'string' || text instanceof String) { return text; } else if (typeof text === 'function') { return text(); } } addButton(button) { this.buttons.push(button); } onTouchStart(event) { for (let button of this.buttons) { // Compute the box of the button let text = this.textToString(button.text); let width = this.context.measureText(text).width; let height = parseInt(button.font.split('p')[0], 10); let x = button.x * this.width() - width / 2; let fontHeight = parseInt(button.font.split('p')[0], 10); let y = button.y * this.height() - fontHeight; let box = enlargeBox({ x: x, y: y, width: width, height: height }); let e = event.changedTouches[0]; if (typeof button.callback === 'function' && isInBox(position(e), box)) { button.callback(); } } } renderButton(button) { this.context.font = button.font; this.context.fillStyle = button.fillStyle; this.context.strokeStyle = button.strokeStyle; let text = this.textToString(button.text); let width = this.context.measureText(text).width; let x = button.x * this.width() - width / 2; let y = button.y * this.height(); if (button.type === Type.Fill || button.type === Type.StrokeFill) { this.context.fillText(text, x, y); } if (button.type === Type.Stroke || button.type === Type.StrokeFill) { this.context.strokeText(text, x, y); } } render() { this.clear(); this.drawBackground(); for (let button of this.buttons) { this.renderButton(button); } } }