<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Luke Lutman</title>
    <link>http://www.lukelutman.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Creative + Code</description>
    <item>
      <title>Definitely Not The Better Way</title>
      <description>&lt;p&gt;The TTC service on Bathurst St. is mediocre at best, but tonight&amp;#8217;s commute home was a new low. After walking three extra blocks to my streetcar stop (there&amp;#8217;s no service at my usual stop due to construction), taking the streetcar, then the subway, I came up onto the bus platform at Bathurst Station about 5:45pm, and got in line waiting for the 7 Bathurst bus going north. After a fifteen to twenty minute wait (which is atrocious for rush hour service), there were two full buses worth of people (roughly a hundred?) ready to board. &lt;/p&gt;

&lt;p&gt;About halfway through passengers loading onto the bus, the driver took issue with an elderly woman bringing a cart with groceries onto the bus (the kind of small cart that most Torontonians without cars depend on for grocery shopping). The TTC does have rules against bringing large objects onto busses, streetcars and subway at rush hour, but what happened next was pathetic, petty and mean. &lt;/p&gt;

&lt;p&gt;The driver said he didn&amp;#8217;t have room for the cart, and asked her to get off the bus and wait for the next one. The woman refused to get off the bus, saying it was cold outside (it&amp;#8217;s 8˚ C, with 30kph winds), and that she&amp;#8217;d already been waiting a long time. The driver asked her two or three more times to leave the bus. Other passengers asked the driver  to let her be, and argued that she didn&amp;#8217;t need to get off. When she continued to refuse, he &amp;#8220;put the bus out of service&amp;#8221;, and ordered all of the other passengers to leave the bus as well. Most of the rest of the passengers refused, phones started came out of pockets, and a woman behind me called the police.&lt;/p&gt;

&lt;p&gt;Meanwhile, three other busses have arrived, except that two of them are out of service and the driver of the third went inside to buy a coffee. So with four fully functional buses at Bathurst Station, nobody moved an inch.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s think about this for a minute&amp;#8230; Ostensibly, people aren&amp;#8217;t allowed to bring shopping carts or other large objects on because they cause delays, or take spaces away from other passengers. If she&amp;#8217;s not allowed on because it&amp;#8217;s rush hour, the next driver would have kept her off his bus too. Having already paid her fare, should she just sit in the station until rush hour is over? That&amp;#8217;s ridiculous. If opening up one extra spot by keepoing a cart off is necessary to keep the TTC moving along at &amp;#8220;maximum efficiency&amp;#8221;, doesn&amp;#8217;t ordering everyone else off and going nowhere kind of defeat the point?&lt;/p&gt;

&lt;p&gt;I can imagine that being a bus driver is a pretty thankless job, but this guy certainly wasn&amp;#8217;t doing himself any favours. Being a by-the-book kind of guy, I understand the driver wanting to stand his ground on principle, but there&amp;#8217;s a limit, and he went way over the line.&lt;/p&gt;</description>
      <pubDate>Thu, 01 Nov 2007 15:50:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:2be28e68-6dea-494e-b92a-f9bb223ed966</guid>
      <author>Luke Lutman</author>
      <link>http://www.lukelutman.com/articles/2007/11/01/definitely-not-the-better-way</link>
      <category>toronto</category>
      <category>ttc</category>
      <category>rants</category>
    </item>
    <item>
      <title>Copy-Fitted Text</title>
      <description>&lt;p&gt;I&amp;#8217;m nerdy enough that I write code just for fun, if the problem&amp;#8217;s interesting enough &amp;#8211; like this one: What&amp;#8217;s the best way to find an arbitrary value in a large range of numbers &amp;#8211; say the &lt;a href="/files/copyfit.html"&gt;maximum &lt;code&gt;font-size&lt;/code&gt; for a line of text without wrapping&lt;/a&gt;?&lt;/p&gt;

&lt;h2&gt;Brute Force&lt;/h2&gt;

&lt;p&gt;The obvious, brute force approach? Keep adding 1 to the font-size until it wraps, then subtract 1, and voila! If the line of text is short, and the window is very wide, we&amp;#8217;ll loop a few hundred times. What&amp;#8217;s that? You want to adjust the text when the window is resized? That&amp;#8217;s a few hundred more. You want to copy-fit two elements? Double. You want another one? Yes! Are you through? Not even close, bud!!&lt;/p&gt;

&lt;p&gt;Obviously, that&amp;#8217;s not going to work.&lt;/p&gt;

&lt;h2&gt;A Better Approach&lt;/h2&gt;

&lt;p&gt;What if I said we can find a magic number between 0 and 100,000 in less than 20 iterations &amp;#8211; doesn&amp;#8217;t matter what the number is, guaranteed? Yep, with a little brain-bending recursive goodness, we&amp;#8217;ll have that sucker in no time.&lt;/p&gt;

&lt;pre&gt;
function find_max( min, max, truth ) {
    var r = max - min;
    var n = min + Math.ceil(r / 2);
    if (r / 2 &lt; 1) {
        return truth(max) ? max : min;
    } else if(truth(n)) {
        return arguments.callee(n, max, truth);
    } else {
        return arguments.callee(min, n, truth);
    }
}

function truth (i) {
    return i &lt;= 66666;
}

find_max( 0, 100000, truth );
&lt;/pre&gt;

&lt;h2&gt;How It Works&lt;/h2&gt;

&lt;p&gt;With a &lt;code&gt;min&lt;/code&gt; of 0 and a &lt;code&gt;max&lt;/code&gt; of 100,000, we&amp;#8217;ll ask: does 50,000 work? If it does, then the number is between 50,000 and 100,000. If not, it&amp;#8217;s between 0 and 50,000. Either way, we&amp;#8217;ve just eliminated half the possibilities. Not bad for a single iteration&amp;#8230;&lt;/p&gt;

&lt;p&gt;In the (arbitrary) case above, 50,000 does work. So, on the next iteration, we have a &lt;code&gt;min&lt;/code&gt; of 50,000 and a &lt;code&gt;max&lt;/code&gt; of 100,000. Does 75,000 work? Nope. So, the magic number is between 50,000 and 75,000. And so on and so forth until half the difference between &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; is less than one &amp;#8211; at which point  it must be one or the other. One more test and bingo! We&amp;#8217;re in business.&lt;/p&gt;

&lt;h2&gt;Making It Work&lt;/h2&gt;

&lt;p&gt;To copy-fit text, we need to do three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add some css to prevent the text from wrapping as the font-size increases, and give us the actual width of the text&lt;/li&gt;
&lt;li&gt;replace the arbitrary conditions in truth with code to change the font-size, and check if it&amp;#8217;s too wide.&lt;/li&gt;
&lt;li&gt;take the final result and use it as the copy-fitted font-size.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Markup&lt;/h2&gt;

&lt;pre&gt;
&amp;lt;h1 id="fitted"&gt;This text is copy-fitted.&amp;lt;/h1&gt;
&lt;/pre&gt;

&lt;h2&gt;CSS&lt;/h2&gt;

&lt;pre&gt;
#fitted {
    display: inline;
    white-space: nowrap; }
&lt;/pre&gt;

&lt;h2&gt;Script&lt;/h2&gt;

&lt;pre&gt;
function find_max( min, max, truth ) {
    var r = max - min;
    var n = min + Math.ceil(r / 2);
    if (r / 2 &lt; 1) {
        return truth(max) ? max : min;
    } else if(truth(n)) {
        return arguments.callee(n, max, truth);
    } else {
        return arguments.callee(min, n, truth);
    }
}

function copyFit(element, width) {
    element.style.fontSize = find_max(0, 500, function(i){
        element.style.fontSize = i + 'px';
        return element.offsetWidth &lt;= width;
    }) + 'px';
}

window.onload = window.onresize = function() {
    var c = document.body;
    var e = document.getElementById('fitted');
    e.style.fontSize = 0;               
    copyFit( e, c.offsetWidth );                
}
&lt;/pre&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;And &lt;a href="files/copyfit.html"&gt;there we go&lt;/a&gt;. A line of text that scales up or down to match the width of the body element. You could also use this in ActionScript, if you&amp;#8217;re so inclined to scale text to fit in a TextField.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this is a proof of concept, so it&amp;#8217;ll need some bullet-proofing and cross-browser testing before being used in the wild.&lt;/p&gt;

&lt;h2&gt;Bonus&lt;/h2&gt;

&lt;p&gt;I haven&amp;#8217;t found a use for it yet, but here&amp;#8217;s a counter-part to &lt;code&gt;find_max&lt;/code&gt;: &lt;/p&gt;

&lt;pre&gt;
function find_min( min, max, truth ){   
    var r = max - min;
    var n = max - Math.ceil(r / 2);
    if (r / 2 &lt; 1) {
        return truth(max) ? max : min;
    } else if(truth(n)) {
        return arguments.callee(min, n, truth);
    } else {
        return arguments.callee(n, max, truth);
    }           
}
&lt;/pre&gt;</description>
      <pubDate>Sun, 15 Oct 2006 09:30:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:27b856ff-df4d-4003-9c08-df9d36073e1f</guid>
      <author>Luke Lutman</author>
      <link>http://www.lukelutman.com/articles/2006/10/15/copy-fitted-text</link>
      <category>(X)HTML</category>
      <category>JavaScript</category>
      <category>ActionScript</category>
      <category>CSS</category>
      <enclosure type="text/html" length="2226" url="http://www.lukelutman.com/files/copyfit.html"/>
    </item>
    <item>
      <title>Work In Progress</title>
      <description>&lt;p&gt;Being a designer and front-end developer, it feels slightly dirty to use a pre-packaged theme (&lt;a href="http://warpspire.com/hemingway"&gt;Hemmingway&lt;/a&gt;, in this case). I know that the html probably isn&amp;#8217;t perfect and that there&amp;#8217;s some inline javascript scattered about. I have no idea if it works in this browser or that one (so far, so good in Safari). &lt;/p&gt;

&lt;p&gt;While making the site technically flawless is a noble aim, I&amp;#8217;m don&amp;#8217;t want to get caught up tinkering under the hood, and miss &lt;a href="/articles/2006/09/30/fashionably-late"&gt;the point&lt;/a&gt;. So I&amp;#8217;m choosing to focus on content, and enjoy going from zero to sixty (from installing Typo to writing posts) in the space of an afternoon.&lt;/p&gt;</description>
      <pubDate>Sat, 30 Sep 2006 16:45:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:08de1896-ea30-466b-abb2-c8917b43a814</guid>
      <author>Luke Lutman</author>
      <link>http://www.lukelutman.com/articles/2006/09/30/work-in-progress</link>
    </item>
    <item>
      <title>Fashionably late...</title>
      <description>&lt;p&gt;Working on the web is a funny business. There&amp;#8217;s no textbook that tells you how it all works, and there&amp;#8217;s no handbook that says how it &lt;em&gt;should&lt;/em&gt; be done. A book could never dream of covering all the possibilities and permutations of the web in one place. Even if it could, it would be well past it&amp;#8217;s best-before date before you could get your hands on it. So geeks (like me) learn by looking at what other geeks have done &amp;#8211; we google, we read forums and mailing lists and blogs &amp;#8211; then we start hacking. &lt;/p&gt;

&lt;p&gt;Sooner or later, you know your floats from your functions and your controllers from your content. Maybe some other geek would find the helper you just wrote handy &amp;#8211; helpful, even. But you&amp;#8217;re not an expert, not an authority &amp;#8211; nobody, really. What&amp;#8217;s the point of keeping a blog, or publishing your handy-work? After all, you just read some blogs and hacked away at things. &lt;/p&gt;

&lt;p&gt;Doubts like those have kept me from sharing, but I&amp;#8217;d like to change that. I work at a small company, and I&amp;#8217;m lucky to be a generalist. I know a little about a lot. I can contribute bits and pieces that connect the things I&amp;#8217;ve learned from other folks. They&amp;#8217;re not perfect or ground-breaking, but maybe they can start a conversation. Maybe someone else can use them, hack them and remix them, and teach me more too.&lt;/p&gt;</description>
      <pubDate>Sat, 30 Sep 2006 15:06:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:99afa8d7-346d-47b7-9906-3f7caafac37d</guid>
      <author>Luke Lutman</author>
      <link>http://www.lukelutman.com/articles/2006/09/30/fashionably-late</link>
    </item>
  </channel>
</rss>
