From dc87b7245638255cfdc76ac4e895b22903b2e68b Mon Sep 17 00:00:00 2001 From: Robert Long Date: Wed, 25 Aug 2021 12:35:16 -0700 Subject: [PATCH] Constrain tiles using aspect ratios and bounding boxes --- src/VideoGrid.jsx | 157 ++++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 53 deletions(-) diff --git a/src/VideoGrid.jsx b/src/VideoGrid.jsx index e3344f5..b86c03e 100644 --- a/src/VideoGrid.jsx +++ b/src/VideoGrid.jsx @@ -38,31 +38,56 @@ function getTilePositions(tileCount, gridBounds) { const newTilePositions = []; const { width: gridWidth, height: gridHeight } = gridBounds; const gap = 8; - let paddingLeft = 8; - let paddingTop = 8; if (tileCount > 12) { console.warn("Over 12 tiles is not currently supported"); } if (tileCount > 0) { - const aspectRatio = gridWidth / gridHeight; + const gridAspectRatio = gridWidth / gridHeight; let columnCount, rowCount; + let tileAspectRatio = 16 / 9; - if (aspectRatio < 1) { - if (tileCount <= 4) { + if (gridAspectRatio < 3 / 4) { + // Phone + if (tileCount === 1) { + columnCount = 1; + rowCount = 1; + tileAspectRatio = 0; + } else if (tileCount <= 4) { columnCount = 1; rowCount = tileCount; } else if (tileCount <= 12) { columnCount = 2; - rowCount = Math.ceil(tileCount / 2); + rowCount = Math.ceil(tileCount / columnCount); + tileAspectRatio = 0; } else { // Unsupported columnCount = 3; - rowCount = Math.ceil(tileCount / 2); + rowCount = Math.ceil(tileCount / columnCount); + tileAspectRatio = 1; } - } else { + } else if (gridAspectRatio < 1) { + // Tablet + if (tileCount === 1) { + columnCount = 1; + rowCount = 1; + tileAspectRatio = 0; + } else if (tileCount <= 4) { + columnCount = 1; + rowCount = tileCount; + } else if (tileCount <= 12) { + columnCount = 2; + rowCount = Math.ceil(tileCount / columnCount); + } else { + // Unsupported + columnCount = 3; + rowCount = Math.ceil(tileCount / columnCount); + tileAspectRatio = 1; + } + } else if (gridAspectRatio < 17 / 9) { + // Computer if (tileCount === 1) { columnCount = 1; rowCount = 1; @@ -78,8 +103,32 @@ function getTilePositions(tileCount, gridBounds) { } else if (tileCount <= 8) { columnCount = 4; rowCount = 2; - } else if (tileCount <= 10) { - columnCount = 5; + tileAspectRatio = 1; + } else if (tileCount <= 12) { + columnCount = 4; + rowCount = 3; + tileAspectRatio = 1; + } else { + // Unsupported + columnCount = 4; + rowCount = 4; + } + } else if (gridAspectRatio <= 32 / 9) { + // Ultrawide + if (tileCount === 1) { + columnCount = 1; + rowCount = 1; + } else if (tileCount === 2) { + columnCount = 2; + rowCount = 1; + } else if (tileCount <= 4) { + columnCount = 2; + rowCount = 2; + } else if (tileCount <= 6) { + columnCount = 3; + rowCount = 2; + } else if (tileCount <= 8) { + columnCount = 4; rowCount = 2; } else if (tileCount <= 12) { columnCount = 4; @@ -89,76 +138,78 @@ function getTilePositions(tileCount, gridBounds) { columnCount = 4; rowCount = 4; } + } else { + // Super Ultrawide + if (tileCount <= 6) { + columnCount = tileCount; + rowCount = 1; + } else { + columnCount = Math.ceil(tileCount / 2); + rowCount = 2; + } } - const maxTileHeight = Math.round( - (gridHeight - gap * (rowCount + 1)) / rowCount - ); - const maxTileWidth = Math.round( + const boxWidth = Math.round( (gridWidth - gap * (columnCount + 1)) / columnCount ); + const boxHeight = Math.round( + (gridHeight - gap * (rowCount + 1)) / rowCount + ); - // TODO Constrain Aspect + let tileWidth, tileHeight; - let tileHeight = maxTileHeight; - let tileWidth = maxTileWidth; + if (tileAspectRatio) { + const boxAspectRatio = boxWidth / boxHeight; - const tileAspectRatio = tileWidth / tileHeight; - - if (aspectRatio < 1) { - if (tileCount === 1) { - tileHeight = maxTileHeight; - tileWidth = maxTileWidth; - } else if (tileCount <= 4) { - tileHeight = Math.round((maxTileWidth * 9) / 16); + if (boxAspectRatio > tileAspectRatio) { + tileWidth = boxHeight * tileAspectRatio; + tileHeight = boxHeight; } else { - tileHeight = tileWidth; + tileWidth = boxWidth; + tileHeight = boxWidth / tileAspectRatio; } } else { + tileWidth = boxWidth; + tileHeight = boxHeight; } - const totalHeight = tileHeight * rowCount + gap * (rowCount - 1); - - if (totalHeight > gridHeight) { - const overflow = totalHeight - gridHeight; - tileHeight = Math.round(tileHeight - overflow / rowCount); - } - - // if (tileAspectRatio > 16 / 9) { - // tileWidth = (16 * tileHeight) / 9; - // } - - paddingTop = + const paddingTop = (gridHeight - tileHeight * rowCount - gap * (rowCount - 1)) / 2; - paddingLeft = + const paddingLeft = (gridWidth - tileWidth * columnCount - gap * (columnCount - 1)) / 2; for (let i = 0; i < tileCount; i++) { const verticalIndex = Math.floor(i / columnCount); const top = verticalIndex * tileHeight + verticalIndex * gap + paddingTop; - console.log(top); - let rowItemCount; - if (verticalIndex + 1 === rowCount && tileCount % rowCount !== 0) { - rowItemCount = Math.floor(tileCount / rowCount); + if (verticalIndex + 1 === rowCount && tileCount % columnCount !== 0) { + rowItemCount = tileCount % columnCount; } else { - rowItemCount = Math.ceil(tileCount / rowCount); + rowItemCount = columnCount; } const horizontalIndex = i % columnCount; - const totalRowGapWidth = (rowItemCount + 1) * gap; - const totalRowTileWidth = rowItemCount * tileWidth; - const rowLeftMargin = Math.round( - (gridWidth - (totalRowTileWidth + totalRowGapWidth)) / 2 - ); + + let centeringPadding = 0; + + if (rowItemCount < columnCount) { + centeringPadding = Math.round( + (gridWidth - + (tileWidth * rowItemCount + + (gap * rowItemCount - 1) + + paddingLeft * 2)) / + 2 + ); + } + const left = - tileWidth * horizontalIndex + - rowLeftMargin + - horizontalIndex * gap + - paddingLeft; + paddingLeft + + centeringPadding + + gap * horizontalIndex + + tileWidth * horizontalIndex; newTilePositions.push({ width: tileWidth,