diff --git a/source/view/demo/art/squares.liquid b/source/view/demo/art/squares.liquid index e10e247..a0975e2 100644 --- a/source/view/demo/art/squares.liquid +++ b/source/view/demo/art/squares.liquid @@ -29,40 +29,21 @@ tags: '#b7e0f0', '#52bed1', '#0c85ff' ]; - // Verify maxSquareSize and minSquareSize are powers of 2 - if (!isPowerOfTwo(maxSquareSize) || !isPowerOfTwo(minSquareSize)) { - console.error('Both maxSquareSize and minSquareSize must be powers of 2'); - return; - } - - if (minSquareSize > maxSquareSize) { - console.error('minSquareSize must be <= maxSquareSize'); - return; - } - - if (largeSquarePercentage < 0 || largeSquarePercentage > 100) { - console.error('largeSquarePercentage must be between 0 and 100'); - return; - } - function isPowerOfTwo(n) { return n > 0 && (n & (n - 1)) === 0; } - // Grid to track occupied cells - let grid = []; - - function initializeGrid() { - grid = Array(Math.ceil(canvas.height / minSquareSize)) - .fill(null) - .map(() => Array(Math.ceil(canvas.width / minSquareSize)).fill(false)); + if (!isPowerOfTwo(maxSquareSize) || !isPowerOfTwo(minSquareSize)) { + console.error('Both sizes must be powers of 2'); + return; } - function canPlaceSquare(gridX, gridY, sizeInCells) { - if (gridY + sizeInCells > grid.length || gridX + sizeInCells > grid[0].length) { - return false; - } + let grid = Array(Math.ceil(canvas.height / minSquareSize)) + .fill(null) + .map(() => Array(Math.ceil(canvas.width / minSquareSize)).fill(false)); + function canPlace(gridX, gridY, sizeInCells) { + if (gridY + sizeInCells > grid.length || gridX + sizeInCells > grid[0].length) return false; for (let y = gridY; y < gridY + sizeInCells; y++) { for (let x = gridX; x < gridX + sizeInCells; x++) { if (grid[y][x]) return false; @@ -71,7 +52,7 @@ tags: return true; } - function markSquareOccupied(gridX, gridY, sizeInCells) { + function markOccupied(gridX, gridY, sizeInCells) { for (let y = gridY; y < gridY + sizeInCells; y++) { for (let x = gridX; x < gridX + sizeInCells; x++) { grid[y][x] = true; @@ -79,108 +60,67 @@ tags: } } - function drawSquare(gridX, gridY, sizeInPixels) { - const pixelX = gridX * minSquareSize; - const pixelY = gridY * minSquareSize; - - const color = colors[Math.floor(Math.random() * colors.length)]; - ctx.fillStyle = color; - ctx.fillRect(pixelX, pixelY, sizeInPixels, sizeInPixels); - + function draw(gridX, gridY, sizeInPixels) { + const x = gridX * minSquareSize; + const y = gridY * minSquareSize; + ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)]; + ctx.fillRect(x, y, sizeInPixels, sizeInPixels); ctx.strokeStyle = '#333'; ctx.lineWidth = 1; - ctx.strokeRect(pixelX, pixelY, sizeInPixels, sizeInPixels); + ctx.strokeRect(x, y, sizeInPixels, sizeInPixels); } - function getSizesInDescendingOrder() { - const sizes = []; - for (let size = maxSquareSize; size >= minSquareSize; size /= 2) { - sizes.push(size); - } - return sizes; - } - - function countPossibleSquares(size) { - const sizeInCells = size / minSquareSize; - let count = 0; + function fill() { + const largestSizeInCells = maxSquareSize / minSquareSize; + // Collect and shuffle positions for largest squares + const positions = []; for (let gridY = 0; gridY < grid.length; gridY++) { for (let gridX = 0; gridX < grid[0].length; gridX++) { - if (canPlaceSquare(gridX, gridY, sizeInCells)) { - count++; + if (canPlace(gridX, gridY, largestSizeInCells)) { + positions.push({ gridX, gridY }); } } } - return count; - } + positions.sort(() => Math.random() - 0.5); - function fillCanvasWithPercentage() { - const sizes = getSizesInDescendingOrder(); - - // Fill the largest squares based on percentage - const largestSize = sizes[0]; - const maxPossibleLargeSquares = countPossibleSquares(largestSize); - const targetLargeSquares = Math.floor((maxPossibleLargeSquares * largeSquarePercentage) / 100); - const largestSizeInCells = largestSize / minSquareSize; - - // Collect all valid positions for largest squares - if (targetLargeSquares > 0) { - const positions = []; - for (let gridY = 0; gridY < grid.length; gridY++) { - for (let gridX = 0; gridX < grid[0].length; gridX++) { - if (canPlaceSquare(gridX, gridY, largestSizeInCells)) { - positions.push({gridX, gridY}); - } - } - } - - // Shuffle positions array - positions.sort(() => Math.random() - 0.5); - - // Place squares up to target percentage - let placedCount = 0; - for (let i = 0; i < positions.length && placedCount < targetLargeSquares; i++) { - const {gridX, gridY} = positions[i]; - // Double-check the position is still valid before placing - if (canPlaceSquare(gridX, gridY, largestSizeInCells)) { - markSquareOccupied(gridX, gridY, largestSizeInCells); - drawSquare(gridX, gridY, largestSize); - placedCount++; - } + // Place largest squares up to percentage + const target = Math.floor(positions.length * largeSquarePercentage / 100); + for (let i = 0; i < target; i++) { + const { gridX, gridY } = positions[i]; + if (canPlace(gridX, gridY, largestSizeInCells)) { + markOccupied(gridX, gridY, largestSizeInCells); + draw(gridX, gridY, maxSquareSize); } } - // Fill remaining space with all sizes in descending order - // Skip the largest size since we already handled it - for (let i = 1; i < sizes.length; i++) { - const size = sizes[i]; - const sizeInCells = size / minSquareSize; - + // Fill remaining space with smaller sizes + for (let size = maxSquareSize / 2; size >= minSquareSize; size /= 2) { + const cellSize = size / minSquareSize; for (let gridY = 0; gridY < grid.length; gridY++) { for (let gridX = 0; gridX < grid[0].length; gridX++) { - if (canPlaceSquare(gridX, gridY, sizeInCells)) { - markSquareOccupied(gridX, gridY, sizeInCells); - drawSquare(gridX, gridY, size); + if (canPlace(gridX, gridY, cellSize)) { + markOccupied(gridX, gridY, cellSize); + draw(gridX, gridY, size); } } } } } - initializeGrid(); - fillCanvasWithPercentage(); + fill(); window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; - + grid = Array(Math.ceil(canvas.height / minSquareSize)) + .fill(null) + .map(() => Array(Math.ceil(canvas.width / minSquareSize)).fill(false)); ctx.clearRect(0, 0, canvas.width, canvas.height); - - initializeGrid(); - fillCanvasWithPercentage(); + fill(); }); } - fillCanvasWithSquares(128, 8, 40); + fillCanvasWithSquares(128, 8, 10); {% endblock %} \ No newline at end of file