In order to use textboxes in canvas we can use html input components and position them over the canvas. I recently had a requirement to display a message board resembling “textarea” in a Phaser game. The game was responsive so it also required repositioning and resizing of the textarea. I am posting bare minimum code to achieve this fuctionality here.
Add following html
<!DOCTYPE html> <html> <head> <title>Demo</title> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no"> <link rel="stylesheet" href="css/app.css"> <script src="js/phaser.min.js"></script> <script src="js/game.js"></script> </head> <body> <textarea disabled id="txtArea" style="display:none" class="txtArea"></textarea> <div id="container"> <div id="mygame"></div> </div> </body> </html>
We have added a textarea which is hidden initially. We will display this component after resizing and repositioning inside the game.
Now add css as following in app.css
body { padding: 0px; margin: 0px; background: #862C2C; overflow-x: hidden; } .txtArea{ position: absolute; background-color: #ffffff; color: #000; padding: 10px; border: 3px solid #9E9E9E; resize: none; } /* Scrollbar styles */ ::-webkit-scrollbar { width: 12px; height: 12px; } ::-webkit-scrollbar-track { border: 1px solid red; border-radius: 10px; } ::-webkit-scrollbar-thumb { background: #fb685d; border-radius: 10px; } ::-webkit-scrollbar-thumb:hover { background: #fb9891; }
We can customize scrollbar styles to make it look nicer using webkit scrollbar properties. You can change these styles to match your game. This works on chrome and safari. Other browsers do not support these properties but you can still stylize it using normal css styles to match your game.
Now add the game code as following
// ---------------boot--------------------- boot = { preload: function () { mygame.stage.backgroundColor = 0x33FCFF; mygame.load.image("loading", "images/loading.png"); }, create: function () { mygame.scale.scaleMode = Phaser.ScaleManager.RESIZE; mygame.scale.setScreenSize = true; mygame.state.start("Loading"); } }; // ---------------loading--------------------- loading = { preload: function () { mygame.stage.backgroundColor = 0x33FCFF; var loadingBar = mygame.add.sprite(this.world.centerX, this.world.centerY, "loading"); loadingBar.anchor.setTo(0.5); this.load.setPreloadSprite(loadingBar); }, create: function () { mygame.state.start("TheGame"); } }; // ---------------TheGame--------------------- var TheGame = function () { }; TheGame.prototype = { init: function () { }, create: function () { var gameWidth = mygame.width; var gameHeight = mygame.height; this.title = mygame.add.text(mygame.world.centerX, mygame.world.centerY, 'My Game', { font: '24px Arial', fill: '#000' }); this.title.anchor.setTo(0.5); this.positionControls(gameWidth, gameHeight); displayDiv("txtArea", true); mygame.input.onDown.add(this.onMouseClick, this); }, resize: function (width, height) { this.positionControls(width, height); }, positionControls: function (width, height) { this.title.x = mygame.world.centerX; this.title.y = height * 0.125; this.divProps = { x: width * 0.25, y: height * 0.25, width: width * 0.50, height: height * 0.5 }; this.resizeDiv("txtArea", this.divProps); }, resizeDiv: function (id, props) { var div = document.getElementById(id); div.style.width = props.width + 'px'; div.style.height = props.height + 'px'; div.style.left = props.x + 'px'; div.style.top = props.y + 'px'; }, onMouseClick: function () { this.writeToBoard('txtArea', "Clicked at " + mygame.input.x + ", " + mygame.input.y + "\n"); }, writeToBoard: function (id, message) { var div = document.getElementById(id); div.value += message; div.scrollTop = div.scrollHeight; } }; function displayDiv(id, display) { var x = document.getElementById(id); if (display) { x.style.display = "block"; } else { x.style.display = "none"; } } var mygame var loadGame = function () { mygame = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.AUTO, "mygame"); mygame.state.add("Boot", boot); mygame.state.add("Loading", loading); mygame.state.add("TheGame", TheGame); mygame.state.start("Boot"); }; if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { loadGame(); } else { document.addEventListener("DOMContentLoaded", loadGame); }
Click here to run the example on your system. Click on the game area to add message to the textarea. Resize the screen which will correctly calculate textarea size and reposition it in the game area.