66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
import * as Phaser from 'phaser';
|
|
|
|
// DOM-overlay text input. Positions a real <input> element above the canvas
|
|
// using the scene's scale so it lines up with where you'd draw it in Phaser.
|
|
export class TextInput {
|
|
constructor(scene, x, y, options = {}) {
|
|
this.scene = scene;
|
|
this.gameX = x;
|
|
this.gameY = y;
|
|
this.width = options.width ?? 360;
|
|
this.height = options.height ?? 48;
|
|
this.layer = document.getElementById('dom-layer');
|
|
|
|
const isTextarea = options.multiline === true;
|
|
this.el = document.createElement(isTextarea ? 'textarea' : 'input');
|
|
if (!isTextarea) this.el.type = options.type ?? 'text';
|
|
if (options.placeholder) this.el.placeholder = options.placeholder;
|
|
if (options.value !== undefined) this.el.value = options.value;
|
|
if (options.maxLength) this.el.maxLength = options.maxLength;
|
|
if (options.autocomplete) this.el.autocomplete = options.autocomplete;
|
|
this.el.style.position = 'absolute';
|
|
this.el.style.boxSizing = 'border-box';
|
|
this.layer.appendChild(this.el);
|
|
|
|
this.reposition = this.reposition.bind(this);
|
|
this.scene.scale.on('resize', this.reposition);
|
|
this.reposition();
|
|
|
|
this.scene.events.once(Phaser.Scenes.Events.SHUTDOWN, () => this.destroy());
|
|
this.scene.events.once(Phaser.Scenes.Events.DESTROY, () => this.destroy());
|
|
}
|
|
|
|
reposition() {
|
|
const cam = this.scene.cameras.main;
|
|
const zoom = this.scene.scale.displayScale; // {x, y} canvas-to-css scale
|
|
const canvas = this.scene.scale.canvas;
|
|
const rect = canvas.getBoundingClientRect();
|
|
const cssX = rect.left + (this.gameX - this.width / 2) / zoom.x;
|
|
const cssY = rect.top + (this.gameY - this.height / 2) / zoom.y;
|
|
const cssW = this.width / zoom.x;
|
|
const cssH = this.height / zoom.y;
|
|
this.el.style.left = `${cssX}px`;
|
|
this.el.style.top = `${cssY}px`;
|
|
this.el.style.width = `${cssW}px`;
|
|
this.el.style.height = `${cssH}px`;
|
|
this.el.style.fontSize = `${20 / zoom.y}px`;
|
|
// Avoid unused-variable lint complaints
|
|
void cam;
|
|
}
|
|
|
|
get value() { return this.el.value; }
|
|
set value(v) { this.el.value = v; }
|
|
|
|
focus() { this.el.focus(); }
|
|
|
|
on(event, handler) {
|
|
this.el.addEventListener(event, handler);
|
|
return this;
|
|
}
|
|
|
|
destroy() {
|
|
this.scene.scale.off('resize', this.reposition);
|
|
this.el.remove();
|
|
}
|
|
}
|