我想将一个段落附加到页面,并为该段落的每个单词添加一个特定的 id
(我将每个单词用 span
包裹在 id
中,以便我们稍后可以控制每个单词的颜色)
代码工作正常,但有一个问题我无法手动解决。
我想要的最大字体大小为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>
最佳答案
我已尽力为您找到解决方法,因此我将解释我所做的事情,希望它有所帮助。
首先,我删除了 getFontSize(paragraph)
和 getTextHeight(text, font)
因为它们每次都会返回相同的字体大小,而不管文本高度和删除了一些无用的 CSS 规则。
接下来,我添加了 scaleFontVW()
函数,在其中缩放每个 的
因为您需要同时执行这两项操作。font-size
和 line-height
span
接下来,while(paragraph.scrollHeight > paragraphContainer.clientHeight)
基本上我将溢出的内容高度与容器的高度进行比较,并循环直到两者变为一。
接下来,通过减去 fontSize
的值来缩小每个跨度大小(通过反复试验,我发现 5 效果很好),以及 line-height
段落的行高公式也非常简单:font-size + font-size * 20%
。
// 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>
关于javascript - 如何将附加文本放入其容器内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60514117/