Comments (16)
Hey, thanks for being a personal beta tester. Could you post a jsfiddle?
from textfit.
Ha! No problem :)
http://jsbin.com/EbaR/1
Will this suffice? It's alot of code but it's from the context it's being used.
from textfit.
See http://jsbin.com/EbaR/3/edit
I can't tell without context of the application this code is in, but it seems awfully complicated for what it does. You may be able to get much better results by simply using percentage widths and heights on your centered div, rather than using JS to resize it. For example:
.container {
position: absolute;
height: 20%;
width: 30%;
left: 50%;
top: 50%;
text-align: center;
margin-left: -15%;
margin-top: -10%;
}
I did commit a fix to a bug that occurs when you nest elements inside the element you're resizing - it needed to be display: inline-block so that it resized correctly to its contents.
For example, if I use percentages I can simplify your code dramatically: http://jsbin.com/uMiW/3/edit
from textfit.
I'm keeping this ticket open for now because I want to ensure this works with alignVert, and it doesn't seem to yet.
from textfit.
That did it! But as you say, there's a trouble with alignVert when you cannot use display: table
. Not sure if it can be circumvented without js?
Thanks for your input by the way, my code is very complex for what it does in this demo, but on the site it handles images and videos with specific ratios, that's why, wasn't sure that any of it were interfering with your script.
from textfit.
@STRML Any idea of a work around? Been trying to hack my way around but with no luck. Really need the possibility to center both vertically and horizontally.
from textfit.
Hi STRML,
Firstly, this is a superb bit of JQuery. Love it.
I am relatively new to Javascript, and I have it working perfectly on initial page load, however, I also want the function to work on $(window).resize(function() .....
.
I have a one page website and the top element resizes dynamically with the window resize action as I wanted. As you will see below, the textFit call is in the same function, but does not work like the element resizing code does when resizing window.
function navNscroll(resizing){
var homePage = ("#homepage");
var headerHeight = $("#header").height(); // scrollHeight
var viewportHeight = $(window).height(); //scrollHeight
var homepagePadding = $(homepage).outerHeight() - $(homepage).height(); // scrollHeight
//var homepagePadding = $(homepageh).outerHeight(true);
var percentFactor = 0.66;
var heightAvailable = viewportHeight - headerHeight;
var homepageHeight = heightAvailable - homepagePadding;
homepageHeight = homepageHeight - parseInt($(".midbanner.one").css("margin-top"),10);
homepageHeight = homepageHeight * percentFactor;
remainder = heightAvailable - homepageHeight;
parseInt(homepageHeight);
var paddingVal = 20;
var homepageWidth = parseInt($(homePage).innerWidth(), 10) - (paddingVal * 2);
function fitText() {
$(homePage).height(homepageHeight).css("margin-bottom",remainder);
$(".midbanner.one .text").css("padding", paddingVal);
$('.bigText').css("width",homepageWidth).css("height", (homepageHeight - (paddingVal *2)));
$('.bigText').textFit({multiLine:true, alignVert:true, lineHeight:1.4, maxFontSize:40});
}
fitText();
if (resizing == "yes"){
fitText(); // tried this because I ran out of ideas
}
}
$(window).resize(function() {
navNscroll('yes');
});
I have also slightly changed your textFit.js code so I can control line-height:
(function($) {
$.fn.textFit = function(options) {
var settings = {
alignVert: false, // if true, textFit will align vertically using css tables
alignHoriz: false, // if true, textFit will set text-align: center
multiLine: true, // if true, textFit will not set white-space: no-wrap
detectMultiLine: true, // disable to turn off automatic multi-line sensing
minFontSize: 6,
maxFontSize: 80,
reProcess: false, // if true, textFit will re-process already-fit nodes. Leave to 'false' for better performance
widthOnly: false, // if true, textFit will fit text to element width, regardless of text height
lineHeight: 1.2 // JBReading: default is 1.2 x font-size
};
$.extend(settings, options);
return this.each(function(){
if (this.length === 0 || (!settings.reProcess && $(this).data('boxfitted'))) {
return $(this);
}
if(!settings.reProcess){
$(this).data('boxfitted', 1);
}
var innerSpan, originalHeight, originalText, originalWidth;
var low, mid, high;
originalText = $(this).html();
$(this).html("");
originalWidth = $(this).width();
originalHeight = $(this).height();
// Don't process if we can't find box dimensions
if (!originalWidth || (!settings.widthOnly && !originalHeight)) {
if (window.console != null) {
if(!settings.widthOnly)
console.info('Set a static height and width on the target element' + this.outerHTML +
' before using textFit!');
else
console.info('Set a static width on the target element' + this.outerHTML +
' before using textFit!');
}
return $(this).html(originalText);
} else {
// Add textfitted span
if (originalText.indexOf('textfitted') === -1) {
innerSpan = $("<span></span>").addClass("textfitted").html(originalText);
$(this).html(innerSpan);
} else {
$(this).html(originalText);
innerSpan = $(originalText).find('span.textfitted');
$(innerSpan).addClass("foundit");
// innerSpan = $("span.textfitted");
}
// Prepare & set alignment
if (settings.alignVert) {
$(this).css("display", "table");
innerSpan.css("display", "table-cell");
innerSpan.css("vertical-align", "middle");
}
if (settings.alignHoriz) {
$(this).css("text-align", "center");
innerSpan.css("text-align", "center");
}
// Check if this string is multiple lines
// Not guaranteed to always work if you use wonky line-heights
if (settings.detectMultiLine && !settings.multiLine &&
innerSpan.height() >= parseInt(innerSpan.css('font-size'), 10) * 2){
settings.multiLine = true;
}
if (!settings.multiLine) {
$(this).css('white-space', 'nowrap');
}
low = settings.minFontSize + 1;
high = settings.maxFontSize + 1;
// Binary search for best fit
while ( low <= high) {
mid = parseInt((low + high) / 2, 10);
innerSpan.css('font-size', mid);
if(innerSpan.width() <= originalWidth && (settings.widthOnly || innerSpan.height() <= originalHeight)){
low = mid + 1;
} else {
high = mid - 1;
}
}
// Sub 1
subOne = mid - 1;
innerSpan.css('font-size', subOne);
// JBReading:
newLineHeight = subOne * settings.lineHeight;
$(this).css('line-height', newLineHeight+"px");
}
});
};
})(jQuery);
The HTML:
<div class="midbanner one" id="homepage">
<div class="text fullwidth" >
<span class="bigText" style="width:300px;height:300px">
In eget tellus quis diam imperdiet condimentum sed quis mauris. Praesent enim purus, aliquet et mauris nec, malesuada luctus purus. Sed nec sapien semper, mattis purus vel, vehicula enim. Nulla vitae sagittis eros. Morbi risus magna, convallis in fringilla vitae, tempor sit amet quam. Cras aliquet diam nulla, a accumsan eros elementum sit amet. Duis molestie leo ac lorem convallis, et porttitor enim dictum.
</span>
<p class="clear"> </p>
</div>
</div><!-- end of midbanner one -->
Any ideas on this?
Thanks in advance.
from textfit.
First of all, @intelligence, sorry for not getting back to you. I'm exploring a vertical alignment strategy that eschews the table and table-cell stylings for a simple margin-top property equal to the (height of the container - the height of the inner span) / 2. Should be relatively simple. You could probably hack something like that in yourself, or wait, I'll likely put it in later as your test case has shown that display:table is really quite fiddly. I will need to do some testing to be sure that it doesn't break anything.
If you want to fix it, try the following around your textFit()
calls (with alignVert:false)
$(".textFitted").css("margin-top", 0);
textFit(...)
var margin = ($(".content").height() - $(".textFitted").height()) / 2;
$(".textFitted").css("margin-top", margin + "px");
from textfit.
@JBReading , feel free to open another issue if you have an unrelated question. But since you posted here, I'll answer here for now.
First, textFit has a reProcess
option. If it's set to true
, it will re-process an already-fitted node. This is necessary if you want to resize something again. I may flip the option in the future so it works this way by default; it won't break existing code though. In your case, you'll want to pass {reProcess: true}
.
Secondly, no need to modify the code to add line-height. Simply use CSS to set a line height of 1.2em on the container.
from textfit.
Hey @STRML! That's no problem, I realize that you probably don't maintain the plugin for a living :)
I tried your quick fix, it works well! Although it seems it goes a bit off when you resize.
Have a look at my implementation here: http://eplusp.se/spotify-facebook/
Username is: dev
Password is: lolboy
from textfit.
I took a look at it. There's something bizarre going on - basically, here's what I see:
Your automatic resizer is moving the container element around and it'll end up with a negative margin of some fractional number of px. I'll give you an example from what I see right now:
style="width: 555px; height: 295.2127659574468px; margin-left: -277.5px; margin-top: -147.6063829787234px; text-align: center;"
The issue is that the browser is doing some rounding here. In this particular case, the container has an offsetWidth of 555px
but the inner span has an offsetWidth of 556px
! On every measurement cycle, textFit
checks the width and sees if it has become bigger than its parent. The problem is, in every single case, it's bigger than its parent because of this bug, even when the text is too small to read. This is something I haven't seen before but it sort of makes sense; basically it's rounding on the fractional amounts a little incorrectly. Best I can tell is, the inner span is being aligned one px farther left on the pixel grid than its parent, resulting in it being one px larger when measured. Pretty weird!
The fix is pretty simple: in your resize function around line 1050, surround all your calculations that are being entered into .css()
in parseInt(value, 10)
calls. This will round them down to an integer value. Be especially careful to round the final values, not the intermediate ones. For example:
$this.find('section .content').each(function(){ // no need for additional $() wrapper
var t = { width: 940, height: 500, retina: false }
var d = ep.projects.calculate( t )
$(this)
.css('width', parseInt(d.w, 10))
.css('height', parseInt(d.h, 10))
.css({ marginTop: '-'+parseInt(d.h/2, 10)+'px', marginLeft: '-'+parseInt(d.w/2, 10)+'px' })
})
Good luck with the app!
Edit: You may have some luck with this novel centering technique.
Edit 2: I've illustrated the inner width problem. Play around with resizing the window and watch your console. It's achievable via simple percentage widths for the same reason. I've only tested in Chrome but it may happen elsewhere.
from textfit.
97a6ecf should help you with alignVert.
from textfit.
Wow, thanks, was not aware of that technique! The vertical align seems to work well but now it seems we're back to the issue where the font-size will not updated on resize. Stays on 32px while I'm narrowing the browser then it jumps straight to 6px.
from textfit.
You didn't update the textFit version.
from textfit.
Are you sure? I checked it and saw that a new class was applied with the new css. I grabbed the minified version.
.textFitAlignVert {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
}
Edit: Tried with the full aswell, but same issue.
Edit2: And the updated version seem to say v2.0.
from textfit.
Please open a new issue if you're still having problems.
from textfit.
Related Issues (20)
- textFit gives error saying "you didn't set a static height and width" but I did. HOT 1
- Fit all the <p> inside a div HOT 2
- Example page doesn't work (Wrong link?) HOT 2
- Support height-only/dynamic width?
- Doesn't work on "hidden" elements HOT 3
- accept string as well HOT 3
- Invalid scaling caused by inconsistency between innerspan.scrollWidth and el.clientWidth HOT 1
- Hassle free my ass
- Do not throw error when width or height is zero
- Max lines option
- Text from input box only appearing on single line HOT 1
- The type definition file is missing from the published NPM package
- TextFit not working with ul/ol
- Line-height and timing issues. HOT 2
- Safari is not considering height of container HOT 1
- It make my border and background color disapear
- CDN I can directly import with link? HOT 1
- Handle splitting of long URLs so that the overall text occupies space per configuration HOT 3
- How to force or detect new line by textarea
- Does not work properly when animating font-size HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from textfit.