{"id":1050,"date":"2019-02-04T15:16:07","date_gmt":"2019-02-04T15:16:07","guid":{"rendered":"http:\/\/www.netexl.com\/blog\/?p=1050"},"modified":"2019-02-05T04:06:08","modified_gmt":"2019-02-05T04:06:08","slug":"use-textarea-in-phaser-game","status":"publish","type":"post","link":"https:\/\/www.netexl.com\/blog\/use-textarea-in-phaser-game\/","title":{"rendered":"Use textarea in Phaser Game"},"content":{"rendered":"<p>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 &#8220;textarea&#8221; in a Phaser game. The game was responsive so it also required repositioning\u00a0and resizing of the textarea. I am posting bare minimum code to achieve this fuctionality here.<\/p>\n<p>Add following html<\/p>\n<pre class=\"lang:default decode:true\">&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n    &lt;title&gt;Demo&lt;\/title&gt;\r\n    &lt;meta http-equiv=\"Content-type\" content=\"text\/html; charset=utf-8\"&gt;\r\n    &lt;meta name=\"viewport\" content=\"width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no\"&gt;\r\n\r\n    &lt;link rel=\"stylesheet\" href=\"css\/app.css\"&gt;\r\n\r\n    &lt;script src=\"js\/phaser.min.js\"&gt;&lt;\/script&gt;\r\n    &lt;script src=\"js\/game.js\"&gt;&lt;\/script&gt;\r\n&lt;\/head&gt;\r\n    &lt;body&gt;\r\n        &lt;textarea disabled id=\"txtArea\" style=\"display:none\" class=\"txtArea\"&gt;&lt;\/textarea&gt;\r\n\r\n        &lt;div id=\"container\"&gt;\r\n            &lt;div id=\"mygame\"&gt;&lt;\/div&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>We have added a textarea which is hidden initially. We will display this component after resizing and repositioning inside the game.<\/p>\n<p>Now add css as following in app.css<\/p>\n<pre class=\"lang:default decode:true \">body {\r\n    padding: 0px;\r\n    margin: 0px;\r\n    background: #862C2C;\r\n    overflow-x: hidden;\r\n}\r\n.txtArea{\r\n    position: absolute;\r\n    background-color: #ffffff;\r\n    color: #000;\r\n    padding: 10px;\r\n    border: 3px solid #9E9E9E;\r\n    resize: none;\r\n}\r\n\r\n\/* Scrollbar styles *\/\r\n::-webkit-scrollbar {\r\nwidth: 12px;\r\nheight: 12px;\r\n}\r\n\r\n::-webkit-scrollbar-track {\r\nborder: 1px solid red;\r\nborder-radius: 10px;\r\n}\r\n\r\n::-webkit-scrollbar-thumb {\r\nbackground: #fb685d;  \r\nborder-radius: 10px;\r\n}\r\n\r\n::-webkit-scrollbar-thumb:hover {\r\nbackground: #fb9891;  \r\n}<\/pre>\n<p>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.<\/p>\n<p>Now add the game code as following<\/p>\n<pre class=\"lang:default decode:true \">\/\/ ---------------boot---------------------\r\nboot = {\r\n    preload: function () {\r\n        mygame.stage.backgroundColor = 0x33FCFF;\r\n        mygame.load.image(\"loading\", \"images\/loading.png\");\r\n    },\r\n    create: function () {\r\n        mygame.scale.scaleMode = Phaser.ScaleManager.RESIZE;\r\n        mygame.scale.setScreenSize = true;\r\n        mygame.state.start(\"Loading\");\r\n    }\r\n};\r\n\/\/ ---------------loading---------------------\r\nloading = {\r\n    preload: function () {\r\n        mygame.stage.backgroundColor = 0x33FCFF;\r\n        var loadingBar = mygame.add.sprite(this.world.centerX, this.world.centerY, \"loading\");\r\n        loadingBar.anchor.setTo(0.5);\r\n        this.load.setPreloadSprite(loadingBar);\r\n    },\r\n    create: function () {\r\n        mygame.state.start(\"TheGame\");\r\n    }\r\n};\r\n\r\n\/\/ ---------------TheGame---------------------\r\nvar TheGame = function () { };\r\n\r\nTheGame.prototype = {\r\n    init: function () {\r\n    },\r\n    create: function () {\r\n        var gameWidth = mygame.width;\r\n        var gameHeight = mygame.height;\r\n\t\tthis.title = mygame.add.text(mygame.world.centerX, mygame.world.centerY, 'My Game', { font: '24px Arial', fill: '#000' });\r\n\t\tthis.title.anchor.setTo(0.5);\r\n\r\n        this.positionControls(gameWidth, gameHeight);\r\n\t\tdisplayDiv(\"txtArea\", true);\r\n\t\tmygame.input.onDown.add(this.onMouseClick, this);\r\n    },\r\n    resize: function (width, height) {\r\n        this.positionControls(width, height);\r\n    },\r\n    positionControls: function (width, height) {\r\n\t\tthis.title.x = mygame.world.centerX;\r\n\t\tthis.title.y = height * 0.125;\r\n        this.divProps = { x: width * 0.25, y: height * 0.25, width: width * 0.50, height: height * 0.5 };\r\n        this.resizeDiv(\"txtArea\", this.divProps);\r\n    },\r\n    resizeDiv: function (id, props) {\r\n         var div = document.getElementById(id);\r\n         div.style.width = props.width + 'px';\r\n         div.style.height = props.height + 'px';\r\n         div.style.left = props.x + 'px';\r\n         div.style.top = props.y + 'px';\r\n    },\r\n\tonMouseClick: function () {\r\n\t\tthis.writeToBoard('txtArea', \"Clicked at \" + mygame.input.x + \", \" + mygame.input.y + \"\\n\");\r\n\t},\r\n    writeToBoard: function (id, message) {\r\n        var div = document.getElementById(id);\r\n        div.value += message;\r\n        div.scrollTop = div.scrollHeight;\r\n    }\r\n};\r\n\r\nfunction displayDiv(id, display) {\r\n    var x = document.getElementById(id);\r\n    if (display) {\r\n        x.style.display = \"block\";\r\n    } else {\r\n        x.style.display = \"none\";\r\n    }\r\n}\r\n\t\r\nvar mygame\r\nvar loadGame = function () {\r\n    mygame = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.AUTO, \"mygame\");\r\n\r\n    mygame.state.add(\"Boot\", boot);\r\n    mygame.state.add(\"Loading\", loading);\r\n    mygame.state.add(\"TheGame\", TheGame);\r\n    mygame.state.start(\"Boot\");\r\n};\r\n \r\nif (document.readyState === \"complete\" || (document.readyState !== \"loading\" &amp;&amp; !document.documentElement.doScroll)) {\r\n    loadGame();\r\n} else {\r\n    document.addEventListener(\"DOMContentLoaded\", loadGame);\r\n}\r\n<\/pre>\n<p>Click\u00a0<a href=\"https:\/\/www.netexl.com\/blog\/demo\/13\/index.html\" target=\"_blank\">here<\/a>\u00a0to run\u00a0the 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.<\/p>\n\n<!-- iframe plugin v.5.2 wordpress.org\/plugins\/iframe\/ -->\n<iframe loading=\"lazy\" src=\"https:\/\/www.netexl.com\/blog\/demo\/13\/index.html\" width=\"450px\" height=\"300px\" scrolling=\"yes\" class=\"iframe-class\" frameborder=\"0\"><\/iframe>\n\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &#8220;textarea&#8221; in a Phaser game. The game was responsive so it also required repositioning\u00a0and resizing of the textarea. I am posting bare minimum code to achieve this fuctionality here. Add following html &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;Demo&lt;\/title&gt; &lt;meta http-equiv=&#8221;Content-type&#8221; content=&#8221;text\/html; charset=utf-8&#8243;&gt; &lt;meta name=&#8221;viewport&#8221; content=&#8221;width=device-width, minimum-scale=1, initial-scale=1, user-scalable=no&#8221;&gt; &lt;link rel=&#8221;stylesheet&#8221; href=&#8221;css\/app.css&#8221;&gt; &lt;script src=&#8221;js\/phaser.min.js&#8221;&gt;&lt;\/script&gt; &lt;script src=&#8221;js\/game.js&#8221;&gt;&lt;\/script&gt; &lt;\/head&gt; &lt;body&gt; &lt;textarea disabled id=&#8221;txtArea&#8221; style=&#8221;display:none&#8221; class=&#8221;txtArea&#8221;&gt;&lt;\/textarea&gt; &lt;div id=&#8221;container&#8221;&gt; &lt;div id=&#8221;mygame&#8221;&gt;&lt;\/div&gt; &lt;\/div&gt; &lt;\/body&gt; &lt;\/html&gt; 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;[&#8230;]<\/p>\n","protected":false},"author":5,"featured_media":293,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,3,24,4,22],"tags":[],"class_list":["post-1050","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","category-html5","category-javascript","category-phaser","category-quick-tip"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1050","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/comments?post=1050"}],"version-history":[{"count":4,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1050\/revisions"}],"predecessor-version":[{"id":1057,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1050\/revisions\/1057"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/media\/293"}],"wp:attachment":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/media?parent=1050"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/categories?post=1050"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/tags?post=1050"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}