JavaScript 的 drawContext 在数学上不正确
JavaScript's drawContext is not mathematically correct
我有一个使用 32x32 瓷砖的瓷砖集:
我将其绘制在 canvas 上以声称是 32x32 的瓷砖地图。但是,似乎数学不正确。为什么 canvas 绘制明显不在 32x32 范围内的图块?
例如:
如您所见,canvas 的 32x32 网格的左上角应该是一个图块...但是它被截断了:
const appDiv = document.getElementById('app');
const tileSize = 32;
const canvasSize = 480; // 32 (tiles) * 15 (columns) = 480 pixels
const tilesAcross = canvasSize / tileSize; // (Size of Canvas [480] / Tile size [32]) = 15 columns
appDiv.innerHTML = `<h2>Canvas</h2><canvas id="map" width="${canvasSize}" height="${canvasSize}">`;
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
resizeCanvas();
// Regenerate map on resize
window.onresize = resizeCanvas;
function resizeCanvas() {
const ctx = document.getElementById('map').getContext('2d');
const image = new Image();
image.src = 'https://i.postimg.cc/k4KBLBJh/terrain.png'; // Tileset
image.onload = () => {
for (let column = 0; column < tilesAcross; column++) {
for (let row = 0; row < tilesAcross; row++) {
ctx.drawImage(
image, // Image elemnt
randomIntFromInterval(0, 5) * 32, // sx - The x-axis of top left corner of the rect of the image to draw into context.
randomIntFromInterval(0, 5) * 32, // sy - The y-axis of top left corner of the rect of the image to draw into context.
32, // sWidth - The width of the rect of the image to draw into context.
32, // sHeight - The height of the rect of the image to draw into the destination context.
row * 32, // dx - The x-axis coordinate in the canvas at which to place the top-left corner of the image.
column * 32, // dy - The y-axis coordinate in the canvas at which to place the top-left corner of the image.
32, // dWidth - The width to draw the image in the canvas. This allows scaling of the drawn image.
32 // dHeight- The width to draw the image in the canvas. This allows scaling of the drawn image.
);
}
}
};
}
canvas {
background: black;
}
<div id="app"></div>
<style src="./style.css"></style>
您图像中的图块不是 32x32px
,更像是 28.56px
。
我认为您需要重新渲染 spritesheet。你不会对这个感到满意,因为你总是会在边缘处有线条,其中一个 row/column 两个图块的像素已被插值。
如果拉伸它们,它们会变得模糊。
const appDiv = document.getElementById('app');
const tileSize = 32;
const canvasSize = 480; // 32 (tiles) * 15 (columns) = 480 pixels
const tilesAcross = canvasSize / tileSize; // (Size of Canvas [480] / Tile size [32]) = 15 columns
appDiv.innerHTML = `<h2>Canvas</h2><canvas id="map" width="${canvasSize}" height="${canvasSize}">`;
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
resizeCanvas();
// Regenerate map on resize
window.onresize = resizeCanvas;
function resizeCanvas() {
const ctx = document.getElementById('map').getContext('2d');
const image = new Image();
image.src = 'https://i.postimg.cc/k4KBLBJh/terrain.png'; // Tileset
image.onload = () => {
const {naturalWidth, naturalHeight} = image;
const tileWidth = image.naturalWidth / 9;
const tileHeight = image.naturalHeight / 28;
console.log({
tileWidth,
tileHeight,
naturalWidth,
naturalHeight,
})
for (let column = 0; column < tilesAcross; column++) {
for (let row = 0; row < tilesAcross; row++) {
ctx.drawImage(
image, // Image elemnt
randomIntFromInterval(0, 5) * tileWidth, // sx - The x-axis of top left corner of the rect of the image to draw into context.
randomIntFromInterval(0, 5) * tileHeight, // sy - The y-axis of top left corner of the rect of the image to draw into context.
tileWidth, // sWidth - The width of the rect of the image to draw into context.
tileHeight, // sHeight - The height of the rect of the image to draw into the destination context.
row * 32, // dx - The x-axis coordinate in the canvas at which to place the top-left corner of the image.
column * 32, // dy - The y-axis coordinate in the canvas at which to place the top-left corner of the image.
32, // dWidth - The width to draw the image in the canvas. This allows scaling of the drawn image.
32 // dHeight- The width to draw the image in the canvas. This allows scaling of the drawn image.
);
}
}
};
}
canvas {
background: black;
}
<div id="app"></div>
<style src="./style.css"></style>
我有一个使用 32x32 瓷砖的瓷砖集:
我将其绘制在 canvas 上以声称是 32x32 的瓷砖地图。但是,似乎数学不正确。为什么 canvas 绘制明显不在 32x32 范围内的图块?
例如:
如您所见,canvas 的 32x32 网格的左上角应该是一个图块...但是它被截断了:
const appDiv = document.getElementById('app');
const tileSize = 32;
const canvasSize = 480; // 32 (tiles) * 15 (columns) = 480 pixels
const tilesAcross = canvasSize / tileSize; // (Size of Canvas [480] / Tile size [32]) = 15 columns
appDiv.innerHTML = `<h2>Canvas</h2><canvas id="map" width="${canvasSize}" height="${canvasSize}">`;
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
resizeCanvas();
// Regenerate map on resize
window.onresize = resizeCanvas;
function resizeCanvas() {
const ctx = document.getElementById('map').getContext('2d');
const image = new Image();
image.src = 'https://i.postimg.cc/k4KBLBJh/terrain.png'; // Tileset
image.onload = () => {
for (let column = 0; column < tilesAcross; column++) {
for (let row = 0; row < tilesAcross; row++) {
ctx.drawImage(
image, // Image elemnt
randomIntFromInterval(0, 5) * 32, // sx - The x-axis of top left corner of the rect of the image to draw into context.
randomIntFromInterval(0, 5) * 32, // sy - The y-axis of top left corner of the rect of the image to draw into context.
32, // sWidth - The width of the rect of the image to draw into context.
32, // sHeight - The height of the rect of the image to draw into the destination context.
row * 32, // dx - The x-axis coordinate in the canvas at which to place the top-left corner of the image.
column * 32, // dy - The y-axis coordinate in the canvas at which to place the top-left corner of the image.
32, // dWidth - The width to draw the image in the canvas. This allows scaling of the drawn image.
32 // dHeight- The width to draw the image in the canvas. This allows scaling of the drawn image.
);
}
}
};
}
canvas {
background: black;
}
<div id="app"></div>
<style src="./style.css"></style>
您图像中的图块不是 32x32px
,更像是 28.56px
。
我认为您需要重新渲染 spritesheet。你不会对这个感到满意,因为你总是会在边缘处有线条,其中一个 row/column 两个图块的像素已被插值。
如果拉伸它们,它们会变得模糊。
const appDiv = document.getElementById('app');
const tileSize = 32;
const canvasSize = 480; // 32 (tiles) * 15 (columns) = 480 pixels
const tilesAcross = canvasSize / tileSize; // (Size of Canvas [480] / Tile size [32]) = 15 columns
appDiv.innerHTML = `<h2>Canvas</h2><canvas id="map" width="${canvasSize}" height="${canvasSize}">`;
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
resizeCanvas();
// Regenerate map on resize
window.onresize = resizeCanvas;
function resizeCanvas() {
const ctx = document.getElementById('map').getContext('2d');
const image = new Image();
image.src = 'https://i.postimg.cc/k4KBLBJh/terrain.png'; // Tileset
image.onload = () => {
const {naturalWidth, naturalHeight} = image;
const tileWidth = image.naturalWidth / 9;
const tileHeight = image.naturalHeight / 28;
console.log({
tileWidth,
tileHeight,
naturalWidth,
naturalHeight,
})
for (let column = 0; column < tilesAcross; column++) {
for (let row = 0; row < tilesAcross; row++) {
ctx.drawImage(
image, // Image elemnt
randomIntFromInterval(0, 5) * tileWidth, // sx - The x-axis of top left corner of the rect of the image to draw into context.
randomIntFromInterval(0, 5) * tileHeight, // sy - The y-axis of top left corner of the rect of the image to draw into context.
tileWidth, // sWidth - The width of the rect of the image to draw into context.
tileHeight, // sHeight - The height of the rect of the image to draw into the destination context.
row * 32, // dx - The x-axis coordinate in the canvas at which to place the top-left corner of the image.
column * 32, // dy - The y-axis coordinate in the canvas at which to place the top-left corner of the image.
32, // dWidth - The width to draw the image in the canvas. This allows scaling of the drawn image.
32 // dHeight- The width to draw the image in the canvas. This allows scaling of the drawn image.
);
}
}
};
}
canvas {
background: black;
}
<div id="app"></div>
<style src="./style.css"></style>