escalator-web/src/gui.js

100 lines
2.5 KiB
JavaScript

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);
}
}
}