Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added a minCharsPerLine parameter

  • Loading branch information...
commit 310e0c97e2b7d7e6d3ffabb166155c50c6e80a61 1 parent 464d479
@freqdec authored
Showing with 54 additions and 33 deletions.
  1. +23 −13 index.html
  2. +29 −18 js/jquery.slabtext.js
  3. +2 −2 js/jquery.slabtext.min.js
View
36 index.html
@@ -70,6 +70,10 @@
{
text-decoration:none;
}
+ h1 a:hover
+ {
+ color:#a82222;
+ }
p
{
margin:0 0 1.5em 0;
@@ -252,6 +256,8 @@ <h2 id="h7">Plugin options</h2>
<dd>An Integer value that indicates the decimal precision to use when setting the CSS values <code>line-height</code>, <code>word-spacing</code> and <code>font-size</code>. Defaults to 3.</dd>
<dt>postTweak</dt>
<dd>A Boolean value that instructs the script to tweak the lineheight or word spacing after the fontsize calculation has been ran (TRUE) or not (FALSE). Defaults to TRUE.</dd>
+ <dt>minCharsPerLine</dt>
+ <dd>An optional Integer value that indicates the minimum number of characters to set per line. Headlines that have a character count smaller than this value are not given the slabText treatment.</dd>
</dl>
<p>It&#8217;s also worth noting that any non-breaking space character used to prevent widowed words within the original, non-adjusted headline will also be included within the adjusted headline.</p>
<h2 id="h8">A note on the CSS</h2>
@@ -292,7 +298,7 @@ <h2 id="h9">Buyer beware</h2>
<li>Unlike the original <a href="http://erikloyer.com/index.php/blog/the_slabtype_algorithm_part_1_background/">slabtype algorithm</a>, vertical space is not taken into consideration at all.</li>
<li>I&#8217;ve no idea how the script behaves in a right-to-left environment.</li>
<li>If the header contains multiple links, only the first link located is taken into account.</li>
- <li>Internet Explorer 6, due to its non-support of <code>inline-block</code>, cannot scale <em>down</em> the text when the browser viewport is reduced in width. This will not be an issue if you serve a fixed width design to IE6 and fluid width design to other browsers.</li>
+ <li>Internet Explorer 6, due to its non-support of <code>inline-block</code>, cannot scale <em>down</em> the text when the browser viewport is reduced in width. This will not be an issue if you serve a fixed width design to IE6 and fluid width design to other, more capable browsers.</li>
<li>Internet Explorer &lt; 8 does not support the CSS value of <code>inherit</code> which means that the <code>letter-spacing</code> and <code>word-spacing</code> have to get reset to zero whenever the slabText treatment is removed by the script.</li>
<li>Always call the script <em>after</em> all <code>fontface</code> fonts have downloaded. I&#8217;ve hacked this for the demo to enable you to see the headline transformation as the script kicks-in but you should always use google WebFont loaders <code>active()</code> and <code>inactive()</code> callbacks to launch the slabText treatment (or a similar "font loaded" callback feature from another font provider).</li>
</ol>
@@ -343,19 +349,23 @@ <h2 id="h12">A few more examples</h2>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<script src="./js/jquery.slabtext.min.js"></script>
<script>
- // Function to slabtext the H1 headings
- function slabTextHeadlines() {
- $("h1").slabText({
- // Don't slabtext the headers if the viewport is under 380px
- "viewportBreakpoint":380
- });
- };
-
- // Called one second after the onload event for the demo (as I'm hacking the fontface load event a bit here)
- // you should really use google WebFont loader events (or something similar) for better control
- $(window).load(function() {
- setTimeout(slabTextHeadlines, 1000);
+ // Function to slabtext the H1 headings
+ function slabTextHeadlines() {
+ $("h1").slabText({
+ // Don't slabtext the headers if the viewport is under 380px
+ "viewportBreakpoint":380
});
+ };
+
+ // Called one second after the onload event for the demo (as I'm hacking the
+ // fontface load event a bit here)
+
+ // Please do not do this in a production environment - you should really use
+ // google WebFont loader events (or something similar) for better control
+ $(window).load(function() {
+ // So, to recap... don't actually do this, it's nasty!
+ setTimeout(slabTextHeadlines, 1000);
+ });
</script>
</body>
</html>
View
47 js/jquery.slabtext.js
@@ -1,4 +1,4 @@
-/*! jQuery slabtext plugin v2.1 MIT/GPL2 @freqdec */
+/*! jQuery slabtext plugin v2.2 MIT/GPL2 @freqdec */
(function( $ ){
$.fn.slabText = function(options) {
@@ -24,7 +24,9 @@
// Do we try to tweak the letter-spacing or word-spacing?
"postTweak" : true,
// Decimal precision to use when setting CSS values
- "precision" : 3
+ "precision" : 3,
+ // The min num of chars a line has to contain
+ "minCharsPerLine" : 0
};
// Add the slabtexted classname to the body to initiate the styling of
@@ -33,8 +35,7 @@
return this.each(function(){
- // Extend options if necessary
- if(options) {
+ if(options) {
$.extend(settings, options);
};
@@ -50,11 +51,16 @@
postTweak = settings.postTweak,
precision = settings.precision,
resizeThrottleTime = settings.resizeThrottleTime,
+ minCharsPerLine = settings.minCharsPerLine,
resizeThrottle = null,
viewportWidth = $(window).width(),
headLink = $this.find("a:first").attr("href") || $this.attr("href"),
linkTitle = headLink ? $this.find("a:first").attr("title") : "";
+ if(!keepSpans && minCharsPerLine && words.join(" ").length < minCharsPerLine) {
+ return;
+ };
+
// Calculates the pixel equivalent of 1em within the current header
var grabPixelFontSize = function() {
var dummy = jQuery('<div style="display:none;font-size:1em;margin:0;padding:0;height:auto;line-height:1;border:0;">&nbsp;</div>').appendTo($this),
@@ -80,7 +86,7 @@
||
headerBreakpoint && headerBreakpoint > parentWidth) {
// Add the slabtextinactive classname to set the spans as inline
- // and to reset the font-size to 1em (inherit won't work in IE7)
+ // and to reset the font-size to 1em (inherit won't work in IE6/7)
$this.addClass("slabtextinactive");
return;
};
@@ -100,6 +106,7 @@
preText = "",
postText = "",
finalText = "",
+ slice,
preDiff,
postDiff;
@@ -122,15 +129,26 @@
};
};
+ // This bit hacks in a minimum characters per line test
+ // on the last line
+ if(minCharsPerLine) {
+ slice = words.slice(wordIndex).join(" ");
+ if(slice.length < minCharsPerLine) {
+ postText += slice;
+ preText = postText;
+ wordIndex = words.length + 2;
+ };
+ };
+
// calculate the character difference between the two strings and the
// ideal number of characters per line
preDiff = idealCharPerLine - preText.length;
postDiff = postText.length - idealCharPerLine;
// if the smaller string is closer to the length of the ideal than
- // the longer string, and doesn’t contain just a single character, then
- // use that one for the line
- if((preDiff < postDiff) && (preText.length > 2)) {
+ // the longer string, and doesn’t contain less than minCharsPerLine
+ // characters, then use that one for the line
+ if((preDiff < postDiff) && (preText.length >= (minCharsPerLine || 2))) {
finalText = preText;
wordIndex--;
// otherwise, use the longer string for the line
@@ -144,7 +162,7 @@
// Wrap ampersands in spans with class `amp` for specific styling
if(settings.wrapAmpersand) {
finalText = finalText.replace(/&amp;/g, '<span class="amp">&amp;</span>');
- }
+ };
finalText = $.trim(finalText)
@@ -153,7 +171,7 @@
$this.html(lineText.join(" "));
// If we have a headLink, add it back just inside our target, around all the slabText spans
- if (headLink) {
+ if(headLink) {
$this.wrapInner('<a href="' + headLink + '" ' + (linkTitle ? 'title="' + linkTitle + '" ' : '') + '/>');
};
};
@@ -163,7 +181,6 @@
origFontSize = fs;
};
- // Loop through the spans changing font-size accordingly
$("span.slabtext", $this).each(function() {
var $span = $(this),
// the .text method appears as fast as using custom -data attributes in this case
@@ -183,7 +200,6 @@
ratio = parentWidth / $span.width();
fontSize = parseFloat(this.style.fontSize) || origFontSize;
- // Resize font
$span.css("font-size", Math.min((fontSize * ratio).toFixed(precision), settings.maxFontSize) + "px");
// Do we still have space to try to fill or crop
@@ -206,20 +222,15 @@
resizeSlabs();
if(!settings.noResizeEvent) {
- // Window resize event
$(window).resize(function() {
// Only run the resize code if the viewport width has changed.
- // we ignore the viewport height as it will be constantly changing
- // due to the font-size resizing and IE fires a resize event whenever
- // vertical height has changed leading to an endless loop and
- // locked browser.
+ // we ignore the viewport height as it will be constantly changing.
if($(window).width() == viewportWidth) {
return;
};
viewportWidth = $(window).width();
- // Throttle the resize event to 300ms
clearTimeout(resizeThrottle);
resizeThrottle = setTimeout(resizeSlabs, resizeThrottleTime);
});
View
4 js/jquery.slabtext.min.js
@@ -1,2 +1,2 @@
-/*! jQuery slabtext plugin v2.1 MIT/GPL2 @freqdec */
-(function($){$.fn.slabText=function(options){var settings={fontRatio:0.78,forceNewCharCount:true,wrapAmpersand:true,headerBreakpoint:null,viewportBreakpoint:null,noResizeEvent:false,resizeThrottleTime:300,maxFontSize:999,postTweak:true,precision:3};$("body").addClass("slabtexted");return this.each(function(){if(options){$.extend(settings,options);}var $this=$(this),keepSpans=$("span.slabtext",$this).length,words=keepSpans?[]:String($.trim($this.text())).replace(/\s{2,}/g," ").split(" "),origFontSize=null,idealCharPerLine=null,fontRatio=settings.fontRatio,forceNewCharCount=settings.forceNewCharCount,headerBreakpoint=settings.headerBreakpoint,viewportBreakpoint=settings.viewportBreakpoint,postTweak=settings.postTweak,precision=settings.precision,resizeThrottleTime=settings.resizeThrottleTime,resizeThrottle=null,viewportWidth=$(window).width(),headLink=$this.find("a:first").attr("href")||$this.attr("href"),linkTitle=headLink?$this.find("a:first").attr("title"):"";var grabPixelFontSize=function(){var dummy=jQuery('<div style="display:none;font-size:1em;margin:0;padding:0;height:auto;line-height:1;border:0;">&nbsp;</div>').appendTo($this),emH=dummy.height();dummy.remove();return emH;};var resizeSlabs=function resizeSlabs(){var parentWidth=$this.width(),fs;$this.removeClass("slabtextdone slabtextinactive");if(viewportBreakpoint&&viewportBreakpoint>viewportWidth||headerBreakpoint&&headerBreakpoint>parentWidth){$this.addClass("slabtextinactive");return;}fs=grabPixelFontSize();if(!keepSpans&&(forceNewCharCount||fs!=origFontSize)){origFontSize=fs;var newCharPerLine=Math.min(60,Math.floor(parentWidth/(origFontSize*fontRatio))),wordIndex=0,lineText=[],counter=0,preText="",postText="",finalText="",preDiff,postDiff;if(newCharPerLine!=idealCharPerLine){idealCharPerLine=newCharPerLine;while(wordIndex<words.length){postText="";while(postText.length<idealCharPerLine){preText=postText;postText+=words[wordIndex]+" ";if(++wordIndex>=words.length){break;}}preDiff=idealCharPerLine-preText.length;postDiff=postText.length-idealCharPerLine;if((preDiff<postDiff)&&(preText.length>2)){finalText=preText;wordIndex--;}else{finalText=postText;}lineText.push('<span class="slabtext">'+$.trim(settings.wrapAmpersand?finalText.replace("&",'<span class="amp">&amp;</span>'):finalText)+"</span>");}$this.html(lineText.join(" "));if(headLink){$this.wrapInner('<a href="'+headLink+'" '+(linkTitle?'title="'+linkTitle+'" ':"")+"/>");}}}else{origFontSize=fs;}$("span.slabtext",$this).each(function(){var $span=$(this),innerText=$span.text(),wordSpacing=innerText.split(" ").length>1,diff,ratio,fontSize;if(postTweak){$span.css({"word-spacing":0,"letter-spacing":0});}ratio=parentWidth/$span.width();fontSize=parseFloat(this.style.fontSize)||origFontSize;$span.css("font-size",Math.min((fontSize*ratio).toFixed(precision),settings.maxFontSize)+"px");diff=!!postTweak?parentWidth-$span.width():false;if(diff){$span.css((wordSpacing?"word":"letter")+"-spacing",(diff/(wordSpacing?innerText.split(" ").length-1:innerText.length)).toFixed(precision)+"px");}});$this.addClass("slabtextdone");};resizeSlabs();if(!settings.noResizeEvent){$(window).resize(function(){if($(window).width()==viewportWidth){return;}viewportWidth=$(window).width();clearTimeout(resizeThrottle);resizeThrottle=setTimeout(resizeSlabs,resizeThrottleTime);});}});};})(jQuery);
+/*! jQuery slabtext plugin v2.2 MIT/GPL2 @freqdec */
+(function($){$.fn.slabText=function(options){var settings={fontRatio:0.78,forceNewCharCount:true,wrapAmpersand:true,headerBreakpoint:null,viewportBreakpoint:null,noResizeEvent:false,resizeThrottleTime:300,maxFontSize:999,postTweak:true,precision:3,minCharsPerLine:0};$("body").addClass("slabtexted");return this.each(function(){if(options){$.extend(settings,options);}var $this=$(this),keepSpans=$("span.slabtext",$this).length,words=keepSpans?[]:String($.trim($this.text())).replace(/\s{2,}/g," ").split(" "),origFontSize=null,idealCharPerLine=null,fontRatio=settings.fontRatio,forceNewCharCount=settings.forceNewCharCount,headerBreakpoint=settings.headerBreakpoint,viewportBreakpoint=settings.viewportBreakpoint,postTweak=settings.postTweak,precision=settings.precision,resizeThrottleTime=settings.resizeThrottleTime,minCharsPerLine=settings.minCharsPerLine,resizeThrottle=null,viewportWidth=$(window).width(),headLink=$this.find("a:first").attr("href")||$this.attr("href"),linkTitle=headLink?$this.find("a:first").attr("title"):"";if(!keepSpans&&minCharsPerLine&&words.join(" ").length<minCharsPerLine){return;}var grabPixelFontSize=function(){var dummy=jQuery('<div style="display:none;font-size:1em;margin:0;padding:0;height:auto;line-height:1;border:0;">&nbsp;</div>').appendTo($this),emH=dummy.height();dummy.remove();return emH;};var resizeSlabs=function resizeSlabs(){var parentWidth=$this.width(),fs;$this.removeClass("slabtextdone slabtextinactive");if(viewportBreakpoint&&viewportBreakpoint>viewportWidth||headerBreakpoint&&headerBreakpoint>parentWidth){$this.addClass("slabtextinactive");return;}fs=grabPixelFontSize();if(!keepSpans&&(forceNewCharCount||fs!=origFontSize)){origFontSize=fs;var newCharPerLine=Math.min(60,Math.floor(parentWidth/(origFontSize*fontRatio))),wordIndex=0,lineText=[],counter=0,preText="",postText="",finalText="",slice,preDiff,postDiff;if(newCharPerLine!=idealCharPerLine){idealCharPerLine=newCharPerLine;while(wordIndex<words.length){postText="";while(postText.length<idealCharPerLine){preText=postText;postText+=words[wordIndex]+" ";if(++wordIndex>=words.length){break;}}if(minCharsPerLine){slice=words.slice(wordIndex).join(" ");if(slice.length<minCharsPerLine){postText+=slice;preText=postText;wordIndex=words.length+2;}}preDiff=idealCharPerLine-preText.length;postDiff=postText.length-idealCharPerLine;if((preDiff<postDiff)&&(preText.length>=(minCharsPerLine||2))){finalText=preText;wordIndex--;}else{finalText=postText;}finalText=$("<div/>").text(finalText).html();if(settings.wrapAmpersand){finalText=finalText.replace(/&amp;/g,'<span class="amp">&amp;</span>');}finalText=$.trim(finalText);lineText.push('<span class="slabtext">'+finalText+"</span>");}$this.html(lineText.join(" "));if(headLink){$this.wrapInner('<a href="'+headLink+'" '+(linkTitle?'title="'+linkTitle+'" ':"")+"/>");}}}else{origFontSize=fs;}$("span.slabtext",$this).each(function(){var $span=$(this),innerText=$span.text(),wordSpacing=innerText.split(" ").length>1,diff,ratio,fontSize;if(postTweak){$span.css({"word-spacing":0,"letter-spacing":0});}ratio=parentWidth/$span.width();fontSize=parseFloat(this.style.fontSize)||origFontSize;$span.css("font-size",Math.min((fontSize*ratio).toFixed(precision),settings.maxFontSize)+"px");diff=!!postTweak?parentWidth-$span.width():false;if(diff){$span.css((wordSpacing?"word":"letter")+"-spacing",(diff/(wordSpacing?innerText.split(" ").length-1:innerText.length)).toFixed(precision)+"px");}});$this.addClass("slabtextdone");};resizeSlabs();if(!settings.noResizeEvent){$(window).resize(function(){if($(window).width()==viewportWidth){return;}viewportWidth=$(window).width();clearTimeout(resizeThrottle);resizeThrottle=setTimeout(resizeSlabs,resizeThrottleTime);});}});};})(jQuery);
Please sign in to comment.
Something went wrong with that request. Please try again.