【问题标题】:How to fit appended text inside its container如何将附加文本放入其容器中
【发布时间】:2020-06-16 05:46:45
【问题描述】:

我想在页面上附加一个段落并将段落的每个单词添加一个特定的id(我用id将每个单词包装在span中,以便我们可以控制每个单词的颜色稍后再说)

代码运行良好,但有一个问题我无法解决。

我想要5vw 的最大字体大小,并且我想减小字体大小以适应paragraphContainer 内的整个段落。

我尽力了,但不幸的是,这还不够!

使用let fontSize = getFontSize(paragraphOriginal); 我试图获取多行附加文本的高度,但我认为它只需要一行的高度!如果我能得到多行的高度...

代码如下:

// our paragraph
let paragraphOriginal = "During a discussion that popped up over this, Adam pointed out there is a new CSS property that is (as I understand it) specifically for this. This removes the need for three elements. Technically you only need one, the inline element, but it's likely you'll be doing this on a header so you'll probably end up with a block-parent anyway, which is best for spacing. LAST WORDS";

// Convert above paragraph to array of words
let paragraphWords = paragraphOriginal.replace(/\s+/g, " ").toLowerCase().replace(/\,|\?|\!|\:|\./g, '').trim().split(' ');


//dimensions of the paragraphContainer container
let height = document.getElementsByClassName("paragraphContainer")[0].clientHeight;

let text_Height;


// Add paragraph to page and assign each word an specific id 
generateParagraph();


function generateParagraph() {

  let paragraph = document.getElementById("paragraph");
  let answerPrototype = '';

  for (let i = 0; i < paragraphWords.length; i++) {
    paragraphWords[i] = ' ' + paragraphWords[i];
  }
  //paragraphWords[0] = paragraphWords[0].trim();

  let paragraphSpans = '';

  for (let i = 0; i < paragraphWords.length; i++) {

    paragraphSpans += `<span class='spans' id='spanID${i}'>${paragraphWords[i]}</span>`;

  };

  //modify the font size based on text length

  let fontSize = getFontSize(paragraphOriginal); // I think here is the problem

  console.log(fontSize);

  paragraph.style.fontSize = `${fontSize}vw`;

  paragraph.innerHTML = `${paragraphSpans}`;

};




function getFontSize(paragraph) {

  let default_size = 5;

  do {
    default_size -= 0.1;
    text_Height = getTextHeight(paragraph, `bold ${default_size}vw Open Sans`);
  }

  while (text_Height > height);

  return default_size.toFixed(2);

};


//Start Of Text Height Function
function getTextHeight(text, font) {
  let canvas = document.createElement("canvas")
  let context = canvas.getContext("2d");

  let sourceWidth = canvas.width;
  let sourceHeight = canvas.height;

  context.font = font;

  // place the text somewhere
  context.textAlign = "left";
  context.textBaseline = "top";
  context.fillText(text, 25, 5);

  // returns an array containing the sum of all pixels in a canvas
  // * 4 (red, green, blue, alpha)
  // [pixel1Red, pixel1Green, pixel1Blue, pixel1Alpha, pixel2Red ...]
  let data = context.getImageData(0, 0, sourceWidth, sourceHeight).data;

  let firstY = -1;
  let lastY = -1;

  // loop through each row
  for (let y = 0; y < sourceHeight; y++) {
    // loop through each column
    for (let x = 0; x < sourceWidth; x++) {
      //var red = data[((sourceWidth * y) + x) * 4];
      //var green = data[((sourceWidth * y) + x) * 4 + 1];
      //var blue = data[((sourceWidth * y) + x) * 4 + 2];
      let alpha = data[((sourceWidth * y) + x) * 4 + 3];

      if (alpha > 0) {
        firstY = y;
        // exit the loop
        break;
      }
    }
    if (firstY >= 0) {
      // exit the loop
      break;
    }

  }

  // loop through each row, this time beginning from the last row
  for (let y = sourceHeight; y > 0; y--) {
    // loop through each column
    for (let x = 0; x < sourceWidth; x++) {
      var alpha = data[((sourceWidth * y) + x) * 4 + 3];
      if (alpha > 0) {
        lastY = y;
        // exit the loop
        break;
      }
    }
    if (lastY >= 0) {
      // exit the loop
      break;
    }

  }

  return lastY - firstY;

}; //End Of Text Height Function
html {
  overflow: hidden;
  background-color: transparent;
}

.paragraphContainer {
  position: absolute;
  overflow: hidden;
  left: 2.45vw;
  top: 25vh;
  height: 55vh;
  width: 95vw;
  outline: 0.1vw dashed orange;
}

.paragraph-class {
  position: absolute;
  white-space: pre-wrap;
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
  color: #595959;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  padding: 0vh 1vh 20vh 1vh;
  justify-content: left;
  align-items: left;
}
<!DOCTYPE html>
<html>

<head>

  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&display=swap" rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="style.css">

</head>

<body>

  <div class="paragraphContainer">
    <div id="paragraph" class="paragraph-class"></div>
  </div>


  <!-- <button id="myBtn">Try it</button>

<script>
document.getElementById("myBtn").addEventListener("click", function(){
  Read();
});
</script> -->


  <script src="script.js"></script>
</body>

</html>

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    我已尽力为您找到解决方法,因此我将解释我做了什么,希望对您有所帮助。

    首先我 removed getFontSize(paragraph)getTextHeight(text, font) 因为无论文本高度如何,它们每次都返回相同的字体大小,并删除了一些无用的 CSS 规则。

    接下来,我添加了scaleFontVW() 函数,我可以根据需要同时缩放每个spanfont-sizeline-height

    接下来,while(paragraph.scrollHeight &gt; paragraphContainer.clientHeight) 基本上我将溢出的内容高度与容器的高度进行比较,然后循环直到两者合而为一。

    接下来,通过减去 fontSize 的值(通过反复试验,我发现 5 效果很好)和 paragraphline-height 的值会缩小每个跨度大小,行高公式很简单:font-size + font-size * 20%.

    有帮助的答案:Paul'smicnic's

    // our paragraph
    let paragraphOriginal = "During a discussion that popped up over this, Adam pointed out there is a new CSS property that is (as I understand it) specifically for this. This removes the need for three elements. Technically you only need one, the inline element, but it's likely you'll be doing this on a header so you'll probably end up with a block-parent anyway, which is best for spacing. LAST WORDS";
    
    
    
    // Convert above paragraph to array of words
    let paragraphWords = paragraphOriginal.replace(/\s+/g, " ").toLowerCase().replace(/\,|\?|\!|\:|\./g,'').trim().split(' ');
    
    
    //dimensions of the paragraphContainer container
    let height = document.getElementsByClassName("paragraphContainer")[0].clientHeight;
    
    let text_Height;
    
    
    // Add paragraph to page and assign each word an specific id 
    generateParagraph();
    
    // Scale the font to fit
    scaleFontVW();
    
    function generateParagraph() {
    
        let paragraph = document.getElementById("paragraph");
        let answerPrototype = '';
    
        for(let i = 0; i < paragraphWords.length; i++){
            paragraphWords[i] = ' ' + paragraphWords[i];
        }
        //paragraphWords[0] = paragraphWords[0].trim();
    
        let paragraphSpans = '';
    
        for (let i = 0; i < paragraphWords.length; i++) {
    
          paragraphSpans += `<span class='spans' id='spanID${i}'>${paragraphWords[i]}</span>`;
    
        };
    
        //modify the font size based on text length
    
        //let fontSize = getFontSize(paragraphOriginal ); // I think here is the problem
    
        //console.log(fontSize);
        
        //paragraph.style.fontSize = `${fontSize}vw`;
         
        paragraph.innerHTML = `${paragraphSpans}`;
    
    };
    
    function scaleFontVW() {
      let paragraph = document.getElementById("paragraph");
      let paragraphContainer = document.getElementById("pc")
      let spans = document.getElementsByTagName("span");
    
      let style = window.getComputedStyle(spans[0], null).getPropertyValue('font-size');
      let fontSize = parseFloat(style); 
    
      while(paragraph.scrollHeight >= paragraphContainer.clientHeight) {
        fontSize -= 5;
        for(let i = 0; i < spans.length; i++) {
          spans[i].style.fontSize = fontSize+"px";
          }
        paragraph.style.lineHeight = fontSize*0.2 + fontSize + "px";
    }
    }
    
    function scaleFontVW_2() {
      let paragraph = document.getElementById("paragraph");
      let paragraphContainer = document.getElementById("pc")
    
      let style = window.getComputedStyle(spans[0], null).getPropertyValue('font-size');
      let fontSize = parseFloat(style); 
    
      while(paragraph.scrollHeight >= paragraphContainer.clientHeight) {
        fontSize -= 1;
        paragraph.style.fontSize = fontSize+"px";
        paragraph.style.lineHeight = fontSize*0.2 + fontSize + "px";
    }
    }
    html{
      background-color: transparent;
    }
    
    .paragraphContainer {
        position: absolute;
        left: 2.45vw;
        top: 25vh;
        height: 55vh;
        width: 95vw;   
        outline: 0.1vw dashed orange;
    }
    
    .paragraph-class {
        font-size: 5vw;
        position: absolute;
        white-space: pre-wrap; 
        font-family: 'Open Sans', sans-serif;  
        font-weight:400;
        color: #595959;
    }
    <!DOCTYPE html>
    <html>
    <head>
    
      <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700&display=swap" rel="stylesheet">
      <link rel="stylesheet" type="text/css" href="style.css"> 
    
    </head>
    
    <body> 
    
    <div id = "pc" class="paragraphContainer"> 
    <div id="paragraph" class="paragraph-class"></div>
    </div>
    
    
    <!-- <button id="myBtn">Try it</button>
    
    <script>
    document.getElementById("myBtn").addEventListener("click", function(){
      Read();
    });
    </script> -->
    
    
    <script src="script.js"></script>
    </body>
    
    </html>

    【讨论】:

    • 很高兴它有帮助。另外,请注意,我现在刚刚添加了一个名为 function scaleFontVW_2() 的新函数,它可以更好地处理非常长(我的意思是非常长)的字符串和普通字符串。我发现更改paragraph fontSize 不是每个span 在提供更长的字符串时更好,并且在正常字符串长度(如您提供的字符串长度)下也能正常工作。检查一下,告诉我哪个版本更适合您的情况。干杯!
    • 感谢您的更新...是的...它更清晰有效...对于那些可能有同样问题的人,请添加let spans = document.getElementsByTagName("span");scaleFontVW_2()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 2023-04-04
    • 1970-01-01
    • 2017-06-14
    • 2020-06-25
    • 2022-01-08
    • 2020-04-15
    相关资源
    最近更新 更多