For the Canvas element, it supports all mouse events in javascript, but does not work if you listen for keyboard events.
/ / effective
canvas.addEventListener('click'.(e) = > {
console.log('Triggered click')})/ / is invalid
canvas.addEventListener('keydown'.(e) = > {
console.log('Button triggered')})Copy the code
The reason for this is that keyboard input events only occur on HTML elements that currently have focus. If no element has focus, the event will be moved up to Windows and Document objects, so there are two common ways to solve this problem:
-
If canvas element is basically the same length and width as Windows, keyboard events can be bound to Windows objects to replace the monitoring and processing of Canvas element.
window.addEventListener('keydown', doKeyDown, true) Copy the code
-
Leave the Canvas element in focus and bind keyboard events to it.
<canvas tabindex="0"></canvas> Copy the code
Set tabIndex to 0 or greater.
The following is a detailed example of the second method:
<! -- HTML section -->
<canvas id="canvas" tabindex="0"></canvas>
Copy the code
/ / js parts
const canvas = document.getElementById('canvas')
canvas.focus()
canvas.addEventListener('keydown'.(e) = > {
console.log(`keyCode: ${e.keyCode}`)})Copy the code
This allows the canvas to be in focus at the beginning and keyboard input events accordingly.
However, tabIndex focused elements will have a default outer box that indicates that the element is in focus. If you do not want to display the outer box, you can use CSS styles to remove it:
canvas:focus {
outline:none;
}
Copy the code
You can write a practical application to test this, such as using the keyboard keys up, down, left, or WSAD to manipulate a small square and move it around the Canvas.
<! -- HTML section -->
<canvas id="canvas" tabindex="0"></canvas>
<! -- CSS section -->
<style>
#canvas{
width: 100vw;
height: 100vh;
background-color: #4ab7bd;
}
#canvas:focus{
outline: none;
}
</style>
<! -- js part -->
<script>
window.onload = function() {
// The width of the canvas
const canvas = document.getElementById('canvas')
const canvasWidth = canvas.clientWidth
const canvasHeight = canvas.clientHeight
// The length and width of the squares moving on the canvas
const [rectWidth, rectHeight] = [40.40]
// The horizontal and vertical coordinates of the box
let [rectX, rectY] = [0.0]
/ / initialization
canvas.width = canvasWidth
canvas.height = canvasHeight
let context = canvas.getContext('2d')
// Set the color and initial coordinates (center point) of the block, draw
context.fillStyle = 'red'
rectX = (canvasWidth - rectWidth) / 2
rectY = (canvasHeight - rectHeight) / 2
context.fillRect(rectX, rectY, rectWidth, rectHeight)
// The canvas element listens for keyboard input events
canvas.addEventListener('keydown', doKeyDown, true)
canvas.focus() // Let canvas focus
function clearCanvas() {
context.clearRect(0.0, canvasWidth, canvasHeight)
}
function doKeyDown(e) {
/ / get the keyCode
const keyCode = e.keyCode ? e.keyCode : e.which
// Up arrow/w, move the ordinate up 10
if (keyCode === 38 || keyCode === 87) {
clearCanvas()
rectY -= 10
if (rectY < 0) {
rectY = 0
}
context.fillRect(rectX, rectY, rectWidth, rectHeight)
}
// Down arrow/s, move the ordinate down 10
if (keyCode === 40 || keyCode === 83) {
clearCanvas()
rectY += 10
if (rectY > canvasHeight - rectHeight) {
rectY = canvasHeight - rectHeight
}
context.fillRect(rectX, rectY, rectWidth, rectHeight)
}
// Arrow to the left/a, move the ordinate to the left by 10
if (keyCode === 37 || keyCode === 65) {
clearCanvas()
rectX -= 10
if (rectX < 0) {
rectX = 0
}
context.fillRect(rectX, rectY, rectWidth, rectHeight)
}
// Go to the right arrow/d and move the ordinate 10 to the right
if (keyCode === 39 || keyCode === 68) {
clearCanvas()
rectX += 10
if (rectX > canvasWidth - rectWidth) {
rectX = canvasWidth - rectWidth
}
context.fillRect(rectX, rectY, rectWidth, rectHeight)
}
}
}
</script>
Copy the code
When the Canvas element is in focus state, it can listen to keyboard events; when it loses focus, it will also lose keyboard listening.
We can develop canvas mini-games based on this, such as Snake, box pushing, maze running, shooting, Tetris, etc.