如果它们不适合所有空间,则连续居中

时间:2017-09-02 23:21:06

标签: javascript html5-canvas

我有一个图像数组,我必须在画布中绘制它们作为网格,给定列。我使用以下函数来实现它,它接收网格将具有的列数,元素的索引,图像或精灵,位置(它将是每个元素的相同初始位置),以及之间的填充元素(对所有人来说都是一样的)。

  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坐标,但我还没想到它出来怎么做。你能帮我解决这个问题吗?

1 个答案:

答案 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;
&#13;
&#13;