Search code examples
javascriptalgorithmmathhtml5-canvasdynamic-image-generation

Calculate how many elements will fit on image when spaces are involved


I need to render N items that are x pixels wide with N-1 spaces y pixels wide between them.

I need to calculate how many items will fir on the screen. What I'm doing is rendering an array of amplitudes as columns. This is my test produce without spaces:

enter image description here

I first calculate how many items will fit, then resample the original array to get exactly the number of values that will fit on the screen. This is the same with 5 pixels per column, you can see that the original array has been resampled:

enter image description here

The formula I use now is no_items = Math.floor(canvasWidth/(barWidth+spaceWidth)):

/**
 * Recalculates waveform data for given width of canvas
 * @param {number} canvasWidth Image width in pixels
 * @param {number} barWidth Width of waveform bars
 * @param {number} spaceWidth Width of spaces between bars
 * @returns {Uint8Array} recalculated bytes
 */
recalculateForWidth(canvasWidth, barWidth, spaceWidth) {
    const no_items = Math.floor(canvasWidth/(barWidth+spaceWidth))
    const result = new Uint8Array(no_items);
    // Resampling code follows
    ...
    return result;
}

But that clearly assumes one extra space at the end of the data - it simply calculates with item width being bar width+ space width.

I want to render bars without space at the end, so how do I calculate how many will fit with spaces but without space at the end?


Solution

  • Your total width will be:

    barWidth(NumberBars) + spaceWidth(NumberBars - 1) = TotalWidth
    

    which expands to:

    barWidth(NumberBars) + (spaceWidth)(NumberBars) - spaceWidth = TotalWidth
    

    add spaceWidth to both sides:

    barWidth(NumberBars) + spaceWidth(NumberBars) = TotalWidth + spaceWidth
    

    Factor left side:

    NumberBars(barWidth + spaceWidth) = TotalWidth + spaceWidth
    

    and divide:

    NumberBars = (TotalWidth + spaceWidth) / (barWidth + spaceWidth)