我有一个图像数组,我必须在给定列的画布上将它们绘制为网格。我使用以下函数来执行此操作,该函数接收网格将具有的列数,元素的索引,图像或精灵,位置(每个元素的初始位置都将是相同的初始位置)以及之间的填充元素(所有元素都相同)。
getImagePosition({ columns, i, sprite, position, padding }) {
const tempX = (i % columns);
const tempY = (i - tempX) / columns;
const x = ((padding.left + sprite.width) * tempX) + position.x;
const y = ((padding.top + sprite.height) * (tempY + 1)) + position.y;
return { x, y };
}
这会画出我的网格,但是如果没有足够的元素来容纳一行,则应将它们放置在中心位置,就像在这个小提琴中一样(这是一个使用flexbox的快速演示,以显示我当前的状态和期望的结果) :https://jsfiddle.net/j4o3qxk0/
图像都是相同的,因此所有元素的宽度和填充都相同,我需要使用该函数计算每个元素起点(左上角)的X坐标,但是我还没有弄清楚去做吧。你能帮我吗?
最佳答案
const finalRowEmptyCols = rows * cols - imgs.length;
const finalRowEndPadding = finalRowEmptyCols * (imgWidth + padding) / 2;
然后
finalRowEndPadding
表示您添加到最后一行的额外填充量。这意味着在您的函数中,您将需要绘制的图像总数,首先,您可以计算出额外的填充量,其次,您可以知道绘制最终行的时间,从而可以添加额外的填充。这是一个工作片段,以防它有助于解释我的意思:
function generateTestImages(count, width, height) {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const context = canvas.getContext('2d');
const testImages = [];
for (let itr = 0; itr < count; ++itr) {
context.fillStyle = '#' + Math.ceil((Math.random() * Math.pow(255, 3))).toString(16);
context.fillRect(0, 0, width, height);
testImages.push(context.getImageData(0, 0, width, height));
}
return testImages;
}
const padding = 10;
const imgWidth = 110;
const imgHeight = 110;
const imgs = generateTestImages(33, imgWidth, imgHeight);
const canvasWidth = 700;
let minimumRowWidth = padding * 2 + imgWidth;
let cols = 1;
while (minimumRowWidth + imgWidth + padding <= canvasWidth) {
minimumRowWidth += imgWidth + padding;
++cols;
}
const rowEndPadding = (canvasWidth - minimumRowWidth) / 2;
const rows = Math.ceil(imgs.length / cols);
const canvasHeight = rows * (imgHeight + padding) + padding;
const finalRowEmptyCols = rows * cols - imgs.length;
const finalRowEndPadding = finalRowEmptyCols * (imgWidth + padding) / 2;
const canvas = document.querySelector('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const context = canvas.getContext('2d');
context.fillStyle = 'black';
context.fillRect(0, 0, canvasWidth, canvasHeight);
let xx = rowEndPadding + padding;
let yy = padding;
let col = 0;
let row = 0;
imgs.forEach(img => {
context.putImageData(img, xx, yy);
xx += imgWidth + padding;
++col;
if (col >= cols) {
col = 0;
xx = padding + rowEndPadding;
if (++row === rows - 1) {
xx += finalRowEndPadding;
}
yy += padding + imgHeight;
}
});
* {
margin: 0;
padding: 0;
}
body {
display: flex;
}
canvas {
width: 100vw;
height: 100vh;
}
<canvas></canvas>