Definitely Not The Better Way

The TTC service on Bathurst St. is mediocre at best, but tonight’s commute home was a new low. After walking three extra blocks to my streetcar stop (there’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.

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.

The driver said he didn’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’s 8˚ C, with 30kph winds), and that she’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’t need to get off. When she continued to refuse, he “put the bus out of service”, 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.

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.

Let’s think about this for a minute… Ostensibly, people aren’t allowed to bring shopping carts or other large objects on because they cause delays, or take spaces away from other passengers. If she’s not allowed on because it’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’s ridiculous. If opening up one extra spot by keepoing a cart off is necessary to keep the TTC moving along at “maximum efficiency”, doesn’t ordering everyone else off and going nowhere kind of defeat the point?

I can imagine that being a bus driver is a pretty thankless job, but this guy certainly wasn’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’s a limit, and he went way over the line.

Posted at 4pm on 11/01/07 | Posted in | no responses | read on

Copy-Fitted Text

I’m nerdy enough that I write code just for fun, if the problem’s interesting enough – like this one: What’s the best way to find an arbitrary value in a large range of numbers – say the maximum font-size for a line of text without wrapping?

Brute Force

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’ll loop a few hundred times. What’s that? You want to adjust the text when the window is resized? That’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!!

Obviously, that’s not going to work.

A Better Approach

What if I said we can find a magic number between 0 and 100,000 in less than 20 iterations – doesn’t matter what the number is, guaranteed? Yep, with a little brain-bending recursive goodness, we’ll have that sucker in no time.

function find_max( min, max, truth ) {
    var r = max - min;
    var n = min + Math.ceil(r / 2);
    if (r / 2 < 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 <= 66666;
}

find_max( 0, 100000, truth );

How It Works

With a min of 0 and a max of 100,000, we’ll ask: does 50,000 work? If it does, then the number is between 50,000 and 100,000. If not, it’s between 0 and 50,000. Either way, we’ve just eliminated half the possibilities. Not bad for a single iteration…

In the (arbitrary) case above, 50,000 does work. So, on the next iteration, we have a min of 50,000 and a max 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 min and max is less than one – at which point it must be one or the other. One more test and bingo! We’re in business.

Making It Work

To copy-fit text, we need to do three things:

  • add some css to prevent the text from wrapping as the font-size increases, and give us the actual width of the text
  • replace the arbitrary conditions in truth with code to change the font-size, and check if it’s too wide.
  • take the final result and use it as the copy-fitted font-size.

Markup

<h1 id="fitted">This text is copy-fitted.</h1>

CSS

#fitted {
    display: inline;
    white-space: nowrap; }

Script

function find_max( min, max, truth ) {
    var r = max - min;
    var n = min + Math.ceil(r / 2);
    if (r / 2 < 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 <= width;
    }) + 'px';
}

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

Conclusion

And there we go. 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’re so inclined to scale text to fit in a TextField.

Note: this is a proof of concept, so it’ll need some bullet-proofing and cross-browser testing before being used in the wild.

Bonus

I haven’t found a use for it yet, but here’s a counter-part to find_max:

function find_min( min, max, truth ){   
    var r = max - min;
    var n = max - Math.ceil(r / 2);
    if (r / 2 < 1) {
        return truth(max) ? max : min;
    } else if(truth(n)) {
        return arguments.callee(min, n, truth);
    } else {
        return arguments.callee(n, max, truth);
    }           
}
Posted at 9am on 10/15/06 | Posted in , , , | no responses | read on

Work In Progress

Being a designer and front-end developer, it feels slightly dirty to use a pre-packaged theme (Hemmingway, in this case). I know that the html probably isn’t perfect and that there’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).

While making the site technically flawless is a noble aim, I’m don’t want to get caught up tinkering under the hood, and miss the point. So I’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.

Posted at 5pm on 09/30/06 | Posted in | no responses | read on

Fashionably late...

Working on the web is a funny business. There’s no textbook that tells you how it all works, and there’s no handbook that says how it should 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’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 – we google, we read forums and mailing lists and blogs – then we start hacking.

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 – helpful, even. But you’re not an expert, not an authority – nobody, really. What’s the point of keeping a blog, or publishing your handy-work? After all, you just read some blogs and hacked away at things.

Doubts like those have kept me from sharing, but I’d like to change that. I work at a small company, and I’m lucky to be a generalist. I know a little about a lot. I can contribute bits and pieces that connect the things I’ve learned from other folks. They’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.

Posted at 3pm on 09/30/06 | Posted in | no responses | read on