This is a spinoff from this question, where I was looking for help with aligning flexbox items. I am now trying to use JavaScript to set the font size perfectly so that these elements fill their respective areas (actually 95%, but let's ignore that detail for now) without overflowing their bounds. This gives a rough idea (at least conceptually) of the desired look:
___ __ _ _ ___
/ _ \ / / _| || | / _ \
| | | |/ /_(_) || || (_) |
| | | | '_ \ |__ _> _ <
| |_| | (_) | | || (_) |
\___/ \___(_) |_| \___/ 07:00 53F
08:00 53F
09:00 54F
_____ __ ______ __ __ _____ 10:00 55F
| ____/_ | ____| /_ /_ |/ ____| etc...
| |__ | | |__ | || | |
|___ \ | | __| | || | |
___) || | | | || | |____
|____/ |_|_| |_||_|\_____|
PTC 49F 10C
The areas you see here (details availble in the original question) are organized like this (showing the ids here:
[unnamed]
[time_temp_container] [right_side]
[time] [icon]
[temp] [forecast00]
[forecast01]
(etc)
From javascript, I can get the elements time_temp_container and time and temp, etc, but I do not find an attribute that shows me the available size of these attributes. I can access the "used" size by referencing, say, time.offsetWidth. And I can see that this value changes as I change the value of time.style.fontSize. But my target width (the number of pixels available) is a value that eludes me. I see screen and all of its attributes (notably screen.width and screen.height). But these values are virtual, not pixels, and besides, I don't see a way to use those to get to (for example) time's width. Then there's window.innerWidth and window.innerHeight, which at least seem to be pixel-based, but again I don't see a relationship I can draw from to get the desired values.
How can I determine the amount of space that is available so that I can detect the font size that will cause current content to fill it?
EDIT
This is a very-trimmed-down version of what I am trying to accomplish, hopefully containing enough of the final code to show the problem. There are two files. The multiclock-sample.js file is referened by name in the multiclock-sample.html file.
multiclock.js
"use strict" ;
var tempsTableElem = document.getElementById('temps') ;
var timeElem = document.getElementById("clocktext") ;
var tempElem = document.getElementById("temptext") ;
var clockElem = document.getElementById("clockDiv") ;
var rightSide = document.getElementById('rightSideContainer') ;
var page = document.getElementById('page') ;
var targetWidth = 0.98 ; // Proportion of full screen width
var startFontSize = 8 ;
var timeFontSize = 10 ;
var tempFontSize = 10 ;
function updateForecastTextSize() {
var theElement = document.getElementById('forecast00') ;
let theFontSize = theElement.style.fontSize == startFontSize ;
theElement.style.fontSize = theFontSize ;
let rect = theElement.getBoundingClientRect() ; // To see in debug
theFontSize *= targetWidth / (theElement.offsetWidth / rightSide.offsetWidth) ;
theElement.style.fontSize = round(theFontSize,2) + 'pt' ;
}
function updateTextSize() {
var save ;
timeFontSize = startFontSize ;
tempFontSize = startFontSize ;
timeElem.style.fontSize = timeFontSize ;
tempElem.style.fontSize = tempFontSize ;
// Hide temp element while sizing time element
save = tempElem.style.display ;
tempElem.style.display = 'none' ;
timeFontSize *= targetWidth / (timeElem.offsetWidth / clockElem.offsetWidth) ;
timeElem.style.fontSize = round(timeFontSize,2) + "pt" ;
tempElem.style.display = save ;
// Hide time element while sizing temp element
save = timeElem.style.display ;
timeElem.style.display = 'none' ;
tempFontSize *= targetWidth / (tempElem.offsetWidth / clockElem.offsetWidth) ;
tempElem.style.fontSize = round(tempFontSize,2) + 'pt' ;
timeElem.style.display = save ;
}
function round(value, precision) {
var multiplier = Math.pow(10, precision || 0) ;
return Math.round(value * multiplier) / multiplier ;
}
updateTextSize() ;
updateForecastTextSize() ;
multiclock.html
<!DOCTYPE html>
<html lang='en' style="height:100%; margin:0; padding:0">
<head>
<title>Full Screen Clock</title>
<style>
.box {
display:flex;
flex-flow: row nowrap;
flex: none;
align-items:center;
justify-content:space-evenly;
width:100%;
height:100%;
}
.forecast {
display:flex ;
text-align:center ;
width:100% ;
flex:none ;
}
</style>
</head>
<body style="display:flex; height:100%; margin:0; padding:0; justify-content:center; align-items:center">
<div id='page' class='box'>
<div id='timeTempContainer' style='align-items:center; width:60%; display: flex; flex-flow:column nowrap; flex:none;'>
<div id='clockDiv' style='font-size:85pt;text-align:center;vertical-align:middle;width:100%;flex:none;'>
<span id="clocktext" style="font-kerning:none;">19:17</span>
</div> <!-- clockDiv -->
<div id='tempContainer' style='font-size:85pt;text-align:center;vertical-align:middle;width:100%;flex:none'>
<span id="temptext" style="font-kerning:auto; text-align:center">39ºF 4ºC</span>
</div> <!-- tempContainer -->
<div id='otherCityContainer' style='font-size:85pt;text-align:center;vertical-align:middle;width:100%;flex:none'>
<span id='othercity' style="font-kerning:auto; text-align:center">Eventually, we will size this</span>
</div> <!-- otherCityContainer -->
</div> <!-- timeTempContainer -->
<div id='rightSideContainer' style='flex-flow: column nowrap;justify-content:space-evenly;flex:none;'>
<div> <span id='weatherIcon' class='forecast'><img alt='weatherIcon' style='vertical-align:middle' height=100 width=100 src='https://openweathermap.org/img/wn/[email protected]'></span> </div>
<div> <span id='forecast00' class='forecast'></span>20:00 38ºF 3ºC</div>
</div> <!-- rightSideContainer -->
</div> <!-- page -->
<script src="multiclock-sample.js">
</script>
</body>
</html>