与响应鼠标事件相比,响应Canvas键盘事件没有那么直接,因为Canvas本身并不支持键盘事件的响应。我们需要耍一点小手段——在Canvas上添加一个支持键盘事件的其他对象。
创建canvas_kebord.cc:
#ifndef EM_PORT_API
#if defined(__EMSCRIPTEN__)
#include <emscripten.h>
#if defined(__cplusplus)
#define EM_PORT_API(rettype) extern "C" rettype EMSCRIPTEN_KEEPALIVE
#else
#define EM_PORT_API(rettype) rettype EMSCRIPTEN_KEEPALIVE
#endif
#else
#if defined(__cplusplus)
#define EM_PORT_API(rettype) extern "C" rettype
#else
#define EM_PORT_API(rettype) rettype
#endif
#endif
#endif
#include <stdio.h>
EM_PORT_API(void) on_key_down(const char* key) {
printf("on_key_down(); key:%s\n", key);
}
编译canvas_kebord.cc文件:
emcc code/1213/canvas_keybord.cc -s "EXPORTED_RUNTIME_METHODS=['ccall']" -o code/1213/canvas_keybord.js
创建canvas_kebord.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="myCanvas" tabindex="0"></canvas>
<script>
Module = {};
Module.onRuntimeInitialized = function () {
var image = new Image();
image.src = "cover.png";
image.onload = function () {
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
var img_data = ctx.getImageData(0, 0, image.width, image.height).data;
canvas.focus();
canvas.addEventListener("keydown", onKeyDown, true);
}
}
function getPointOnCanvas(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: x - bbox.left * (canvas.width / bbox.width),
y: y - bbox.top * (canvas.height / bbox.height)
};
}
function onKeyDown (event) {
Module.ccall('on_key_down', null, ['string'], [event.key]);
}
</script>
<script src="canvas_keybord.js"></script>
</body>
</html>
由于canvas无法直接照顾支持键盘事件,这里使用特殊方式实现。
// 有效
canvas.addEventListener('click', (e) => {
console.log('触发点击了')
})
// 无效
canvas.addEventListener('keydown', (e) => {
console.log('触发按键了')
})
给canvas一个tabindex,并设置为0或者更大的值,让canvas处于聚焦状态(canvas.focus()),这样就能向它绑定键盘事件了。
浏览器中运行canvas_kebord.html:
控制台成功输出对应键盘事件。