我有一个图像数组,我必须在画布中绘制它们作为网格,给定列。我使用以下函数来实现它,它接收网格将具有的列数,元素的索引,图像或精灵,位置(它将是每个元素的相同初始位置),以及之间的填充元素(对所有人来说都是一样的)。
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的快速演示,以显示我当前的aligmnent和期望的结果):https://jsfiddle.net/j4o3qxk0/
图像都是相同的,因此所有元素的宽度和填充相等,我需要用该函数计算每个元素的起点(左上角)的X坐标,但我还没想到它出来怎么做。你能帮我解决这个问题吗?
答案 0 :(得分:1)
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;
}
});
&#13;
* {
margin: 0;
padding: 0;
}
body {
display: flex;
}
canvas {
width: 100vw;
height: 100vh;
}
&#13;
<canvas></canvas>
&#13;