사용자가 입력 한 텍스트를 고정 크기 div로 표시해야합니다. 내가 원하는 것은 텍스트가 가능한 한 상자를 채우도록 글꼴 크기를 자동으로 조정하는 것입니다.
따라서-div가 400px x 300px 인 경우. 누군가가 ABC를 입력하면 정말 큰 글꼴입니다. 문단을 입력하면 작은 글꼴이됩니다.
아마도 최대 글꼴 크기로 시작하고 싶을 것입니다-아마도 32px이며 텍스트가 너무 커서 컨테이너에 맞지 않을 때까지 글꼴 크기를 줄이십시오.
답변
감사 공격 . 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>
이것은 첫 번째 jquery 플러그인이므로 아마도 좋지 않을 것입니다. 포인터는 확실히 환영합니다.
답변
이전 솔루션 중 성능이 좋지 않아 충분히 적합한 솔루션을 찾지 못했기 때문에 루핑 대신 간단한 수학을 사용하는 솔루션을 만들었습니다. 모든 브라우저에서도 잘 작동합니다.
이 성능 테스트 사례 에 따르면 여기에있는 다른 솔루션보다 훨씬 빠릅니다.
(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에 추가 했습니다 .
답변
내가이 답변에 대해 가끔씩 공감하는 것을 좋아하는만큼 (감사합니다!), 이것은 실제로이 문제에 대한 가장 큰 접근법은 아닙니다. 다른 멋진 답변, 특히 반복하지 않고 솔루션을 찾은 답변을 확인하십시오.
아직도, 참고로 여기에 내 원래의 대답이 있습니다 .
<html>
<head>
<style type="text/css">
#dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textSpan = document.getElementById("dynamicSpan");
var textDiv = document.getElementById("dynamicDiv");
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
</script>
</head>
<body onload="shrink()">
<div id="dynamicDiv"><span id="dynamicSpan">DYNAMIC FONT</span></div>
</body>
</html>
다음은 클래스 가있는 버전입니다 .
<html>
<head>
<style type="text/css">
.dynamicDiv
{
background: #CCCCCC;
width: 300px;
height: 100px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textDivs = document.getElementsByClassName("dynamicDiv");
var textDivsLength = textDivs.length;
// Loop through all of the dynamic divs on the page
for(var i=0; i<textDivsLength; i++) {
var textDiv = textDivs[i];
// Loop through all of the dynamic spans within the div
var textSpan = textDiv.getElementsByClassName("dynamicSpan")[0];
// Use the same looping logic as before
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
}
</script>
</head>
<body onload="shrink()">
<div class="dynamicDiv"><span class="dynamicSpan">DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">ANOTHER DYNAMIC FONT</span></div>
<div class="dynamicDiv"><span class="dynamicSpan">AND YET ANOTHER DYNAMIC FONT</span></div>
</body>
</html>
답변
다른 답변의 대부분은 div에 맞을 때까지 글꼴 크기를 줄이기 위해 루프를 사용합니다. 글꼴 크기가 변경 될 때마다 페이지가 요소를 다시 렌더링해야하기 때문에 매우 느립니다. 결국 사용자 브라우저를 멈추지 않고 주기적으로 내용을 업데이트 할 수있는 방식으로 자체 알고리즘을 작성해야했습니다. 다른 기능 (텍스트 회전, 패딩 추가)을 추가하고 jQuery 플러그인으로 패키지하면 다음에서 얻을 수 있습니다.
https://github.com/DanielHoffmann/jquery-bigtext
단순히 전화
$("#text").bigText();
컨테이너에 잘 맞습니다.
여기에서 실제로보십시오 :
http://danielhoffmann.github.io/jquery-bigtext/
현재로서는 몇 가지 제한 사항이 있으므로 div의 높이와 너비는 고정되어 있어야하며 여러 줄로 텍스트 줄 바꿈을 지원하지 않습니다.
최대 글꼴 크기를 설정하는 옵션을 얻는 중입니다.
편집 : 플러그인에 더 많은 문제가 있음을 발견했습니다. 표준 모델 이외의 다른 상자 모델을 처리하지 않으며 div에 여백이나 테두리를 가질 수 없습니다. 나는 그것을 할 것입니다.
Edit2 : 나는 이제 이러한 문제와 한계를 수정하고 더 많은 옵션을 추가했습니다. 최대 글꼴 크기를 설정할 수 있으며 너비, 높이 또는 둘 다를 사용하여 글꼴 크기를 제한하도록 선택할 수도 있습니다. 래퍼 요소에서 최대 너비 및 최대 높이 값을 허용하도록 노력하겠습니다.
Edit3 : 플러그인을 버전 1.2.0으로 업데이트했습니다. 코드 및 새로운 옵션 (verticalAlign, horizontalAlign, textAlign)에 대한 주요 정리 및 span 태그 내부의 내부 요소 지원 (줄 바꿈 또는 멋진 아이콘)
답변
이것은 GeekyMonkey가 위에 게시 한 내용을 기반으로하며 약간 수정되었습니다.
; (function($) {
/**
* Resize inner element to fit the outer element
* @author Some modifications by Sandstrom
* @author Code based on earlier works by Russ Painter (WebDesign@GeekyMonkey.com)
* @version 0.2
*/
$.fn.textfill = function(options) {
options = jQuery.extend({
maxFontSize: null,
minFontSize: 8,
step: 1
}, options);
return this.each(function() {
var innerElements = $(this).children(':visible'),
fontSize = options.maxFontSize || innerElements.css("font-size"), // use current font-size by default
maxHeight = $(this).height(),
maxWidth = $(this).width(),
innerHeight,
innerWidth;
do {
innerElements.css('font-size', fontSize);
// use the combined height of all children, eg. multiple <p> elements.
innerHeight = $.map(innerElements, function(e) {
return $(e).outerHeight();
}).reduce(function(p, c) {
return p + c;
}, 0);
innerWidth = innerElements.outerWidth(); // assumes that all inner elements have the same width
fontSize = fontSize - options.step;
} while ((innerHeight > maxHeight || innerWidth > maxWidth) && fontSize > options.minFontSize);
});
};
})(jQuery);
답변
다음은 이진 검색을 사용하여 가능한 가장 작은 단계에서 부모에 맞는 가장 큰 크기를 찾는 향상된 루핑 방법입니다 (고정 된 글꼴 크기로 스테핑하는 것보다 빠르고 정확합니다). 코드는 성능을 위해 여러 가지 방법으로 최적화됩니다.
기본적으로 10 개의 이진 검색 단계가 수행되며 최적 크기의 0.1 % 이내가됩니다. 대신 numIter를 값 N으로 설정하여 최적 크기의 1 / 2 ^ N 이내로 만들 수 있습니다.
CSS 선택기로 호출하십시오. 예 : fitToParent('.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);
}
});
};
답변
AngularJS에 대한 지시문을 만들었습니다 .GeekyMonkey의 답변에서 영감을 얻었지만 jQuery 종속성은 없습니다.
데모 : http://plnkr.co/edit/8tPCZIjvO3VSApSeTtYr?p=preview
마크 업
<div class="fittext" max-font-size="50" text="Your text goes here..."></div>
지령
app.directive('fittext', function() {
return {
scope: {
minFontSize: '@',
maxFontSize: '@',
text: '='
},
restrict: 'C',
transclude: true,
template: '<div ng-transclude class="textContainer" ng-bind="text"></div>',
controller: function($scope, $element, $attrs) {
var fontSize = $scope.maxFontSize || 50;
var minFontSize = $scope.minFontSize || 8;
// text container
var textContainer = $element[0].querySelector('.textContainer');
angular.element(textContainer).css('word-wrap', 'break-word');
// max dimensions for text container
var maxHeight = $element[0].offsetHeight;
var maxWidth = $element[0].offsetWidth;
var textContainerHeight;
var textContainerWidth;
var resizeText = function(){
do {
// set new font size and determine resulting dimensions
textContainer.style.fontSize = fontSize + 'px';
textContainerHeight = textContainer.offsetHeight;
textContainerWidth = textContainer.offsetWidth;
// shrink font size
var ratioHeight = Math.floor(textContainerHeight / maxHeight);
var ratioWidth = Math.floor(textContainerWidth / maxWidth);
var shrinkFactor = ratioHeight > ratioWidth ? ratioHeight : ratioWidth;
fontSize -= shrinkFactor;
} while ((textContainerHeight > maxHeight || textContainerWidth > maxWidth) && fontSize > minFontSize);
};
// watch for changes to text
$scope.$watch('text', function(newText, oldText){
if(newText === undefined) return;
// text was deleted
if(oldText !== undefined && newText.length < oldText.length){
fontSize = $scope.maxFontSize;
}
resizeText();
});
}
};
});