我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
我需要显示用户输入的文本到一个固定大小的div。我想要的是字体大小自动调整,以便文本尽可能多地填充框。
如果div是400px x 300px。如果有人输入ABC,那么字体就很大。如果他们输入一个段落,那么它将是一个很小的字体。
我可能想要从最大字体大小开始——可能是32px,当文本太大而不适合容器时,缩小字体大小直到它适合。
当前回答
下面是一种改进的循环方法,它使用二进制搜索在尽可能少的步骤中找到适合父字体的最大可能大小(这比按固定字体大小步进更快更准确)。代码还在几个方面进行了性能优化。
默认情况下,将执行10个二进制搜索步骤,这将在最佳大小的0.1%之内。相反,您可以将numIter设置为某个值N,以获得最佳大小的1/2^N范围内。
用CSS选择器调用它,例如:fittopparent ('.title-span');
/**
* Fit all elements matching a given CSS selector to their parent elements'
* width and height, by adjusting the font-size attribute to be as large as
* possible. Uses binary search.
*/
var fitToParent = function(selector) {
var numIter = 10; // Number of binary search iterations
var regexp = /\d+(\.\d+)?/;
var fontSize = function(elem) {
var match = elem.css('font-size').match(regexp);
var size = match == null ? 16 : parseFloat(match[0]);
return isNaN(size) ? 16 : size;
}
$(selector).each(function() {
var elem = $(this);
var parentWidth = elem.parent().width();
var parentHeight = elem.parent().height();
if (elem.width() > parentWidth || elem.height() > parentHeight) {
var maxSize = fontSize(elem), minSize = 0.1;
for (var i = 0; i < numIter; i++) {
var currSize = (minSize + maxSize) / 2;
elem.css('font-size', currSize);
if (elem.width() > parentWidth || elem.height() > parentHeight) {
maxSize = currSize;
} else {
minSize = currSize;
}
}
elem.css('font-size', minSize);
}
});
};
其他回答
我没有发现任何以前的解决方案是足够的,由于糟糕的性能,所以我自己使用简单的数学,而不是循环。在所有浏览器中都可以正常工作。
根据这个性能测试用例,它比这里找到的其他解决方案快得多。
(function($) {
$.fn.textfill = function(maxFontSize) {
maxFontSize = parseInt(maxFontSize, 10);
return this.each(function(){
var ourText = $("span", this),
parent = ourText.parent(),
maxHeight = parent.height(),
maxWidth = parent.width(),
fontSize = parseInt(ourText.css("fontSize"), 10),
multiplier = maxWidth/ourText.width(),
newSize = (fontSize*(multiplier-0.1));
ourText.css(
"fontSize",
(maxFontSize > 0 && newSize > maxFontSize) ?
maxFontSize :
newSize
);
});
};
})(jQuery);
如果你想投稿,我已经把这个添加到Gist。
我的网站也遇到了同样的问题。我有一个页面,显示在投影仪上,在墙上,大屏幕上。
因为我不知道我的字体的最大大小,我重新使用了@GeekMonkey上面的插件,但增加了字体大小:
$.fn.textfill = function(options) {
var defaults = { innerTag: 'span', padding: '10' };
var Opts = jQuery.extend(defaults, options);
return this.each(function() {
var ourText = $(Opts.innerTag + ':visible:first', this);
var fontSize = parseFloat(ourText.css('font-size'),10);
var doNotTrepass = $(this).height()-2*Opts.padding ;
var textHeight;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
fontSize = fontSize + 2;
} while (textHeight < doNotTrepass );
});
};
编辑:此代码用于在HTML5视频的顶部显示注释。当视频调整大小时(当浏览器窗口调整大小时),它会动态地改变字体大小。注释被连接到视频(就像YouTube上的注释一样),这就是代码使用实例而不是直接使用DOM句柄的原因。
根据请求,我将抛出一些代码,我用来实现这一点。(HTML5视频上方的文本框。)代码是很久以前写的,坦率地说,我认为它相当混乱。因为这个问题已经被回答了,而且答案在很久以前就已经被接受了,所以我就不麻烦重写了。但是如果有人想把这个简化一点,欢迎你!
// Figure out the text size:
var text = val['text'];
var letters = text.length;
var findMultiplier = function(x) { // g(x)
/* By analysing some functions with regression, the resulting function that
gives the best font size with respect to the number of letters and the size
of the note is:
g(x) = 8.3 - 2.75x^0.15 [1 < x < 255]
f(x) = g(letters) * (x / 1000)^0.5
Font size = f(size)
*/
return 8.3 - 2.75 * Math.pow(x, 0.15);
};
var findFontSize = function(x) { // f(x)
return findMultiplier(letters) * Math.pow(x / 1000, 0.5);
};
val.setFontSizeListener = function() {
p.style.fontSize = '1px'; // So the text should not overflow the box when measuring.
var noteStyle = window.getComputedStyle(table);
var width = noteStyle.getPropertyValue('width');
var height = noteStyle.getPropertyValue('height');
var size = width.substring(0, width.length - 2) * height.substring(0, height.length - 2);
p.style.fontSize = findFontSize(size) + 'px';
};
window.addEventListener('resize', val.setFontSizeListener);
您可能需要将这些数字从font-family调整为font-family。一个很好的方法就是下载一个叫做GeoGebra的免费图形可视化工具。更改文本的长度和框的大小。然后手动设置大小。将手工结果绘制到坐标系统中。然后输入我在这里发布的两个方程,然后调整数字,直到“我的”图形符合你自己手动绘制的点。
下面是接受的答案的一个版本,它也可以接受minFontSize参数。
(function($) {
/**
* Resizes an inner element's font so that the inner element completely fills the outer element.
* @author Russ Painter WebDesign@GeekyMonkey.com
* @author Blake Robertson
* @version 0.2 -- Modified it so a min font parameter can be specified.
*
* @param {Object} Options which are maxFontPixels (default=40), innerTag (default='span')
* @return All outer elements processed
* @example <div class='mybigdiv filltext'><span>My Text To Resize</span></div>
*/
$.fn.textfill = function(options) {
var defaults = {
maxFontPixels: 40,
minFontPixels: 10,
innerTag: 'span'
};
var Opts = jQuery.extend(defaults, options);
return this.each(function() {
var fontSize = Opts.maxFontPixels;
var ourText = $(Opts.innerTag + ':visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > Opts.minFontPixels);
});
};
})(jQuery);
这是我最后得到的结果:
这是该插件的链接:https://plugins.jquery.com/textfill/ 还有一个来源的链接:http://jquery-textfill.github.io/
;(function($) {
$.fn.textfill = function(options) {
var fontSize = options.maxFontPixels;
var ourText = $('span:visible:first', this);
var maxHeight = $(this).height();
var maxWidth = $(this).width();
var textHeight;
var textWidth;
do {
ourText.css('font-size', fontSize);
textHeight = ourText.height();
textWidth = ourText.width();
fontSize = fontSize - 1;
} while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
return this;
}
})(jQuery);
$(document).ready(function() {
$('.jtextfill').textfill({ maxFontPixels: 36 });
});
我的HTML是这样的
<div class='jtextfill' style='width:100px;height:50px;'>
<span>My Text Here</span>
</div>