使用双上下文获取 canvas 上的真实鼠标位置
Get the real mouse location on a canvas with double context
有人要求我在 html5 使用 canvas 制作的游戏中获取鼠标坐标。
作为第一个测试,尝试使用以下函数读取鼠标位置。但是此函数仅读取鼠标位置,同时考虑到 canvas.
的尺寸
发生的事情是游戏的舞台比 canvas 大,这个功能没有显示角色在舞台上的真实位置。
我正在搜索并注意到 behind”canvas 存在于地图 (.png) 中,其像素尺寸已经确定。 canvas 像照相机一样工作,可以看到地图的一部分。
是否可以调整我的函数以读取地图的尺寸,然后定位玩家的实际坐标?
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
canvas.addEventListener("click", function(e) {
var cRect = canvas.getBoundingClientRect();
var scaleX = canvas.width / cRect.width;
var scaleY = canvas.height / cRect.height;
var canvasX = Math.round((e.clientX - cRect.left) * scaleX);
var canvasY = Math.round((e.clientY - cRect.top) * scaleY);
console.log("X: "+canvasX+", Y: "+canvasY);
});
这个函数只会根据canvas的大小给我鼠标的位置,但是地图更大,我在这里留下一张解释性的图片。
希望你理解我的意思。提前致谢。
世界 <=> 查看
要建立白话,使用的术语是
- World:world/playfield/(红框)的坐标系(以像素为单位)。
- View:canvas/camera/(蓝框)的坐标系(单位canvas像素)。
正如评论中指出的那样。您需要视图原点。也就是世界space.
中canvas左上角的坐标
您还需要了解视图比例。这就是 canvas 相对于世界的大小。
所需信息
const world = {width: 2048, height: 1024}; // Red box in pixels
const view = { // blue box
origin: {x: 500, y: 20}, // in world scale (pixels on world)
scale: {width: 1, height: 1}, // scale of pixels (from view to world)
}
没有此信息,您无法进行转换。它必须存在,因为它需要将世界内容渲染到 canvas。
请注意 如果比例为 1
,则只能在 canvas 渲染系统中推断。如果找不到比例尺,请使用 1
.
注意这个答案假设没有旋转视图。
查看 => 世界
以下函数将从视图坐标转换为世界坐标。
function viewToWorld(x, y) { // x,y pixel coordinates on canvas
return {
x: x * view.scale.width + view.origin.x,
y: y * view.scale.height + view.origin.y
}; // return x,y pixel coordinates in world
}
在客户端为 canvas
的鼠标事件中使用
function mouseEvent(event) {
// get world (red box) coords
const worldCoord = viewToWorld(event.clientX, event.clientY);
// normalize
worldCoord.x /= world.width;
worldCoord.y /= world.height;
}
世界 => 查看
您可以反向转换。即通过以下函数从世界坐标移动到视图坐标。
function normalWorldToView(x, y) { // x,y normalized world coordinates
return {
x: (x * world.width - view.origin.x) / view.scale.width,
y: (y * world.height - view.origin.y) / view.scale.height
}; // return x,y pixel on canvas (view)
}
以像素为单位
function worldToView(x, y) { // x,y world coordinates in pixels
return {
x: (x - view.origin.x) / view.scale.width,
y: (y - view.origin.y) / view.scale.height
}; // return x,y pixel on canvas (view)
}
有人要求我在 html5 使用 canvas 制作的游戏中获取鼠标坐标。 作为第一个测试,尝试使用以下函数读取鼠标位置。但是此函数仅读取鼠标位置,同时考虑到 canvas.
的尺寸发生的事情是游戏的舞台比 canvas 大,这个功能没有显示角色在舞台上的真实位置。
我正在搜索并注意到 behind”canvas 存在于地图 (.png) 中,其像素尺寸已经确定。 canvas 像照相机一样工作,可以看到地图的一部分。
是否可以调整我的函数以读取地图的尺寸,然后定位玩家的实际坐标?
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
canvas.addEventListener("click", function(e) {
var cRect = canvas.getBoundingClientRect();
var scaleX = canvas.width / cRect.width;
var scaleY = canvas.height / cRect.height;
var canvasX = Math.round((e.clientX - cRect.left) * scaleX);
var canvasY = Math.round((e.clientY - cRect.top) * scaleY);
console.log("X: "+canvasX+", Y: "+canvasY);
});
这个函数只会根据canvas的大小给我鼠标的位置,但是地图更大,我在这里留下一张解释性的图片。
希望你理解我的意思。提前致谢。
世界 <=> 查看
要建立白话,使用的术语是
- World:world/playfield/(红框)的坐标系(以像素为单位)。
- View:canvas/camera/(蓝框)的坐标系(单位canvas像素)。
正如评论中指出的那样。您需要视图原点。也就是世界space.
中canvas左上角的坐标您还需要了解视图比例。这就是 canvas 相对于世界的大小。
所需信息
const world = {width: 2048, height: 1024}; // Red box in pixels
const view = { // blue box
origin: {x: 500, y: 20}, // in world scale (pixels on world)
scale: {width: 1, height: 1}, // scale of pixels (from view to world)
}
没有此信息,您无法进行转换。它必须存在,因为它需要将世界内容渲染到 canvas。
请注意 如果比例为 1
,则只能在 canvas 渲染系统中推断。如果找不到比例尺,请使用 1
.
注意这个答案假设没有旋转视图。
查看 => 世界
以下函数将从视图坐标转换为世界坐标。
function viewToWorld(x, y) { // x,y pixel coordinates on canvas
return {
x: x * view.scale.width + view.origin.x,
y: y * view.scale.height + view.origin.y
}; // return x,y pixel coordinates in world
}
在客户端为 canvas
的鼠标事件中使用function mouseEvent(event) {
// get world (red box) coords
const worldCoord = viewToWorld(event.clientX, event.clientY);
// normalize
worldCoord.x /= world.width;
worldCoord.y /= world.height;
}
世界 => 查看
您可以反向转换。即通过以下函数从世界坐标移动到视图坐标。
function normalWorldToView(x, y) { // x,y normalized world coordinates
return {
x: (x * world.width - view.origin.x) / view.scale.width,
y: (y * world.height - view.origin.y) / view.scale.height
}; // return x,y pixel on canvas (view)
}
以像素为单位
function worldToView(x, y) { // x,y world coordinates in pixels
return {
x: (x - view.origin.x) / view.scale.width,
y: (y - view.origin.y) / view.scale.height
}; // return x,y pixel on canvas (view)
}