Javascript 设置字体大小以填充页面宽度

问题描述 投票:0回答:1

我正在尝试创建一个全页的基于网络的时钟以供嵌入式设备使用。这个想法是,该设备将显示全屏,其中大显示屏显示时钟,下方显示当前温度、华氏度和摄氏度以及城市名称或代码。时钟时间和温度将随时间更新;时钟将以 5 秒的间隔重复滚动浏览可用城市。

我无法正常调整字体大小。这个想法是,将设置一个较小的字体以获得初始大小,然后我们将进行算术以使文本填充宽度的 90%。这是在迭代循环中完成的,因为 offsetWidth 是一个整数值,因此迭代处理应该让我们足够接近我们的目标。

有一个组划分,其中有时间划分和温度划分。所有这三个都指定 100% 宽度,这就是我想要的。然后将各个元素的 offsetWidths 应用到分割宽度,以导出填充该宽度所需的字体。

逐个播放,10 点字体的初始“时钟”offsetWidth 为 48,目标为 1259。算术正确地将字体大小设置为 236(并更改)。然后我们查看温度偏移宽度,在进行任何算术之前,它显示 offsetWidth 已经是 1259,因此字体没有被操作。但这个数字并不正确; offsetWidth 应该更像 150 左右。

此外,时钟大小调整似乎只起作用一次(因此它出现大约半秒),然后与温度大小调整存在相同的问题。我没有看到任何重置失败或重置不正确的地方,所以我很困惑这里发生了什么。

我已经包含了源代码(test.html 和 test.js),希望有人能告诉我哪里可能出了问题。我将感谢您的指导。

测试.html

<!DOCTYPE html>
<html lang='en' style="height:100%; width:100%; margin:0; padding:0">
    <head>
    <title>Full Screen Clock</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name='viewport' content ='width = device-width, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, user-scalable = no, viewport-fit=cover' >
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="apple-mobile-web-app-title" content="Ampron Clock">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

    <style>
        /* Customizable font and colors */
        html {
            font-family: 'Courier' ;
            background:#000000;
            color: #91ff0f ;
        }
    </style>
</head>

<body style="display:flex; height:100%; width:100%; margin:0; padding:0; justify-content:center; align-items:center">
    <div style='height:100%; width: 100%; margin: 0 auto'>
        <div id='clockDiv' style='height:60%; width:100%; margin: 0 auto'>
            <span id="clocktext" style="font-kerning:none; text-align:center"></span>
        </div>
        <div id='tempDiv' style='width:100%; margin: 0 auto'>
            <span id="temptext" style="font-kerning:none; text-align:center"></span>
        </div>
    </div>

    <script src='test.js'></script>
</body>
</html>

测试.js

    "use strict" ;
    const cycleLength = 5 ;
    const startFontSize = 10 ;
    const targetWidth = .9 ;
    var tempsTableElem = document.getElementById('temps') ;
    var timeElem = document.getElementById("clocktext") ;
    var tempElem = document.getElementById("temptext") ;
    var clockElem = document.getElementById("clockDiv") ;
    var timeFontSize ;
    var tempFontSize ;
    var cityTempArray ;



    function updateClock() {
        var d = new Date() ;

        var seconds = d.getSeconds() ;
        var cityCount = cityTempArray.length ;
        var showSeconds = (cityCount == 1) ;
        var showCity = (cityCount > 1) ;
        // We change cities (if applicable) every 5 seconds. So:
        //     If there are two cities, the cycle repeats every 10 seconds
        //     If there are three cities, the cycle repeats every 15 seconds
        //     four cities: 20 seconds
        // Therefore, we can use (seconds/5) modulus (number of cities) to get city index.
        // So if we are, say, 38 seconds into the minute and there are, say, 3 cities, then current city (from 0 to 2) is:
        //     Math.floor(38/5) % cityCount = 7 % 3 = 1 (0~4=0 5~9=1 10~14=2 15~19=0 22~24=1 25~29=2 30~34=0 35~39=1)
        // We will set maximum to 4 cities because it gets weird after that.  Anyway, that's enough, right?
        var currentCity = Math.floor(seconds/cycleLength) % cityCount ; // (0 through number-cities - 1)

        var cityCode = cityTempArray[currentCity][0] ;
        var farenheit = round(cityTempArray[currentCity][1], 0) ;
        var s = "" ;
        var celsius = round(5 / 9 * (farenheit - 32), 1) ;
        var colon = (showSeconds || d.getMilliseconds() < 500) ? ':' : ' ' ;
        s +=         (d.getHours()   < 10 ? "0" : "") + d.getHours()   ;
        s += colon + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes() ;
        if (showSeconds)
            s += colon + (d.getSeconds() < 10 ? "0" : "") + d.getSeconds() ;

        timeElem.textContent = s ;
        s = farenheit + 'ºF ' + celsius + 'ºC' ;
        if (showCity)
            s += ' ' + cityCode ;
        tempElem.textContent = s ;

        updateTextSize() ;
        let time = 500 - d.getTime() % 500 + 20 ;
        setTimeout(updateClock, time) ;
        }



function updateTextSize() { // Attempt to fill the width of the page with clock text and temperature text
    tempFontSize = startFontSize ;
    timeFontSize = startFontSize ;
    for (var i = 0 ; i < 3 ; i++) {  // Iterate for better better convergence
        // We will hide the elements we're not sizing, so that they don't interfere
        tempElem.style.display = 'none' ;
        timeFontSize *= targetWidth / (timeElem.offsetWidth / clockElem.offsetWidth) ;
        timeElem.style.fontSize = timeFontSize + "pt" ;
        // We will hide the elements we're not sizing, so that they don't interfere
        timeElem.style.display = 'none' ;
        tempElem.style.display = 'block' ;
        tempFontSize *= targetWidth / (tempElem.offsetWidth / clockElem.offsetWidth) ;
        tempElem.style.fontSize = tempFontSize + 'pt' ;
        timeElem.style.display = 'block' ;
    }
}

function getTemps(tableElement) {
    cityTempArray = [ [ 'NewYork', 34 ], ['Brisbain', 76 ] ] ;
}



function round(value, precision) {
    var multiplier = Math.pow(10, precision || 0) ;
    return Math.round(value * multiplier) / multiplier ;
}



getTemps() ;
updateClock() ;
window.addEventListener("resize", updateTextSize) ;
javascript html css font-size
1个回答
0
投票

看来 timeElem.offsetWidth 和clockElem.offsetWidth 总是相同的值,因为你设置了 timeElem.style.display = 'block',我只是添加了一个样式flex,希望它有帮助

<!DOCTYPE html>
<html lang="en" style="height: 100%;">

<head>
  <title>title</title>
  <meta name='viewport' content='width = device-width, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, user-scalable = no, viewport-fit=cover'>
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="apple-mobile-web-app-title" content="Ampron Clock">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


</head>
<style>
  /* Customizable font and colors */
  
  html {
    font-family: 'Courier';
    background: #000000;
    color: #91ff0f;
  }
</style>

<body style="display:flex; height:100%; width:100%; margin:0; padding:0; justify-content:center; align-items:center">
  <div style='height:100%; width: 100%; margin: 0 auto'>
    <div id='clockDiv' style='height:60%; width:100%;display:flex; justify-content:center; margin: 0 auto'>
      <span id="clocktext" style="font-kerning:none;"></span>
    </div>
    <div id='tempDiv' style='width:100%; margin: 0 auto;display:flex; justify-content:center;'>
      <span id="temptext" style="font-kerning:none"></span>
    </div>
  </div>
  <script>
    const cycleLength = 5;
    const startFontSize = 10;
    const targetWidth = .9;
    var timeElem = document.getElementById("clocktext");
    var tempElem = document.getElementById("temptext");
    var clockElem = document.getElementById("clockDiv");
    var timeFontSize;
    var tempFontSize;
    var cityTempArray;

    function updateClock() {
      var d = new Date();

      var seconds = d.getSeconds();
      var cityCount = cityTempArray.length;
      var showSeconds = (cityCount == 1);
      var showCity = (cityCount > 1);
      // We change cities (if applicable) every 5 seconds. So:
      //     If there are two cities, the cycle repeats every 10 seconds
      //     If there are three cities, the cycle repeats every 15 seconds
      //     four cities: 20 seconds
      // Therefore, we can use (seconds/5) modulus (number of cities) to get city index.
      // So if we are, say, 38 seconds into the minute and there are, say, 3 cities, then current city (from 0 to 2) is:
      //     Math.floor(38/5) % cityCount = 7 % 3 = 1 (0~4=0 5~9=1 10~14=2 15~19=0 22~24=1 25~29=2 30~34=0 35~39=1)
      // We will set maximum to 4 cities because it gets weird after that.  Anyway, that's enough, right?
      var currentCity = Math.floor(seconds / cycleLength) % cityCount; // (0 through number-cities - 1)

      var cityCode = cityTempArray[currentCity][0];
      var farenheit = round(cityTempArray[currentCity][1], 0);
      var s = "";
      var celsius = round(5 / 9 * (farenheit - 32), 1);
      var colon = (showSeconds || d.getMilliseconds() < 500) ? ':' : ' ';
      s += (d.getHours() < 10 ? "0" : "") + d.getHours();
      s += colon + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes();
      if (showSeconds)
        s += colon + (d.getSeconds() < 10 ? "0" : "") + d.getSeconds();

      timeElem.textContent = s;
      s = farenheit + 'ºF ' + celsius + 'ºC';
      if (showCity)
        s += ' ' + cityCode;
      tempElem.textContent = s;

      updateTextSize();
      let time = 500 - d.getTime() % 500 + 20;
      setTimeout(updateClock, time);
    }

    function updateTextSize() { // Attempt to fill the width of the page with clock text and temperature text
      tempFontSize = startFontSize;
      timeFontSize = startFontSize;
      for (var i = 0; i < 3; i++) { // Iterate for better better convergence
        // We will hide the elements we're not sizing, so that they don't interfere
        tempElem.style.display = 'none';
        timeFontSize *= targetWidth / (timeElem.offsetWidth / clockElem.offsetWidth);
        timeElem.style.fontSize = timeFontSize + "pt";
        // We will hide the elements we're not sizing, so that they don't interfere
        timeElem.style.display = 'none';
        tempElem.style.display = 'block';
        tempFontSize *= targetWidth / (tempElem.offsetWidth / clockElem.offsetWidth);
        tempElem.style.fontSize = tempFontSize + 'pt';
        timeElem.style.display = 'block';
      }
    }
    function getTemps(tableElement) {
      cityTempArray = [
        ['NewYork', 34],
        ['Brisbain', 76]
      ];
    }
    function round(value, precision) {
      var multiplier = Math.pow(10, precision || 0);
      return Math.round(value * multiplier) / multiplier;
    }
    getTemps();
    updateClock();
    window.addEventListener("resize", updateTextSize);
  </script>
</body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.