使用 css 缩放和 contain:fit 获取 canvas 点击坐标
Get canvas click coordinates with css scaling and contain:fit
对于我的像素艺术网站,我有一个相对于视口固定的 canvas,使用 css 缩放,并且有 object-fit:contain;使其保持 div 的大小,无论内部绘制或调整大小。
我需要获取鼠标点击坐标 而无需缩放 。 e.y/e.x 收集的缩放坐标不会有用,因为 object-fit:contain;会改变纵横比。
这里有一些虚拟代码可以更好地解释我的问题:
var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');
c.height = 16; // varaible height
c.width = 16; // varaible width
for (var x = 0; x < c.width; x++) {
for (var y = 0; y < c.height; y++) {
ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
}
}
c.addEventListener('click', function(e) {
//this is what i need help with, clickX and clickY need to give the pixel coordinates of the canvas, not the screen
let clickX = e.x - this.offsetLeft;
let clickY = e.y - this.offsetTop;
console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
width: 50vw;
height: 50vh;
image-rendering: pixelated;
object-fit: contain;
background-color: black;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>
</body>
</html>
应该是这样的吗?我采用“像素”单元格坐标。
var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');
c.height = 16; // varaible height
c.width = 16; // varaible width
for (var x = 0; x < c.width; x++) {
for (var y = 0; y < c.height; y++) {
ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
}
}
c.addEventListener('click', function(e) {
let realWidth = c.getBoundingClientRect().width;
let realHeight = c.getBoundingClientRect().height;
let cellSize = (realWidth < realHeight) ? realWidth/16 : realHeight/16;
let clickX = Math.floor((e.x - this.offsetLeft - (realWidth - cellSize*16)/2)/cellSize);
let clickY = Math.floor((e.y - this.offsetTop - (realHeight - cellSize*16)/2)/cellSize);
console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
width: 50vw;
height: 50vh;
image-rendering: pixelated;
object-fit: contain;
background-color: black;
}
<canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>
对于我的像素艺术网站,我有一个相对于视口固定的 canvas,使用 css 缩放,并且有 object-fit:contain;使其保持 div 的大小,无论内部绘制或调整大小。 我需要获取鼠标点击坐标 而无需缩放 。 e.y/e.x 收集的缩放坐标不会有用,因为 object-fit:contain;会改变纵横比。
这里有一些虚拟代码可以更好地解释我的问题:
var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');
c.height = 16; // varaible height
c.width = 16; // varaible width
for (var x = 0; x < c.width; x++) {
for (var y = 0; y < c.height; y++) {
ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
}
}
c.addEventListener('click', function(e) {
//this is what i need help with, clickX and clickY need to give the pixel coordinates of the canvas, not the screen
let clickX = e.x - this.offsetLeft;
let clickY = e.y - this.offsetTop;
console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
width: 50vw;
height: 50vh;
image-rendering: pixelated;
object-fit: contain;
background-color: black;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>
</body>
</html>
应该是这样的吗?我采用“像素”单元格坐标。
var c = document.getElementById("scaledCanvas");
var ctx = c.getContext('2d');
c.height = 16; // varaible height
c.width = 16; // varaible width
for (var x = 0; x < c.width; x++) {
for (var y = 0; y < c.height; y++) {
ctx.fillStyle = "#" + Math.floor(Math.random() * 16777215).toString(16); // pick random color
ctx.fillRect(x, y, 1, 1); // draw pixel on canvas
}
}
c.addEventListener('click', function(e) {
let realWidth = c.getBoundingClientRect().width;
let realHeight = c.getBoundingClientRect().height;
let cellSize = (realWidth < realHeight) ? realWidth/16 : realHeight/16;
let clickX = Math.floor((e.x - this.offsetLeft - (realWidth - cellSize*16)/2)/cellSize);
let clickY = Math.floor((e.y - this.offsetTop - (realHeight - cellSize*16)/2)/cellSize);
console.log(clickX + ", " + clickY);
}, false);
#scaledCanvas {
width: 50vw;
height: 50vh;
image-rendering: pixelated;
object-fit: contain;
background-color: black;
}
<canvas id="scaledCanvas" width="16" height="16">Canvas Not Supported</canvas>