Tom
Tom

Reputation: 6697

Forward keyboard keydown events from html5 textbox to game canvas

How can I forward all keyboard key hits that mobile browser needs to send to textbox, into my game canvas?

I had to add this kind of inputbox below my game just so that inputbox triggers keyboard on mobile phone screen, and game works ok in iPhone, but not in Android. Game works with physical keyboard of course.

<input value="click here" style="font-size: 22px;" autocorrect="off" autofocus type='text' id='foo'><div onclick='$("#foo").focus();'>click here</div>

Upvotes: 0

Views: 332

Answers (1)

user5734311
user5734311

Reputation:

Since it's apparently not possible to forward the original event, my approach was to create my own and dispatch it to the canvas. To hide the fact that the user is tapping on an <input> I put a button on top and made it ignore pointer events. I also have to keep a character in the text field at all times to prevent the Android keyboard from going back to capital letters.

const canvas = document.querySelector("#app canvas");
const link = document.querySelector("#app a");
const input = document.querySelector("#app input");
const output = document.querySelector("#app pre");

canvas.addEventListener("keydown", e => {
  // console.log("key:", e.key);
  output.textContent += e.key;
});

input.addEventListener("focus", function() {
  setTimeout(() => {
    link.style.display = "none";
    input.value = "a";
  }, 0);
});

input.addEventListener("keyup", function(e) {
  const key = this.value[1];
  const keyCode = key && key.charCodeAt(0);
  const ev = new KeyboardEvent("keydown", {
    key,
    keyCode
  });
  canvas.dispatchEvent(ev);
  setTimeout(() => {
    input.value = "a";
  }, 0);
});
body {
  font-family: sans-serif;
  text-align: center;
}

canvas {
  display: block;
  box-shadow: 0 0 5px 0 black;
  width: 60%;
  margin: 0 auto;
  height: 120px;
}

#app {
  position: relative;
}

#textfield {
  position: absolute;
  left: 0;
  width: 100%;
  top: 40%;
  text-align: center;
}

#textfield * {
  width: 70px;
  height: 40px;
  position: absolute;
  margin-left: -35px;
}

#textfield a {
  color: white;
  border-radius: 5px;
  background-color: red;
  box-sizing: border-box;
  padding: 0.5em;
  pointer-events: none;
  z-index: 1;
}

#textfield input {
  cursor: pointer;
  width: 70px;
  opacity: 0;
}
<div id="app">
  <canvas></canvas>
  <p id="textfield">
    <a href="">Play</a>
    <input />
  </p>
  Canvas keydown listener output:
  <pre></pre>
</div>

Upvotes: 1

Related Questions