5
votes

So I have a matrix of divs within a container in my page, each div displays either a '1' or a '0'.

If I set my container to a width of 100% and height to fit the bottom of my page, I want to be able to scale all of the 1's and 0's inside the container's divs (the number of 0's and 1's will be a static number, lets go with 100 for the sake of this question) to always fit the container perfectly no matter what size the browser is resized to, so it fits the width and height of the container perfectly without any trailing white-space or elements that go off the page or trigger a scroll bar.

The goal is to make sure the fonts resize to fit within the container exactly, regardless of screen size (both height and width).

I have seen multiple similar questions on stack overflow, such as: JavaScript Scale Text to Fit in Fixed Div, but they all seem to scale a certain line of text rather than the text from my combined divs. Is there a way I can do this within JavaScript?

If you see what is being asked for in This Question, this is exactly what I want. The difference in that Q is that he uses some text within 1 div rather than multiple to fit his container.

Here is my HTML:

<div id="binaryMatrix" style="width: 100%; height: 100%;">
    <div>0</div>
    <div>1</div>
    <div>0</div>
    <div>1</div>
    <div>0</div>
    <div>1</div>
    <div>0</div>
    <div>1</div>
    ...up to 100
 </div>

Here is my CSS:

#binaryMatrix div {
    float: left;
}

See Fiddle: Fiddle

This project is also on GitHub: GitHub - danjonescidtrix/binary-matrix


Any help or advice here is appreciated, thank you in advance

3
can you create a fiddle and share so that we can work on it.Aslam
no problem, see edit @hunzaboydjmcr
Will all elements be 1 and 0?Alvaro
yes they will @Alvarodjmcr

3 Answers

1
votes

I decided to have another go at this - not least because it's a fascinating problem.

I think I have cracked it.

var binaryMatrix = document.getElementById('binaryMatrix');
var binaryMatrixDivs = binaryMatrix.getElementsByTagName('div');

var largestNumberOfRows = 12;

for (var i = largestNumberOfRows; i > 0; i--) {
    if (binaryMatrixDivs.length % i === 0) {
        var numberOfRows = i;
        break;
    }
}

function changeDivWidth() {
    for (var i = 0; i < binaryMatrixDivs.length; i++) {
    var divWidth = (100 / (binaryMatrixDivs.length / numberOfRows));
    var divHeight = (100 / numberOfRows);

    binaryMatrixDivs[i].style.width = divWidth + 'vw';
    binaryMatrixDivs[i].style.height = divHeight + 'vh';
    binaryMatrixDivs[i].style.lineHeight = divHeight + 'vh';
    }
}

window.addEventListener('load',changeDivWidth,false);
body {
margin: 0;
padding: 0;
}

#binaryMatrix {
width: 100vw;
height: 100vh;
}

#binaryMatrix div {
display: inline-block;
float: left;
width: 0;
height: 0;
line-height: 20vh;
text-align: center;
}

#binaryMatrix div:nth-of-type(odd) {
background-color: rgb(191,191,191);
}

#binaryMatrix div:nth-of-type(even) {
background-color: rgb(127,127,127);
}
<div id="binaryMatrix">
<div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div>
</div>

Notes:

1) You can determine the number of rows by altering the value of numberOfRows. If the numberOfRows is set to 5, then there will always be 5 rows - no matter how short or tall or wide or narrow the window is.

2) Obviously, you'll want the numberOfRows to be a factor of the number of divs you have. So 5 rows is good if you have 100 divs or 90 divs, but if you have 96 divs, you'll want numberOfRows to be 4 or 6 or 12 or some other factor of 96.


Improvement:

The two notes above were necessary because in the first version of the script, you have to manually declare the number of rows. In the second version of the script (above) you can still manually declare the number of rows if you wish but (slightly less effort) you can simply manually declare the largest number of rows you wish to see (eg. no more than 14 rows) and the script will count down from 14 until it finds a factor - and the first factor it comes to will be the numberOfRows.

This will enable you to change the number of divs (manually or dynamically) without having to reset the numberOfRows each time.

1
votes

Right. Third attempt (and I really do have it cracked this time).

The number of digits is static. Let's call it 100 digits.

Digits are taller than they are wide, so we need a grid of tall, narrow divs. 10x10 is no good. Let's set up a 20x5 grid instead.

Now all we need to do is work out:

  1. how large the digit font-size would be based only on the width of the viewport; and
  2. how large the digit font-size would be based only on the height of the viewport;

Whichever is the smaller can be the font-size applied to the digits.

var binaryMatrix = document.getElementById('binaryMatrix');
var binaryMatrixDivs = binaryMatrix.getElementsByTagName('div');

function applyNewFontSize() {

    var newVerticalFontSize = (window.innerHeight / 5.5);
    var newHorizontalFontSize = (window.innerWidth / 20.5);
    var newFontSize = (newVerticalFontSize > newHorizontalFontSize ? newHorizontalFontSize : newVerticalFontSize);

    for (var i = 0; i < binaryMatrixDivs.length; i++) {
    binaryMatrixDivs[i].style.fontSize = newFontSize + 'px';
    binaryMatrixDivs[i].style.lineHeight = newFontSize + 'px';
    }

}

window.addEventListener('resize',applyNewFontSize,false);
window.addEventListener('load',applyNewFontSize,false);
body {
margin: 0;
padding: 0;
}

#binaryMatrix {
width: 100vw;
height: 100vh;
}

#binaryMatrix div {
display: inline-block;
float: left;
width: 5vw;
height: 20vh;
text-align: center;
color: rgb(163,163,163);
}
<div id="binaryMatrix">
<div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div><div>0</div><div>1</div>
</div>
0
votes

You can scale each element and then position its left value according to the new scale.

https://jsfiddle.net/f6Lfe8hv/2/

var total_width = 0;
var total_left = 0;
var $divs = $('#binaryMatrix>div');
var $binaryMatrix = $('#binaryMatrix');
var scale = 1;

$divs.each(function() {
  total_width += $(this).width();
});

function full_width() {

  scale = $binaryMatrix.width() / total_width;

  $divs.css('transform', 'scale(' + scale + ')');

  $divs.each(function() {

    $(this).css('left', total_left);

    total_left += $(this).width() * 1;

  });

  total_left = 0;
}

full_width();

$(window).resize(function() {

  full_width();

})
#binaryMatrix div {
  position: absolute;
  transform-origin: left;
}

#binaryMatrix {
  top:0;
  left:0;
  background: pink;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="binaryMatrix" style="width: 100%; height: 100%;">

  <div>some_test_value</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>0</div>
  <div>1</div>
  <div>0</div>
  <div>1</div>
  <div>another_test_value</div>

</div>