I'm using HTML5 and canvas to design a game for which I need a keyboard input element. I do NOT want to use the device's keyboard, but instead, would like to make a custom keyboard that will be "fixed" to the screen/canvas for the duration of gameplay. I've seen NETTUT's sample of a CSS/JS/HTML5 keyboard. I would love to recreate the IOS-like interface in that example. However, I'm interested in a keyboard that is integrated into the canvas (in other words, no CSS). Is that possible? If so, what are the different methods that I use in order to draw the keyboard and give it functionality WITHIN the canvas using javascript? Scaling is also a concern. I'm extremely comfortable with HTML5/CSS but I am brand new to Javascript, so PLEASE break it ALL the way down. Thanks!
-
1Possibly [this](http://stackoverflow.com/questions/596481/simulate-javascript-key-events) and [this](http://stackoverflow.com/questions/4846687/j) questions can help. – antejan Jan 16 '13 at 00:33
-
1Antejan, thanks for the links. I would like a code/method that works in both safari and chrome and recognizes touch on the keyboard. Should I use
in the HTML and draw the background of the keyboard and/or keys? I would also like to highlight the button when clicked. I thought that I could separate the keyboard background, keys, and highlighted key images and use canvas to draw the characters over the keys. Is this a good idea? BTW, I would like to keep this application as lightweight as possible. – Sabrina Shields Jan 19 '13 at 02:08
1 Answers
I do this in my library project (visual-js game engine) please this post Virtual keyboar in canvas2d .
Live example : hosted on jsfiddle
Problem for can be implementation (it is not pure and native to make easy copy paste) . In v-js ge you can draw custom canvas2d code. I will suggest you to look at :
Here is idea. Create object with (x,y,w,h) and create in click event calculating method 'is it clicked in object bounds' . Best way is to put it all(obj's) in array then in click event check for whose obj's reseive clicks.
for example draws for that object can be :
if (obj.visible == true) {
ctx.fillRect( obj.x , obj.y , obj.w , obj.h )
ctx.fillText( obj.TEXT , obj.x -obj.w/2 , obj.y ) // dont use height for ipad/iphone
// set up middle positon of text
}
You can use samo model object for keyboard elements and also textbox element in canvas .(i dont talk about html tags)
In your game something action is done and you will need to create for every character uniq object with one char ( "A" , "SHIFT", "ENTER" etc ... ) make position for every obj. Draw all keyboard obj's .
' Now you need some flag to know what is current ACTIVE_ELEMENT (any param in your game).
There is one big problem in moment when you append char (some special chars) they have some text format deforms. I ask but there is no answer (i will post that question later) .
In this code block is solution for that problem (i cant simple pass value for current keycode) Looks like hardcode but it is only solution for me :
ROOT.CAPTURE_CHAR = "";
ROOT.CLEAR_CAPTURE_ON_PRESS_ENTER = true;
ROOT.LAST_CAPTURE_CHAR = "";
ROOT.ENTER_PRESSED = false;
ROOT.SHIFT_PRESSED = false;
ROOT.ACTION_ON_KEY_DOWN = function(){};
...
//@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@
// SPECIAL FOR TEXTBOX
//@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@
SYS.DEBUG.LOG("KEYBOARD-->> Show users types : " + e.keyCode );
var keynum;
if(window.event){ keynum = e.keyCode;}else{if(e.which){ keynum = e.which;}}
//console.log(String.fromCharCode(keynum));
if (e.keyCode == 16){
ROOT.SHIFT_PRESSED = true;
}
if (e.keyCode == 8) {
SYS.DEBUG.LOG("textbox delete last char!");
ROOT.CAPTURE_CHAR = remove_last( ROOT.CAPTURE_CHAR );
}
else if(e.keyCode == 13){
ROOT.ENTER_PRESSED = true;
}
else {
if (ROOT.SHIFT_PRESSED == false) {
if (e.keyCode == 189) {
ROOT.CAPTURE_CHAR+="_";
ROOT.LAST_CAPTURE_CHAR ="_";
}
else if (e.keyCode == 187) {
ROOT.CAPTURE_CHAR+="+";
ROOT.LAST_CAPTURE_CHAR ="+";
}
else if (e.keyCode == 187) {
ROOT.CAPTURE_CHAR+="+";
ROOT.LAST_CAPTURE_CHAR ="+";
}
else if (e.keyCode == 188) {
ROOT.CAPTURE_CHAR+=",";
ROOT.LAST_CAPTURE_CHAR =",";
}
else if (e.keyCode == 190) {
ROOT.CAPTURE_CHAR+=".";
ROOT.LAST_CAPTURE_CHAR =".";
}
else if (e.keyCode == 191) {
ROOT.CAPTURE_CHAR+="/";
ROOT.LAST_CAPTURE_CHAR ="/";
}
else if (e.keyCode == 186) {
ROOT.CAPTURE_CHAR+=";";
ROOT.LAST_CAPTURE_CHAR =";";
}
else if (e.keyCode == 222) {
ROOT.CAPTURE_CHAR+="'";
ROOT.LAST_CAPTURE_CHAR ="'";
}
else if (e.keyCode == 220) {
ROOT.CAPTURE_CHAR+= "\\";
ROOT.LAST_CAPTURE_CHAR ='\\';
}
else if (e.keyCode == 219) {
ROOT.CAPTURE_CHAR+='[';
ROOT.LAST_CAPTURE_CHAR ='[';
}
else if (e.keyCode == 221) {
ROOT.CAPTURE_CHAR+=']';
ROOT.LAST_CAPTURE_CHAR =']';
}
else{
ROOT.CAPTURE_CHAR+=(String.fromCharCode(keynum).toLowerCase());
ROOT.LAST_CAPTURE_CHAR = (String.fromCharCode(keynum).toLowerCase());
}
}
else {
if (e.keyCode == 50) {
ROOT.CAPTURE_CHAR+="@";
ROOT.LAST_CAPTURE_CHAR ="@";
}
else if (e.keyCode == 49) {
ROOT.CAPTURE_CHAR+="!";
ROOT.LAST_CAPTURE_CHAR ="!";
}
else if (e.keyCode == 51) {
ROOT.CAPTURE_CHAR+="#";
ROOT.LAST_CAPTURE_CHAR ="#";
}
else if (e.keyCode == 52) {
ROOT.CAPTURE_CHAR+="$";
ROOT.LAST_CAPTURE_CHAR ="$";
}
else if (e.keyCode == 53) {
ROOT.CAPTURE_CHAR+="%";
ROOT.LAST_CAPTURE_CHAR ="%";
}
else if (e.keyCode == 54) {
ROOT.CAPTURE_CHAR+="^";
ROOT.LAST_CAPTURE_CHAR ="^";
}
else if (e.keyCode == 55) {
ROOT.CAPTURE_CHAR+="&";
ROOT.LAST_CAPTURE_CHAR ="&";
}
else if (e.keyCode == 56) {
ROOT.CAPTURE_CHAR+="*";
ROOT.LAST_CAPTURE_CHAR ="*";
}
else if (e.keyCode == 57) {
ROOT.CAPTURE_CHAR+="(";
ROOT.LAST_CAPTURE_CHAR ="(";
}
else if (e.keyCode == 48) {
ROOT.CAPTURE_CHAR+=")";
ROOT.LAST_CAPTURE_CHAR =")";
}
else if (e.keyCode == 189) {
ROOT.CAPTURE_CHAR+="_";
ROOT.LAST_CAPTURE_CHAR ="_";
}
else if (e.keyCode == 187) {
ROOT.CAPTURE_CHAR+="+";
ROOT.LAST_CAPTURE_CHAR ="+";
}
else if (e.keyCode == 187) {
ROOT.CAPTURE_CHAR+="+";
ROOT.LAST_CAPTURE_CHAR ="+";
}
else if (e.keyCode == 188) {
ROOT.CAPTURE_CHAR+="<";
ROOT.LAST_CAPTURE_CHAR ="<";
}
else if (e.keyCode == 190) {
ROOT.CAPTURE_CHAR+=">";
ROOT.LAST_CAPTURE_CHAR =">";
}
else if (e.keyCode == 191) {
ROOT.CAPTURE_CHAR+="?";
ROOT.LAST_CAPTURE_CHAR ="?";
}
else if (e.keyCode == 186) {
ROOT.CAPTURE_CHAR+=":";
ROOT.LAST_CAPTURE_CHAR =":";
}
else if (e.keyCode == 222) {
ROOT.CAPTURE_CHAR+='"';
ROOT.LAST_CAPTURE_CHAR ='"';
}
else if (e.keyCode == 220) {
ROOT.CAPTURE_CHAR+='|';
ROOT.LAST_CAPTURE_CHAR ='|';
}
else if (e.keyCode == 219) {
ROOT.CAPTURE_CHAR+='{';
ROOT.LAST_CAPTURE_CHAR ='{';
}
else if (e.keyCode == 221) {
ROOT.CAPTURE_CHAR+='}';
ROOT.LAST_CAPTURE_CHAR ='}';
}
else {
ROOT.CAPTURE_CHAR+=(String.fromCharCode(keynum).toUpperCase());
ROOT.LAST_CAPTURE_CHAR = (String.fromCharCode(keynum).toUpperCase());
}
}
}
ROOT.ACTION_ON_KEY_DOWN();
//@@@@@@@@@@@@@@@@@@@@@@@@@
if (typeof ROOT.TARGET_MODUL != 'undefined' && typeof ROOT.TARGET != 'undefined' ) {
ROOT.CAPTURE_CHAR = ROOT.CAPTURE_CHAR.replace(/[^\x00-\x7F]/g, "");
ROOT.CAPTURE_CHAR = ROOT.CAPTURE_CHAR.replace(/[^A-Za-z 0-9 \.,\?""!#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '');
window[ROOT.PROGRAM_NAME].ENGINE.MODULES.ACCESS(ROOT.TARGET_MODUL).GAME_OBJECTS.ACCESS(ROOT.TARGET).TEXTBOX.TEXT = ROOT.CAPTURE_CHAR;
if (ROOT.ENTER_PRESSED == true) {
window[ROOT.PROGRAM_NAME].ENGINE.MODULES.ACCESS(ROOT.TARGET_MODUL).GAME_OBJECTS.ACCESS(ROOT.TARGET).TEXTBOX.ON_PRESS_ENTER();
if ( ROOT.CLEAR_CAPTURE_ON_PRESS_ENTER == true )
{
ROOT.CAPTURE_CHAR = '';
}
}
}
ROOT.ENTER_PRESSED = false;
//local_go.TEXTBOX.TEXT = ROOT_EVENTS.ROOT_ENGINE.KEYBOARD.CAPTURE_CHAR;
//@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@

- 4,001
- 6
- 44
- 75