addEventListener for keydown on Canvas
Edit - This answer is a solution, but a much simpler and proper approach would be setting the tabindex
attribute on the canvas element (as suggested by hobberwickey).
You can't focus a canvas element. A simple work around this, would be to make your "own" focus.
var lastDownTarget, canvas;
window.onload = function() {
canvas = document.getElementById('canvas');
document.addEventListener('mousedown', function(event) {
lastDownTarget = event.target;
alert('mousedown');
}, false);
document.addEventListener('keydown', function(event) {
if(lastDownTarget == canvas) {
alert('keydown');
}
}, false);
}
JSFIDDLE
keydown is not working when using addEventListener on Javascript
be informed that you can't bind keydow
directly to the canvas..bind it to the entire window instead
window.addEventListener("keydown", function, false);
How do I capture a keydown event on the canvas without interfering with the rest of my website?
You should check this other question:
addEventListener for keydown on Canvas
The fix was by caching the last focused element, and then asking if it's the canvas, then do something different.
Hope it works!
How to register onkeydown event for HTML5 canvas
As jing3142 has said, you can't listen for keyboard events on elements that are not designed for them.
However, you can force an element to be designed for them.
canvas.tabIndex = 1000;
Now you can use canvas.addEventListener
with keyboard events.
This is preferable over window.addEventListener
because then you don't interfere with any other elements on the page such as actual input elements.
Note that you may see a dotted outline in some browsers when the canvas has focus. To remove this:
canvas.style.outline = "none";
Have fun!
addEventListener('keydown') JavaScript bug?
Keyboard IO.
Generally IO events like the mouse, touch, and keyboards should only be used to get the current state of the devices they are listening to. The job of reacting to input is done in your game.
one way to handle keyboard input is as follows
// this defines what keys you are listening to and
// holds the current state of the key true for down false for up
const keys = {
ArrowUp : false, // list the keyboard keys you want to listen to
ArrowDown : false,
ArrowLeft : false,
ArrowRight : false,
};
// the event listener listens for key events
function keyEvents(e){
if(keys[e.code] !== undefined){ // check if its a key we are listening for
keys[e.code] = event.type === "keydown" ; // set the state up or down
e.preventDefault(); // stop default action
}
}
addEventListener("keyup",keyEvents); // set up the listeners
addEventListener("keydown",keyEvents);
Then in your game's main loop or called from there check the key state and perform the action that the state requires..
if (keys.ArrowDown) { player.y += 5 }
if (keys.ArrowUp) { player.y -= 5 }
if (keys.ArrowLeft) { player.x -= 5 }
if (keys.ArrowRight) { player.x += 5 }
addEventListener per element only
You can create separate keydown/click event for each of your input/canvas.
To get canvas to response to keydown you need to add tabindex="1"
.
Like so <canvas id="gameCanvas" tabindex="1"></canvas>
Both input and canvas will response to keyboard event when the right elements are selected and triggered when keys are pressed. If you prefer click event just replace keydown
with click
instead.
//js file gameCanvas = document.getElementById('gameCanvas'); conversation = document.getElementById('conversation');
gameCanvas.addEventListener("keydown", function(e){ console.log(gameCanvas); }, false);
conversation.addEventListener("keydown", function(e){ console.log(conversation); }, false);
#gameCanvas { background: blue; width: 100px; height: 100px; }
<p>gamecanvas</p><canvas id="gameCanvas" tabindex="1"></canvas><br /><p>conversation</p> <input id="conversation" type="text" tabindex="2"></input>
addEventListener keydown not working
You can't assign the keydown
event to the canvas because you can't focus the canvas with the cursor. You will need to assign the event to the window:
window.addEventListener("keydown", handle, true);
Trouble detecting keydown on canvas
You were pretty close!
You accidentally put canvas.addEventListener('keydown', playerMove, true); inside the playerMove function so the event listener was never being set up.
Also, you had a few missing braces and you need to trigger the onload event to run your functions (I put an init() trigger in your body tag).
Here is your code—slightly reworked:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<style>
body{
margin:0;
}
canvas {
border: solid 1px black;
position:relative;
}
#holder {
display:block;
margin: 100px auto 0 auto;
width:800px;
height:600px;
}
</style>
<script>
function init() {
console.log("start");
// define variables
var canvas, c;
var WIDTH;
var HEIGHT;
var INTERVAL = 20;
var mouseX, mouseY;
var mousePos;
// set up canvas
canvas = document.getElementById("canvas");
c = canvas.getContext("2d");
// initial canvas background
c.beginPath();
c.fillStyle = "rgb(45,133,222)";
c.rect(0,0,800,600);
c.fill();
c.closePath();
// Player coords and initial location
function Player () {
this.x = 400;
this.y = 300;
this.w = 20;
this.h = 20;
this.xcenter = 400;
this.ycenter = 300;
this.angle = 0.9;
this.fill = '#000000';
}
var Player1 = new Player();
// game loop interval
setInterval(mainDraw, INTERVAL);
// clear canvas function
function clear(c) {
c.clearRect(0, 0, WIDTH, HEIGHT);
}
// drawing function / game loop
function mainDraw(canvas, message) {
// get the angle between the player coords and the mouse coords
deltaX = mouseX - Player1.x;
deltaY = mouseY - Player1.y;
var newAngle = Math.atan(deltaY / deltaX);
// clear the canvas and draw the background again
clear(c);
c.beginPath();
c.fillStyle = "rgb(45,133,22)";
c.rect(0,0,800,600);
c.fill();
c.closePath();
// draw the player with the new angle so that it faces the mouse
c.beginPath();
c.save();
c.translate(Player1.x,Player1.y);
if (deltaX < 0) {
c.rotate(newAngle);
}
else {
c.rotate(newAngle);
c.scale(-1,1);
}
c.translate(-Player1.x,-Player1.y);
c.fillStyle = "#000000";
c.moveTo(Player1.x - 15, Player1.y);
c.lineTo(Player1.x + 15, Player1.y + 10);
c.lineTo(Player1.x + 15, Player1.y - 10);
c.lineTo(Player1.x - 15, Player1.y);
c.fill();
c.restore();
c.closePath();
}
// focus on the canvas on mouseover to detect key input
var handlefocus=function(e){
if(e.type=='mouseover')
{
canvas.focus(); return false;
}
else if (e.type=='mouseout')
{
canvas.blur(); return false;
}
return true;
};
canvas.addEventListener('mouseover',handlefocus,true);
// Detect mouse movement and assign to mouseX, mouseY
function mouseMove(e)
{
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
}
canvas.addEventListener('mousemove', mouseMove, true);
// Detect key press for movement
function playerMove(evt){
canvas.focus()
alert('keycode: ' + evt.keyCode);
{
if ( evt.keyCode == 87 ) {
Player1.y = Player1.y + 1;
}
if ( evt.keyCode == 83 ) {
Player1.y -= 1;
}
if ( evt.keyCode == 65 ) {
Player1.x -= 1;
}
if ( evt.keyCode == 68 ) {
Player1.x += 1;
}
return false;
}
}
canvas.addEventListener('keydown', playerMove, true);
}
</script>
</head>
<body onload="init()">
<div id = "holder">
<canvas id="canvas" width="800" height="600" tabindex='1'></canvas>
</div>
</body>
</html>
Related Topics
Angular 2: How to Detect Changes in an Array? (@Input Property)
Chrome Extension - How to Get Http Response Body
Replace a Regex Capture Group with Uppercase in JavaScript
JavaScript Syntax (0, Fn)(Args)
Javascript: How to Validate Dates in Format Mm-Dd-Yyyy
Keyword 'Const' Does Not Make the Value Immutable. What Does It Mean
How to Create Every Combination Possible for the Contents of Two Arrays
How to Convert Raw JavaScript Object to a Dictionary
Http Status Code 401 Even Though I'm Sending Credentials in the Request
How to Sequentially Run Promises with Q in JavaScript
Access JavaScript Nested Objects Safely
How to Implement a Stack and a Queue in JavaScript
How to Resolve Iframe Cross Domain Issue
How to Emulate an HTML Input "Maxlength" Attribute on an HTML Textarea
How to Submit 2 Forms in One Page with a Single Submit Button
Insert External Page HTML into a Page HTML
How to Run HTML Files Directly from Github, Instead of Just Viewing Their Source