2

如何计算文本元素填充所需空间所需的字体大小?例如:

txt = "this text should fill the div precisely"
el = $("<div/>")
    .html(txt)
    .width(200)
    .css({
        fontFamily: "arial",
        fontSize: font_size_to_fit(txt,"arial",200)
    });

编辑:我要求一个根据简单的数学公式计算大小的函数。它可以是一个近似值。针对上述问题提出的解决方案是不正确的,因为它涉及交互式 DOM 操作,该操作太重而无法放置在瓶颈区域。

4

4 回答 4

3

我从来没有尝试过这个,也许这很疯狂,但不是所有(不幸的是无益的)建议通过一遍又一遍地改变大小直到文本适合来解决这个问题,也许你可以只尝试两种非常不同的字体大小(使用 no-换行,当然),例如 10 和 100,然后假设关系应该几乎是线性的,然后插值或推断您的预期值?我不知道做这样的两个布局是否对你的瓶颈来说太贵了。如果是这样,我不确定你真的有什么希望,因为字体可能很棘手。但这可能会奏效。

更新:我使用这种技术创建了一个小提琴。它似乎工作得相当好。相关代码为:

var font_size_to_fit = (function() {
    var $test = $("<span/>").appendTo("body").css({
        visibility: "hidden", 
        border: 0, 
        padding: 0, 
        whiteSpace: "pre"
    });
    var minFont = 10, maxFont = 100; 
    return function(txt, fontFamily, size) {
        $test.appendTo("body").css({fontFamily: fontFamily}).text(txt);
        $test.css({fontSize: maxFont + "px"});
        var maxWidth = $test.width();
        $test.css({fontSize: minFont + "px"});
        var minWidth = $test.width();
        var width = (size - minWidth) * (maxFont - minFont) / 
            (maxWidth - minWidth) + minFont;
        $test.detach();
        return width + "px";
    };
}());

这可能还需要一些错误检查以确保我们没有被零除,这会在 时发生minWidth == maxWidth,很可能在提供的文本为空时发生。这留给读者作为练习。

另一个更新:这在某个时候坏了。我更新了小提琴以包含以下内容:

        return (width - .1) + "px";

这修复了评论中指出的错误。但我不知道发生了什么变化使其介于两者之间。

于 2013-08-02T15:18:21.683 回答
2

FitText.js是一个很棒的 jQuery 插件。

它会流畅地调整大小(当元素改变大小时,它会修改字体大小,而不仅仅是在文档准备好或加载时),允许最小和最大字体大小,并有一些其他选项可以让您调整其行为。

于 2013-08-02T15:09:00.980 回答
2
function font_size_to_fit(text, fontFamily, divSize) {
  var tester = $("<div/>")
  .appendTo("body")
  .css({
    position: "absolute",
    left: "-9999px",
    fontFamily: fontFamily })
  .html(text);

  var width;
  var fontSize = 72;
  do {
    tester.css("fontSize", fontSize);
    fontSize -= 1;
    width = tester.width();
  } while (!(width <= divSize && width >= divSize * .98));
  return fontSize;
}

也许是这样的?(注意:不解决潜在的浏览器最小字体大小,不想让循环过于复杂。)

(编辑一次以修复一些潜在的错误)

于 2013-08-02T15:05:09.027 回答
1

工作演示

var x = 1;
var y = 20; //staring font-size
txt = "this text should fill the div precisely";
$('#element').html(txt).width(200).height(30).css('font-family', 'arial');
while (x == 1) {
    var element = document.querySelector('#element');
    if ((element.offsetHeight < element.scrollHeight) || (element.offsetWidth < element.scrollWidth)) {
        element.style.background = "yellow";
        element.style.fontSize = parseInt(y) + 'px';
        y--;
    } else {
        x = 0;
        element.style.background = "blue";
    }
}
于 2013-08-02T15:07:45.840 回答