Make name entry on mobile browsers possible
Prior to this change, there wasn't a way in mobile browsers to show the virtual keyboard in order to enter the player name. With this change, the name entry is now done via a hidden input field, which enables the use if a virtual keyboard. Mobile browsers are not special cased, the desktop browsers will also use the input field.
This commit is contained in:
parent
6e9c715980
commit
86e90c2dc2
@ -1,7 +1,9 @@
|
|||||||
|
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||||
|
|
||||||
export class TextInput extends Phaser.GameObjects.BitmapText {
|
export class TextInput extends Phaser.GameObjects.BitmapText {
|
||||||
private minUnderLineLength = 4;
|
private minUnderLineLength = 4;
|
||||||
private underLine: Phaser.GameObjects.Text;
|
private underLine: Phaser.GameObjects.Text;
|
||||||
|
private onChange: (text: string) => void;
|
||||||
|
|
||||||
constructor(scene: Phaser.Scene, x: number, y: number, maxLength: number, text: string, onChange: (text: string) => void) {
|
constructor(scene: Phaser.Scene, x: number, y: number, maxLength: number, text: string, onChange: (text: string) => void) {
|
||||||
super(scene, x, y, 'main_font', text, 32);
|
super(scene, x, y, 'main_font', text, 32);
|
||||||
@ -10,17 +12,28 @@ export class TextInput extends Phaser.GameObjects.BitmapText {
|
|||||||
|
|
||||||
this.underLine = this.scene.add.text(x, y+1, this.getUnderLineBody(text.length), { fontFamily: 'Arial', fontSize: "32px", color: '#ffffff'})
|
this.underLine = this.scene.add.text(x, y+1, this.getUnderLineBody(text.length), { fontFamily: 'Arial', fontSize: "32px", color: '#ffffff'})
|
||||||
this.underLine.setOrigin(0.5)
|
this.underLine.setOrigin(0.5)
|
||||||
|
this.onChange = onChange;
|
||||||
|
|
||||||
|
// Use a hidden input field so that on mobile browsers the virtual
|
||||||
|
// keyboard will be displayed
|
||||||
|
const mainContainer = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-container');
|
||||||
|
const inputElement = document.createElement('input');
|
||||||
|
inputElement.id = 'playerName';
|
||||||
|
inputElement.maxLength = maxLength
|
||||||
|
// Make sure that now scolling is needed and that the input field is
|
||||||
|
// not visible
|
||||||
|
inputElement.setAttribute('style', 'opacity:0;position:absolute;bottom:0');
|
||||||
|
mainContainer.appendChild(inputElement);
|
||||||
|
|
||||||
this.scene.input.keyboard.on('keydown', (event: KeyboardEvent) => {
|
inputElement.addEventListener('input', this.onInput.bind(this) as EventListener);
|
||||||
if (event.keyCode === 8 && this.text.length > 0) {
|
}
|
||||||
this.deleteLetter();
|
|
||||||
} else if ((event.keyCode === 32 || (event.keyCode >= 48 && event.keyCode <= 90)) && this.text.length < maxLength) {
|
private onInput(event: InputEvent) {
|
||||||
this.addLetter(event.key);
|
const inputElement = <HTMLInputElement>event.target;
|
||||||
}
|
// Truncate the text to the maximum length, this is needed for mobile
|
||||||
this.underLine.text = this.getUnderLineBody(this.text.length);
|
// browsers that don't support the input field `maxLength` attribute
|
||||||
onChange(this.text);
|
this.text = inputElement.value.substr(0, inputElement.maxLength)
|
||||||
});
|
this.onChange(this.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getUnderLineBody(textLength:number): string {
|
private getUnderLineBody(textLength:number): string {
|
||||||
@ -32,15 +45,6 @@ export class TextInput extends Phaser.GameObjects.BitmapText {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private deleteLetter() {
|
|
||||||
this.text = this.text.substr(0, this.text.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private addLetter(letter: string) {
|
|
||||||
this.text += letter;
|
|
||||||
}
|
|
||||||
|
|
||||||
getText(): string {
|
getText(): string {
|
||||||
return this.text;
|
return this.text;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||||
import {gameManager} from "../Game/GameManager";
|
import {gameManager} from "../Game/GameManager";
|
||||||
import {TextField} from "../Components/TextField";
|
import {TextField} from "../Components/TextField";
|
||||||
import {TextInput} from "../Components/TextInput";
|
import {TextInput} from "../Components/TextInput";
|
||||||
@ -41,6 +42,22 @@ export class LoginScene extends ResizableScene {
|
|||||||
this.name = text;
|
this.name = text;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mobile Browsers need an input field, so that a virtual keyboard
|
||||||
|
// gets shown
|
||||||
|
const nameInputElement = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('playerName');
|
||||||
|
// As we need an input field for mobile browsers, use it also for
|
||||||
|
// the desktop. Therefore make sure that is has the focus when the page
|
||||||
|
// is loaded, so that all keyboard events are handled by that input
|
||||||
|
// field.
|
||||||
|
nameInputElement.focus()
|
||||||
|
// Mobile browsers won't show the virtual keyboard on page load, hence
|
||||||
|
// re-focus to make it pop up. On desktop browsers it doesn't do any
|
||||||
|
// harm.
|
||||||
|
this.input.on('pointerdown', () => {
|
||||||
|
nameInputElement.blur();
|
||||||
|
nameInputElement.focus();
|
||||||
|
});
|
||||||
|
|
||||||
this.pressReturnField = new TextField(this, this.game.renderer.width / 2, 130, 'Press enter to start');
|
this.pressReturnField = new TextField(this, this.game.renderer.width / 2, 130, 'Press enter to start');
|
||||||
|
|
||||||
this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, LoginTextures.icon);
|
this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, LoginTextures.icon);
|
||||||
|
Loading…
Reference in New Issue
Block a user