2013-08-02 3 views
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) 
    }); 

Edit: Я прошу функцию, которая вычисляет размер, основанный в straighforward математической формуле. Это может быть приближение. Решение, предложенное по вышеуказанному вопросу, неверно, поскольку оно связано с интерактивной манипуляцией DOM, которая слишком тяжела для размещения в узком месте.

+0

Сделайте текст в другом контейнере/контейнере и проверьте его ширину до тех пор, пока она не совпадет. – NoLifeKing

+0

Это сложнейшая проблема, чем на первый взгляд, поскольку большинство браузеров обеспечивают минимальный размер шрифта. Поэтому, если вы используете цикл для непрерывного сжатия шрифта, вам также нужно проверить, соответствует ли фактический размер шрифта тому же, что и указанный размер шрифта. Если это не так, вы достигли минимума и должны отменить свой цикл. – Blazemonger

+0

Я ценю ввод, но это совсем другая ситуация.В этом вопросе предлагается метод динамически вписывать текст в элемент - это то, что делает решение, используя некоторое время. Я прошу функцию, которая ** рассчитает ** требуемую ширину. Моя функция будет помещена в узкую область, поэтому она должна быть быстрой математической формулой, а не итеративной манипуляцией DOM. – MaiaVictor

ответ

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; 
} 

Возможно, что-то в этом роде? (Примечание: Не учитывает возможные минимальные браузеры размеров шрифта, не хочет, чтобы сделать цикл слишком сложным.)

(ред один раз, чтобы исправить некоторые потенциальные ошибки)

1

Working Demo

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"; 
    } 
} 
2

FitText.js - отличный плагин jQuery для этого.

Он будет изменять размер жидкости (поскольку элемент изменяет размер, он изменит размер шрифта, а не только на готовую или загруженную документацию), позволяет использовать минимальные и максимальные размеры шрифта и имеет некоторые другие параметры, которые позволят вам настроить его поведение.

3

Я никогда не пробовал это, и, возможно, это безумие, но вместо всех (к сожалению, бесполезных) предложений, чтобы приблизиться к этому, изменяя размеры снова и снова, пока текст не подходит, возможно, вы можете попробовать только два очень разных размера шрифта (конечно, без обертки), например 10 и 100, а затем интерполировать или экстраполировать ожидаемое значение, предполагая, что отношение должно быть почти линейным? Я не знаю, стоит ли делать два макета, как это слишком дорого для вашего узкого места. Если это так, я не уверен, какая надежда у вас действительно есть, поскольку шрифты могут быть сложными. Но это может сработать.

Update: Я создал Fiddle, используя эту технику. Кажется, он работает достаточно хорошо. Соответствующий код:

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, скорее всего, когда текст прилагается пуст. Это остается как упражнение для читателя.

Другое обновление: Это сломалось в какой-то момент. Я обновил Fiddle, чтобы включить это:

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

Это исправляет ошибку, отмеченную в комментариях. Но я понятия не имею, что изменилось, чтобы заставить его сломаться между ними.

+0

Работает как прелесть в моем приложении, и для меня это должен быть ответ на этот вопрос. :) Мне нужно, чтобы вычисления были быстрыми, поэтому этот подход для меня действительно лучше. –

+0

@licancabur: Рад, что это работает для вас. Я никогда не звонил сам. Но казалось, что это сработает. –

+0

Скрипка не работала для меня в Chrome. Мне пришлось подстроить несколько вещей: http://jsfiddle.net/webxl/1f0g40bn/ – webXL

Смежные вопросы