Reputation: 1702
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
Upvotes: 5
Views: 479
Reputation: 29511
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:
font-size
would be based only on the width of the viewport; andfont-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>
Upvotes: 1
Reputation: 29511
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.
Upvotes: 1
Reputation: 9682
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>
Upvotes: 0