2023-05-21

Add random/uneven spacing between pixel blocks in an HTML canvas

I have this code that takes an image and divides it into blocks with a size of blockSize, then deletes the surrounding pixels and spaces them out by a spacing defined by spacing. This creates a uniform split, but I want to add some randomness to the spacing to distribute the blocks unevenly (controlled by variance variable).

Bonus answer: Also add some randomness to the blockSize to make some blocks larger than others. This is my current code:

const canvas = document.createElement("canvas")
const ctx = ref.current.getContext("2d")!
const imgData = ctx.getImageData(0, 0, ref.current.width, ref.current.height)
const pixels = imgData.data

let blockSize = 5
let spacing = 70
let variance = 50

for (let row = 0; row < imgData.height; row++) {
    for (let col = 0; col < imgData.width; col++) {
        const i = (row * imgData.width + col) * 4
        let r = pixels[i]
        let g = pixels[i+1]
        let b = pixels[i+2]
        let a = pixels[i+3]
        const adjustedSpacing = spacing // Add randomness?
        const blockRow = Math.floor(row / (blockSize + adjustedSpacing))
        const blockCol = Math.floor(col / (blockSize + adjustedSpacing))
        const blockRowPixel = blockRow * (blockSize + adjustedSpacing)
        const blockColPixel = blockCol * (blockSize + adjustedSpacing)

        const withinBlockRow = row >= blockRowPixel && row < blockRowPixel + blockSize
        const withinBlockCol = col >= blockColPixel && col < blockColPixel + blockSize
        if (withinBlockRow && withinBlockCol) {
            pixels[i] = r
            pixels[i+1] = g
            pixels[i+2] = b
            pixels[i+3] = a
        } else {
            pixels[i] = 0
            pixels[i+1] = 0
            pixels[i+2] = 0
            pixels[i+3] = 0
        }
    }
}
ctx.putImageData(imgData, 0, 0)

This was my attempted solution, but it doesn't work. It destroys the blocks:

const adjustedSpacing = Math.floor(Math.random() * variance) + spacing


No comments:

Post a Comment