我有一个上下文,我在其中绘制了几个矩形。然后上下文应用了转换,将其变成平面图的 3D 幻觉。
我正在尝试创建一个公式来计算光标悬停在哪个坐标上,而不使用 Path2D。这是因为我需要能够计算它是什么坐标,即使没有绘制图 block ,而是无论如何都在网格上。
转换矩阵有一个...
水平
- 缩放
1.0
- 倾斜
0.5
(columns * 32)
的移动(列数:6)
- 缩放
垂直
- 缩放
0.5
- 倾斜
-1.0
- 移动
0
- 缩放
在Real mouse position in canvas的帮助下的回答,我相信我在正确的道路上,但是,当鼠标向下和向左移动时,尽管在同一列上,列也会减少。向右下行时,尽管在同一行,行也会减少。
const rows = 10;
const columns = 6;
const $coordinate = $("#coordinate");
const $canvas = $("#canvas");
canvas.width = (rows * 32) + (columns * 32);
canvas.height = (rows * 16) + (columns * 16);
const context = $canvas[0].getContext("2d");
context.imageSmoothingEnabled = false;
context.save();
context.fillStyle = "white";
context.setTransform(1, 0.5, -1, 0.5, (columns * 32), 0);
// (a) horizontal scaling: 1
// (b) horizontal skewing: 0.5
// (c) vertical skewing: -1
// (d) vertical scaling: 0.5
// (e) horizontal moving: (columns * 32)
// (f) vertical moving: 0
const matrix = {
vertical: {
scaling: 1.0,
skewing: 0.5,
moving: (columns * 32)
},
horizontal: {
scaling: 0.5,
skewing: -1,
moving: 0
}
};
for(let row = 0; row < rows; row++) {
for(let column = 0; column < columns; column++) {
context.rect(row * 32, column * 32, 31.5, 31.5);
}
}
context.fill();
$canvas.mousemove(function(e) {
const position = {
left: e.pageX - $canvas.offset().left,
top: e.pageY - $canvas.offset().top
};
const innerPosition = {
left: position.left * matrix.horizontal.scaling + position.top * matrix.vertical.skewing + matrix.horizontal.moving,
top: position.left * matrix.horizontal.skewing + position.top * matrix.vertical.scaling + matrix.vertical.moving
};
const coordinate = {
row: Math.trunc(innerPosition.top / 32),
column: Math.trunc(innerPosition.left / 32)
};
$coordinate.html(coordinate.row + "x" + coordinate.column);
});
#canvas {
background: green;
}
#coordinate {
position: absolute;
font-family: Arial, sans-serif;
font-size: 16px;
left: 12px;
top: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>
<div id="coordinate">0x0</div>
我没有使用任何框架(但 JQuery 除外,与问题无关)。我怎样才能计算出准确的坐标?
最佳答案
您对 setTransform(a, b, c, d, e, f)
的调用创建了一个 3x3 仿射变换矩阵:
| a c e |
| b d f |
| 0 0 1 |
给定您当前的值 (1, 0.5, -1, 0.5, n, 0) 有一个逆矩阵:
| 0.5 1 -n/2 |
| -0.5 1 +n/2 |
| 0 0 1 |
将该变换矩阵应用于您的鼠标坐标(需要表示为 1x3 矩阵 [x, y, 1]
应该提供所需的网格坐标:
const rows = 10;
const columns = 6;
const $coordinate = $("#coordinate");
const $canvas = $("#canvas");
canvas.width = (rows * 32) + (columns * 32);
canvas.height = (rows * 16) + (columns * 16);
const context = $canvas[0].getContext("2d");
context.imageSmoothingEnabled = false;
context.save();
context.fillStyle = "white";
context.setTransform(1, 0.5, -1, 0.5, (columns * 32), 0);
// (a) horizontal scaling: 1
// (b) horizontal skewing: 0.5
// (c) vertical skewing: -1
// (d) vertical scaling: 0.5
// (e) horizontal moving: (columns * 32)
// (f) vertical moving: 0
for(let row = 0; row < rows; row++) {
for(let column = 0; column < columns; column++) {
context.rect(row * 32, column * 32, 31.5, 31.5);
}
}
context.fill();
$canvas.mousemove(function(e) {
const position = {
left: e.pageX - $canvas.offset().left,
top: e.pageY - $canvas.offset().top
};
const innerPosition = {
left: position.left * 0.5 + position.top - (columns * 32) / 2,
top: position.left * -0.5 + position.top + (columns * 32) / 2
};
const coordinate = {
row: Math.floor(innerPosition.top / 32),
column: Math.floor(innerPosition.left / 32)
};
$coordinate.html(coordinate.row + "x" + coordinate.column);
});
#canvas {
background: green;
}
#coordinate {
position: absolute;
font-family: Arial, sans-serif;
font-size: 16px;
left: 12px;
top: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>
<div id="coordinate">0x0</div>
关于javascript - 如何从转换后的楼层 map 中正确计算坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63004060/