<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8729407087018325447</id><updated>2012-03-07T13:46:04.829-08:00</updated><title type='text'>Kirk's UI Dev Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7909165214403176643</id><published>2012-03-07T13:46:00.001-08:00</published><updated>2012-03-07T13:46:04.839-08:00</updated><title type='text'>the pirate kart</title><content type='html'>I do have a real post pending (need to figure something out with jsfiddle) but meanwhile I'd like to talk about the&amp;nbsp;&lt;a href="http://www.piratekart.com/"&gt;2012-in-one Glorious Developers Konference Kollection Pirate Kart&lt;/a&gt;. It has its ultimate origin on a place called&amp;nbsp;&lt;a href="http://glorioustrainwrecks.com/"&gt;Glorious Trainwrecks&lt;/a&gt;, a site launched to praise terrible 90s homebrew shareware but now dedicated to the&amp;nbsp;proposition that every can make games, and should.&lt;br /&gt;&lt;br /&gt;The Pirate Kart of course shares that sensibility. The &lt;a href="http://www.piratekart.com/igfpiratekart.html"&gt;most recent Kart&lt;/a&gt; had been assembled for the Indie Games Festival Main Competition. Then there was a bit of a... political? motivation? It was meant as a playful argument against the "scenesterism" that sometimes haunts "Indie Games" as a movement.&lt;br /&gt;&lt;br /&gt;The Glorious Trainwrecks has always had a spirit of openness, though originally there was an emphasis on use of a particularly peculiar no-programming game construction kit called "Klik and Play" (which is why Ks show up a lot on the site and its offshoots, a trend that as a guy named Kirk I kan only applaud) which let people whip together a game in the 2-hour Klik of the Month Klub events.&lt;br /&gt;&lt;br /&gt;Personally, I tend to program in Processing (sometimes making Processing.js variants) which has the added benefit of keeping my Java skills from completely rusting. But more than that, making silly, 2-hour-game prototypes has given me a deeper sense of easy-to-code-but-juicy physics that really helps me make more intriguing and attractive UIs.&lt;br /&gt;&lt;br /&gt;Anyway, here are my 5 games! Click to play them online and get some more details about the background story.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="margin-left: auto; margin-right: auto;"&gt;&lt;a href="http://www.blogger.com/goog_317868671"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-sBu72ubE7BQ/T1fVzTnO-sI/AAAAAAAAAJw/oYv17Q0HTTY/s320/shavefacerace.png" width="306" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://kirkjerk.com/2012/02/27/"&gt;shave face race&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="margin-left: auto; margin-right: auto;"&gt;&lt;a href="http://www.blogger.com/goog_317868690"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-1nOT4VcIJ30/T1fV2tQGS2I/AAAAAAAAAKQ/BkDQh_JrI8Q/s320/robotish.png" width="306" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://kirkjerk.com/2012/02/28/"&gt;robotish&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="margin-left: auto; margin-right: auto;"&gt;&lt;a href="http://www.blogger.com/goog_317868680"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-oF4pk-ZoPaI/T1fV1zGykpI/AAAAAAAAAKA/hTIQr_ESK5o/s320/dinobeeboxer.png" width="306" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://kirkjerk.com/2012/02/29/"&gt;dinobeeboxer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="margin-left: auto; margin-right: auto;"&gt;&lt;a href="http://www.blogger.com/goog_317868685"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-lJ9luXsbk10/T1fV2PMXkgI/AAAAAAAAAKI/vice2Z-VHhQ/s320/hitormissile.png" width="306" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://kirkjerk.com/2012/03/01/"&gt;hit or missile&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;span style="margin-left: auto; margin-right: auto;"&gt;&lt;a href="http://www.blogger.com/goog_317868676"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-LgLrmwk9UVQ/T1fV1oaMFOI/AAAAAAAAAJ4/ITAa7qkW68M/s320/actionfigurefighter.jpg" width="306" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://kirkjerk.com/2012/03/02/"&gt;action figure fighter&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Of all of these, "action figure fighter" is probably my favorite, "robotish" is the best from a game-playing standpoint, and "dinobeeboxer" is just weird and cool.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7909165214403176643?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7909165214403176643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/03/pirate-kart.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7909165214403176643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7909165214403176643'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/03/pirate-kart.html' title='the pirate kart'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-sBu72ubE7BQ/T1fVzTnO-sI/AAAAAAAAAJw/oYv17Q0HTTY/s72-c/shavefacerace.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5130731064697794230</id><published>2012-02-21T11:06:00.000-08:00</published><updated>2012-02-21T11:57:19.420-08:00</updated><title type='text'>death of the mouse: film at 11</title><content type='html'>&lt;a href="http://gizmodo.com/5886574/its-time-to-exterminate-the-mouse" style="font-family: inherit;"&gt;"It's Time to Exterminate the Mouse"&lt;/a&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;reads Mat Honan's Gizmodo headline, the lead feature for the site. And at the risk of sounding like a cranky old man, I think he has an extremely half-assed understanding of how people and computers interact. His whole tone is kinda provocative and juvenile, to the extent that the whole article feels like a troll. After a few potshots complaining about how 8-bit this hardware feels and how "anyone pushing them with new computers is selling crap" (NB: this point is stronger than it would be otherwise because he's&amp;nbsp;&lt;/span&gt;tangentially&lt;span style="font-family: inherit;"&gt;&amp;nbsp;talking about desktop systems, which are even more on the way out than mice..) he rhetorically asks:&lt;/span&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: inherit;"&gt;When was the last time you really loved a mouse? When was the last time you were like, "damn, this is a great mouse and I enjoy using it?"&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: inherit;"&gt;That's an easy one-- the last time I tried to do coding work on my laptop for a few hours. Going back to the mouse after a day on the touchpad is a blessed relief... stuck with just the touchpad for a day, an almost tangible pressure of annoyance builds and builds.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;He then gives examples of a gesture I agree with the utility of: pinch to zoom is pretty decent and intutive. And I think inertial scrolling is probably a bit better than the scrollwheel, and definitely (usually) better than manipulating a page pointer by finger or mousepoint.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Then he says&lt;/span&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: inherit;"&gt;Today at any given time we may be running 20 apps at once, with a dozen or more browser windows open, while trying to sort through more data in a few seconds than an early Cray supercomputer saw over the course of its lifetime. And yet we still use tools designed for a simpler time, with simpler needs.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: inherit;"&gt;Which is true, but how is that an argument for gestures etc over the mouse? The iPad and the iPhone are lovely because they do ONE thing at once. In fact, much of the physicality comes from the way your glass slab has temporarily been turned a unitasking device for that activity. You need a lot of real estate to pinch and slide and poke.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;It goes on...&lt;/span&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: inherit;"&gt;Gesture-based computing gives us far more precision and control over the interface. We can manipulate not just points but entire screens. We can perform complex actions that once required keyboard shortcuts, with just our fingertips.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: inherit;"&gt;Precision? Really? And keyboard shortcuts are nerdy but they are full of precision and control. Plus, you can see easily written descriptions of what keyboard shortcut goes with what command...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;He then points to the Kinect as REALLY ahead of the curve with this stuff. Admittedly I was an early adopter, but using the Kinect to navigate the most simple menus is a nightmare. Each game invents its own paradigm for "select this option" (some use a swipe, some use a hold, etc) and for "back" and "pause". With the right game, using your body as the controller is fun as heck, but that's because you have a great mapping to a physical activity. (Ironically, the one place he admits to the superiority of the mouse is for FPS games. I was going to argue that the other way games have better interfaces is with the two stick controller and all those buttons, but then again each game has its own buttons to learn, and it only really works well because of the physicality of it.)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Other advantages of the mouse: has this guy ever heard of "gorilla arm"? That's what your arm feels like after a few hours of poke, poke, poke at the screen. For people who work long hours in front of a computer, you need something that's not going to tire you out. (Not to mention all the greasy fingerprints...)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Similarly, Mouse use on screen pointers. These pointers are nice because they keep state on the screen even when you put your hand down for typing. This allows bimodal systems that react to your projected interest (for example, hover states on buttons as you mouse around.) in a different way from your project intent (some form of clicking). Very few gesture systems carry that, and with the rise of touch devices, the hover state might be on its way out.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Also gestures tend to have poor discoverability. There are only a few universal moves (the zoom pinch, the swipe, the slide) and everything else varies greatly-- in fact, what a swipe "means" will vary from app to app. (Maybe if there was a universal "help I need the cheat sheet!" gesture?) So you get to a new app (or better yet to an old one you haven't used in a while) the answer to "how do I use this" might not be so clear.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Many gestures are residents of the universe of "moves the user can make unintentionally". Sometimes I mouse and shake a window on my Windows 7 machine, and suddenly all the other windows are minimized, including my chat windows and virtual post-its and things I like to keep around. And there's no real "Undo" for that, so I have to go and finds the things I wanted open. It's a clear violation of the Dao of UX, which is "a computer should always do that which surprises the user least."&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;So I might be sounding like that old "get off my lawn!" geezer. I might be underestimating the ability for gestures to standardize (they already are, like the "two finger scroll" on Macs) as well as having an exaggerated sense of the limitations of &amp;nbsp;touchpads, since I often use these nasty tiny PC things that lack both the 2-finger-scrolling and the generous dimensions of Apple's Magic Touchpad... Still, I think this article is a overly&amp;nbsp;&lt;/span&gt;provocative&lt;span style="font-family: inherit;"&gt;&amp;nbsp;and insufficiently thought out or balanced. On the other hand, it lets me (and the majority of the Gizmodo commenters by the look of it) feel as if they're rather smarter than the author.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5130731064697794230?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5130731064697794230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/death-of-mouse-film-at-11.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5130731064697794230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5130731064697794230'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/death-of-mouse-film-at-11.html' title='death of the mouse: film at 11'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-1800360481289269266</id><published>2012-02-20T13:12:00.000-08:00</published><updated>2012-02-20T13:12:33.199-08:00</updated><title type='text'>inputWrapper: default text and masks</title><content type='html'>I'll start with my usual disclaimer: this blog is meant to be notes to my future self along with stuff other developers might find useful, with code snippets that suffer from a heap of my inexperience and the usual "Get It Done!"/"Worse is Better" rush of my employer, and so isn't always representative of js and jquery best practices. (That said, the stuff we come up with is well-QA'd and I always aim to make robust and readable code, so there is that.)&lt;br /&gt;&lt;br /&gt;A common UI trick is to have a text entry field that has a prompt in the body of the input itself that goes away when the box is clicked on, and returns if the box is left without text. (A UX note is in many cases you don't want the box to be otherwise unlabled (no matter how slick your designer is trying to make the form) since that label goes away when text is entered, and depending on the context, the user might not know what the data he or she entered means.)&lt;br /&gt;&lt;br /&gt;A while back we experimented with different techniques for making this effect, and came up with the following. It's a function that you call as follows:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;makeInputDefault(".selectorForInputField",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;"Prompt To Put There","some_unique_identifier");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;It's a little wonky... possibly it should be wrapped in as a proper chainable jquery function, and having the developer pick a unique identifier is a bit odd.&lt;br /&gt;&lt;br /&gt;What the code does is make a sibling span that actually covers the input box. The js for that is&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function makeInputDefault(sel, def, classForSpan){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(sel).blur(function(){inputDefault_inputBlur(this);});&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$(sel).focus(function(){inputDefault_inputFocus(this);});&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;wrapperIdCounter = wrapperIdCounter + 1;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var inputWrapperID = "inputWrapperId_" + wrapperIdCounter;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$(sel).wrap("&amp;lt;div class='inputWrapper' id='" + inputWrapperID + "'&amp;gt;");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$(sel).parent("div").append('&amp;lt;span class="unpicked" onclick="inputDefault_spanClick(this);" style="display: inline;"&amp;gt;'+def+'&amp;lt;/span&amp;gt;');&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(classForSpan != undefined){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;$(sel).siblings(".unpicked").addClass(classForSpan);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if($(sel).val() != ""){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &amp;nbsp; &amp;nbsp;$(sel).siblings(".unpicked").hide();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small; white-space: pre;"&gt; &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;setTimeout(function() { inputDefault_inputLoad("#" + inputWrapperID) }, 500);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function inputDefault_spanClick(obj) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;ccdebug('spanClick');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentSpan = $(obj);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentInput = currentSpan.parent().find("input");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;currentInput.focus();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function inputDefault_inputFocus(obj) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;ccdebug('inputFocus');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentInput = $(obj);&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentSpan = currentInput.parent().find("span");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;currentSpan.fadeOut(250);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function inputDefault_inputBlur(sel) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;ccdebug('inputBlur');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentInput = $(sel);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentSpan = currentInput.parent().find("span");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(currentInput.val() == "") {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;currentSpan.fadeIn(250);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;//this next function makes sure we initialize to the right state,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;//in terms of showing the overlay or not...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function inputDefault_inputLoad(obj) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentWrapper = $(obj);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentInput = currentWrapper.find("input");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var currentSpan = currentWrapper.find("span.unpicked");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(currentInput.val() == "") {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;currentSpan.show();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;} else {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;currentSpan.hide();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;(I think the timeout is a hack to cope with browsers auto-filling the field after the sibling tag had been rendered...)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This goes with a jot of CSS:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.inputWrapper {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; padding: 2px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; position: relative;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.inputWrapper input, select {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; border: 1px solid #D7D7D7;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; color: #666666;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; font-size: 16px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; width: 150px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.inputWrapper span{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;position: absolute;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;top:3px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;left:6px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;display:none;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.inputWrapper .picked {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;color:#666666;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.inputWrapper .unpicked {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;color:#D7D7D7;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;So that seems to work ok. But why is it so complex?&amp;nbsp;&lt;a href="http://www.dailycoding.com/Posts/default_text_fields_using_simple_jquery_trick.aspx"&gt;this dailycoding article&lt;/a&gt;&amp;nbsp;outlines a method that is much more straightforward, and keeps the default text with the HTML. Well, I found two reasons... one is we are also using&amp;nbsp;&lt;a href="http://digitalbush.com/projects/masked-input-plugin/"&gt;this masked Input plugin&lt;/a&gt;&amp;nbsp;to autofill the field with hyphens, and it kind of short circuits the simpler prompt method. Another is (and this is a guess) that the dailycoding technique means you have to check if the current input value is equal to the prompt, and ignore it accordingly, when the form data is actually used.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I guess my overall suggestion is to use the dailycoding technique first (nice site btw, I just subscribed to its feed) and then use something like this span technique if the straightforward way isn't up to par.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-1800360481289269266?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/1800360481289269266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/inputwrapper-default-text-and-masks.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1800360481289269266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1800360481289269266'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/inputwrapper-default-text-and-masks.html' title='inputWrapper: default text and masks'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-9055712300486932654</id><published>2012-02-16T08:14:00.001-08:00</published><updated>2012-02-16T08:14:07.904-08:00</updated><title type='text'>a bit of wisdom to my future self</title><content type='html'>Future self, when having to resize elements based on some other elements' animation of size or position, you will get better results if you put a callback at the end of animate() rather than trying to read the size or position right there and then.&lt;br /&gt;&lt;br /&gt;Cheers!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-9055712300486932654?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/9055712300486932654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/bit-of-wisdom-to-my-future-self.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/9055712300486932654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/9055712300486932654'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/bit-of-wisdom-to-my-future-self.html' title='a bit of wisdom to my future self'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-4057355383182613252</id><published>2012-02-13T14:07:00.000-08:00</published><updated>2012-02-13T14:07:45.073-08:00</updated><title type='text'>basalmiq's big blue arrow</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="text-align: -webkit-auto;"&gt;At my company, our product owners like to sketch things out in&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.balsamiq.com/" style="text-align: -webkit-auto;"&gt;basalmiq&lt;/a&gt;&lt;span style="text-align: -webkit-auto;"&gt;, layout-mockup software that makes it easy to give a rough outline of what the various product screens should look like. What's nice about basalmiq is that everything has a clean but crude look, as if someone with a very clean style was sketching it on a whiteboard:&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-tELqUQTiZRc/TzmFnQt7KCI/AAAAAAAAAIg/5K8zAdga3lE/s1600/basalmiq.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="277" src="http://1.bp.blogspot.com/-tELqUQTiZRc/TzmFnQt7KCI/AAAAAAAAAIg/5K8zAdga3lE/s320/basalmiq.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The deliberate crudeness lets people reviewing see the bigger picture, and not got tripped up on commenting on small details of the design. (As is the reviewer's wont, I know from personal experience.)&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The program's "presentation mode" has a beautiful UX detail I simply adore. It features an oversized mouse pointer, so that people in the back of the room can see what you're pointing to. But MORE than that, they have the pointer rotate so that it's always directed at the center. It took me a second to realize that was the simple algorithm they were using, because in practice it does a terrific job of subtly grabbing the eye and really &lt;i&gt;seeing &lt;/i&gt;what's being pointed at.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I used processing.js to mockup a replica of it in action, full of this that and the other... (my apologies, and sympathies, to users of older versions of IE)&lt;/div&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}&lt;/style&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe border="0" height="520" src="http://kirkjerk.com/m/files/kirkdev/bluearrow/" width="520"&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;center style="text-align: left;"&gt;It's such a great idea-- really thinking outside the box. Or rather, noticing that there was a box to think outside of. UX detail at its finest.&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-4057355383182613252?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/4057355383182613252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/basalmiqs-big-blue-arrow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4057355383182613252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4057355383182613252'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/basalmiqs-big-blue-arrow.html' title='basalmiq&apos;s big blue arrow'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-tELqUQTiZRc/TzmFnQt7KCI/AAAAAAAAAIg/5K8zAdga3lE/s72-c/basalmiq.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-6145276725080938113</id><published>2012-02-07T13:47:00.000-08:00</published><updated>2012-02-07T13:47:01.605-08:00</updated><title type='text'>basic diy pubsub</title><content type='html'>&lt;br /&gt;So to solve a problem at work I wrote a basic pubsub, a publish/subscribe model so parts of our page can notify other parts of events they care about... it's a powerful design pattern for decoupling various components on a page. There are&amp;nbsp;&lt;a href="https://gist.github.com/661855"&gt;other implementations&lt;/a&gt;&amp;nbsp;we coulda used, but it's pretty fun and easy to roll our own, I think the resulting code is small and robust:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;var localDataBreaker = new function(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;this.callbacks = {};&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;this.subscribe = function(event,id,funk){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(this.callbacks[event] == undefined){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;this.callbacks[event] = {};&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;this.callbacks[event][id] = funk;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;this.unsubscribe = function(event,id){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(this.callbacks[event] != undefined){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;delete(this.callbacks[event][id]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;this.publish = function(event,args){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(this.callbacks[event] != undefined){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;for(key in this.callbacks[event]){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;var funk = this.callbacks[event][key];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;funk(args);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(I like the idea of functions subscribing with a string key for later unsubscriptions, that seemed safer than assuming there will be a reference to the same function handy when a function wants to stop listening.)&lt;br /&gt;&lt;br /&gt;So here's a basic test of it... we subscribe to event "foo" with an anonymous function that we key with "bar", we practice firing "foo", then we also subscribe with an event tagged "baz", we see both fire when the event occurs, then we remove "bar" and see just "baz" fire when we fire the event a third time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.subscribe("foo","bar",function(o){alert('bar:'+o);});&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.publish("foo",'event &amp;nbsp;1 after just bar ');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.subscribe("foo","baz",function(o){alert('baz:'+o);});&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.publish("foo",'event 2 after bar and baz ');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.unsubscribe("foo",'bar');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;localDataBreaker.publish("foo",'event 3 after bar removed ');&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-6145276725080938113?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/6145276725080938113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/basic-diy-pubsub.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6145276725080938113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6145276725080938113'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/basic-diy-pubsub.html' title='basic diy pubsub'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2035504331192307592</id><published>2012-02-02T12:05:00.000-08:00</published><updated>2012-02-02T12:05:00.599-08:00</updated><title type='text'>onerror and busted images</title><content type='html'>My company's site &lt;a href="http://alleyoop.com/"&gt;alleyoop.com&lt;/a&gt;&amp;nbsp;just had its big public launch! Hooray for us!&lt;br /&gt;&lt;br /&gt;So we have a lot of Math "subtopics", each with its own representative image. Those image files live in the file system, but the subtopic names live in the database (with the front end getting the list of available subtopics from various endpoints.)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-eMZ7TPaQlt4/Tyrqxa2rrSI/AAAAAAAAAH0/POmkPg6ArJU/s1600/Comparing+Graphs+of+-%C3%A1Quadratic+Functions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="106" src="http://4.bp.blogspot.com/-eMZ7TPaQlt4/Tyrqxa2rrSI/AAAAAAAAAH0/POmkPg6ArJU/s320/Comparing+Graphs+of+-%C3%A1Quadratic+Functions.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;We use the subtopic name as the file name, which is of course asking for trouble a little bit, but in practice it works ok, and it's a lot easier for our design people to work with meaningful long file names than having to look up unique IDs.&lt;br /&gt;&lt;br /&gt;To make sure all subtopics had correctly named art, I made a QA tool that polls the endpoints and slaps up the images. I found an easy way to get generate a list of the broken images, so that we don't have to carefully inspect the whole very long page by hand... I build the HTML with something like&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;buf += "&amp;lt;pre&amp;gt;"+showname+"&amp;lt;/pre&amp;gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;+"&amp;lt;img src='"+path+name+".png' onerror='doerror(this)' &amp;gt;\n";&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I know some people prefer to build objects with templates (though I'm sad that my favorite templating for jQuery isn't gonna make it outta beta) or with DOM objects... (which annoy me a little, because now I have two ways of making up parts of a page, by writing HTML, or the "language of DOM elements". I'd rather speak one language when possible!) but this is more than adequate for most purposes, especially quick and dirty QA purposes...&lt;br /&gt;&lt;br /&gt;So that "onerror" nicely gets called when the image is indeed busted, and so I have a function doerror that takes the object and does this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function doerror(o){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var parts = o.src.split("/");&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var name = parts[parts.length-1];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;name = name.substring(0,name.length-4);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;name = replaceAll(name, "%20"," ");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;$("#error").append(name+"&amp;lt;br&amp;gt;");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;(I should probably have it replace escaped ^s not just spaces...)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So that works well, and is a powerful way of quickly detecting broken image references before they make it into production.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;BONUS TIP:&lt;/div&gt;&lt;div&gt;Our work laptops all have encrypted harddrives, so sometimes when we transfer files straight to PC from Mac via IM, the files all show up with green filenames, and Apache Tomcat can't actually display the files! In that case I have to select all the files, right click to Properties, click "Advanced..." and then uncheck "Encrypt conctents to secure data".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2035504331192307592?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2035504331192307592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/02/onerror-and-busted-images.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2035504331192307592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2035504331192307592'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/02/onerror-and-busted-images.html' title='onerror and busted images'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-eMZ7TPaQlt4/Tyrqxa2rrSI/AAAAAAAAAH0/POmkPg6ArJU/s72-c/Comparing+Graphs+of+-%C3%A1Quadratic+Functions.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3449136344190241010</id><published>2012-01-27T11:58:00.000-08:00</published><updated>2012-01-27T12:01:36.160-08:00</updated><title type='text'>bounding rectangles 101</title><content type='html'>I'm very psyched to be doing the Global Game Jam for the fourth time-- all around the world people form small teams in order to make interesting games, all over one-48-hour weekend.&lt;br /&gt;&lt;br /&gt;Something that comes up often in game programming is the question "did this thing hit this other thing?" Often, the easiest way of figuring that out is using "bounding rectangles", changing the question to the simpler-to-code "does the box corresponding to this thing's outline overlap the box corresponding to this other thing's outline?" (Even if you need to do a finer-grained collision detection, it's often more efficient to start with this question.)&lt;br /&gt;&lt;br /&gt;But even with this simplification, it's not a trivial thing to code. If you code like I do, you'll be having two objects, each with an x,y coordinate for their top corner, and a width and a height (referred to now from w and h). &amp;nbsp;My class in (processing/processing.js) to represent that is something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;class boxish{&lt;br /&gt;    float w,h,x,y;&lt;br /&gt;    color c;&lt;br /&gt;    &lt;br /&gt;    boxish(float px,float py,float pw,float ph,color pc){&lt;br /&gt;            x = px;&lt;br /&gt;            y = py;&lt;br /&gt;            w = pw;&lt;br /&gt;            h = ph;&lt;br /&gt;            c = pc;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    void draw(){&lt;br /&gt;        fill(c);&lt;br /&gt;        rect(x,y,w,h);        &lt;br /&gt;    }    &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;that lets me create a box, give it a color, and then ask it do draw itself.&lt;br /&gt;&lt;br /&gt;So now what?&lt;br /&gt;&lt;br /&gt;The first simplification of "do these boxes overlap?" can be "do these boxes overlap horizontally AND vertically"? Because two boxes could be around the same x-coordinate, but if one is way higher than the other one, they won't overlap-- and vice versa for the y-coordinate. By breaking down the problem this way, we're turning our 2 dimensional issue into a 2 1 dimensional ones... much easier!&lt;br /&gt;&lt;br /&gt;The trivial code for this is&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;boolean overlapBox(boxish b1, boxish b2){&lt;br /&gt;    if(overlapHoriz(b1,b2) &amp;amp;&amp;amp; overlapVert(b1,b2)){&lt;br /&gt;        return true;&lt;br /&gt;    } else {&lt;br /&gt;        return false;    &lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok. Lets start with the Horizontal 1D problem. We have 2 line segments, and we need to know if they touch each other. There are 6 possibilities, outline here in this crude diagram:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JdQXaYoGU8M/TyL-x41SkdI/AAAAAAAAAHM/ke8Scc8clcU/s1600/overlap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-JdQXaYoGU8M/TyL-x41SkdI/AAAAAAAAAHM/ke8Scc8clcU/s1600/overlap.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I don't know about you, but my takeaway was this: there are more ways for two lines to overlap than for them not to... therefore, we're going to just test for the two cases where they don't - namely where both of line1's points are to the left of line 2's left or both the points are to the right of line 2's right.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So my code was:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;/div&gt;&lt;div class="" id="magicdomid55"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid56"&gt;&lt;span class=""&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;boolean overlapHoriz(boxish b1, boxish b2){&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid57"&gt;&lt;span class=""&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; float b1left = b1.x;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid58"&gt;&lt;span class=""&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; float b1right = b1.x+b1.w;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="ace-line" id="magicdomid80"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; float b&lt;/span&gt;&lt;span class="author-p-442"&gt;2&lt;/span&gt;&lt;span class=""&gt;left = b2.x;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="ace-line" id="magicdomid221"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; float b&lt;/span&gt;&lt;span class="author-p-442"&gt;2&lt;/span&gt;&lt;span class=""&gt;right = b2.x+b2.w;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="ace-line" id="magicdomid226"&gt;&lt;span class="author-p-442"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(b1left &amp;lt; b2left &amp;amp;&amp;amp; b1right &amp;lt; b2left) return false;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid224"&gt;&lt;span class="author-p-442"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(b1left &amp;gt; b2right &amp;amp;&amp;amp; b1right &amp;gt; b2right) return false;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="ace-line" id="magicdomid179"&gt;&lt;span class="author-p-442"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="" id="magicdomid66"&gt;&lt;span class=""&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;overlapVert() should be pretty obvious from that.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So that's it. I put together the following little test program that changes color when the moving box overlaps one of the static ones:&lt;/div&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}&lt;/style&gt;&lt;iframe border="0" height="220" src="http://kirkjerk.com/m/files/kirkdev/overlap/" width="220"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;You can see the&amp;nbsp;&lt;a href="http://kirkjerk.com/m/files/kirkdev/overlap/overlap.pjs"&gt;full psj sourcecode here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3449136344190241010?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3449136344190241010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/01/bounding-rectangles.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3449136344190241010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3449136344190241010'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/01/bounding-rectangles.html' title='bounding rectangles 101'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-JdQXaYoGU8M/TyL-x41SkdI/AAAAAAAAAHM/ke8Scc8clcU/s72-c/overlap.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5721539407950589546</id><published>2012-01-18T13:21:00.000-08:00</published><updated>2012-01-19T07:47:45.676-08:00</updated><title type='text'>a simple jquery slot machine effect</title><content type='html'>For work they wanted a "juicy" (I've been promoting use of that term for pleasingly physical or generally pleasant animations) way of showing a randomly generated amount of virtual currency assigned to the user. I suggested a slot machine-effect, and it came out really nicely, a widget with a very high "coolness to code complexity" ratio.&lt;br /&gt;&lt;br /&gt;Here's another version of what I quickly came up with, click to spin!&lt;br /&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}&lt;/style&gt;&lt;iframe height="140" src="http://kirkjerk.com/m/files/kirkdev/slots/slots.html" width="310"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;The final product for work was a bit different, a single little rotating slot with graphical icons and more polish, &amp;nbsp;(including a nice fade in behind once the final amount was displayed). But for messing about purposes, I simplified the display, threw in a few extra windows, and made the results A B C D or F.&lt;br /&gt;&lt;br /&gt;You can see the &lt;a href="http://kirkjerk.com/m/files/kirkdev/slots/"&gt;html, js, and css here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;There's very little too it, really: each slot consists of an outer class "slots" that provides the border and has a hidden overflow. Inside each slot is a (very tall) "wrapper", and then the js code adds a bunch of divs of class "slot", each as wide as the wrapper and each containing a random letter. &amp;nbsp;When it's time to let things "spin", we just animate the wrapper's margin-top property to a multiple (7) of the negative height of a single slot. Some of the secret sauce is the easing, "easeOutElastic" from the jQuery easing module... I&amp;nbsp;&lt;a href="http://kirkdev.blogspot.com/2011/11/more-pleasing-easing.html"&gt;wrote about that easing stuff earlier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If the user clicks again, we repeat the process, adding in extra divs of class slot, and moving an increased seven times the height from where it was before. There are some little tricks going on here: we add more divs than we actually need because the elastic animation overshoots a bit (and of course, it's not really circular like a real slot machine would be), it took a while to realize that you should just move a small # of slots, and I added some randomness to the length of time of the animation, so it didn't all move in lockstep. It would be easy to tweak the timing so slots 2 and 3 started after 1, for a kind of 1....2...3! effect. (Another thing I added for this demo was the use of the "stop()" command... otherwise repeated spin clicks would have to wait until the earlier spins were fully settled. stop() has some arguments I missed when I first learned about i&lt;strike&gt;t, they didn't come in handy here,&lt;/strike&gt; but let you control if the element/animation queue finishes the pending animation(s) or just stops cold to start the new one. (Actually it turns out I needed to stop() the animation, including the parameter to jump to the final position, before reading the old position to set the new goal.)&lt;br /&gt;&lt;br /&gt;Stuff like this is a great argument for jQuery/CSS UI engineers to err on the side of building things from scratch rather than relying on gluing together pre-existing bits. If I had only used other people's slideshow modules, rather than realizing it was a simple matter of wrapper divs, overflow:hidden, and animating margins, I wouldn't know enough to put this together... but it's really quite simple when you treat jQuery and CSS as the empowering technologies that they are.&lt;br /&gt;&lt;br /&gt;BONUS PROTIP: This animation read the old margin-top in order to set the new one&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;jqo.css("margin-top"); //jqo is the jQuery object&lt;/span&gt;&lt;br /&gt;That returns a value like "100px". To get rid of the "px" and treat that as an integer, parseInt works very well, it's designed to read numbers at the start of a string and then stop when it encounters non-digits:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;var marginTop = parseInt(jqo.css("margin-top"), 10);&lt;/span&gt;&lt;br /&gt;(The 10 after makes sure that we keep things in base 10, if the number string started with, say, a "0", strange &amp;nbsp;things might result.)&lt;br /&gt;Of course after you've done your math you need to append the "px" again, but you know that already, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5721539407950589546?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5721539407950589546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/01/simple-slot-machine-effect.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5721539407950589546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5721539407950589546'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/01/simple-slot-machine-effect.html' title='a simple jquery slot machine effect'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5517106188161698160</id><published>2012-01-12T09:10:00.000-08:00</published><updated>2012-01-18T13:40:25.920-08:00</updated><title type='text'>on smaller frameworks</title><content type='html'>(This is a response to Gordon L Hempton's blogpost &lt;a href="http://codebrief.com/2012/01/javascript-frameworks-are-too-small/"&gt;Javascript Frameworks Are Too Small&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Interesting article link you posted. Why don't we have as many layer of abstractions for web development? One answer might be, each of  levels Queru describes is built on a REALLY reliable and well-engineered level beneath it, and there isn't that kind of solidity under JS/HTML5. But I think the other answer is: it's not necessary, at least for a certain kind of developer.&lt;br /&gt;&lt;br /&gt;I can't even tell you how foreign I find your proclamation&lt;i&gt; given the choice between two frameworks with equally well-written code, I would probably opt for the larger framework  &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;There's a valid outlook that's the opposite of this: it says, I want to learn as little new as possible to get the job done, to minimize the mental load my tools are causing me. Toolkits with lots of abstraction often don't have good power/weight ratios; they're not much more expressive than more basic toolkits, but there's a lot more you new unique knowledge you have to keep in your head to use them properly (lest you become one of those Microsoft-y types, who can do decent stuff but have NO idea what's going on under the hood, or how to fix it when it goes wrong in a deep way.)&lt;br /&gt;&lt;br /&gt;I think more abstract toolkits tend to program in nouns... "configure me correctly/learn which of my calls will do your bidding, and I'll do all the "tough work" and you can keep commanding on high rather than dirtying your hands in the trenches". But the cost of that comes in debugging, where suddenly the result of your bug is more likely to be farther away -- "physically" in the files, mentally in the abstraction -- than if you kept your toolbox nice and light and focused on the solving the problems that are actually a pain in the butt to keep resolving. (jQuery being one of the shining examples of awesomeness for the latter.)&lt;br /&gt;&lt;br /&gt;I agree that "a larger amount of energy goes towards dealing with the frameworks involved, rather than the problem being solved" but not in the sense you mean: finding people who know the intricacies of a new stack, or training up people to get that knowledge, is the expense...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5517106188161698160?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5517106188161698160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/01/on-smaller-frameworks.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5517106188161698160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5517106188161698160'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/01/on-smaller-frameworks.html' title='on smaller frameworks'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-746196909141918502</id><published>2012-01-06T10:33:00.000-08:00</published><updated>2012-01-06T10:33:30.463-08:00</updated><title type='text'>jquery animating background positions (and colors)</title><content type='html'>Short but sweet: "background-position" tends to be a compound kind of setting, with a separate value for x and y, but the single key. This means jQuery's default animation function can't smooth animate it, like it can't animate color transitions. But just like how there's a&amp;nbsp;&lt;a href="http://www.bitstorm.org/jquery/color-animation/"&gt;plugin to let you animate colors&lt;/a&gt;&amp;nbsp;there's one for&amp;nbsp;&lt;a href="http://www.protofunc.com/scripts/jquery/backgroundPosition/"&gt;backgroundPosition as well&lt;/a&gt;. There's not much to it besides what the page says. I stuck copies of both on my "just in case the links go away" jquery file archive at&amp;nbsp;&lt;a href="http://kirkjerk.com/m/files/"&gt;http://kirkjerk.com/m/files/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-746196909141918502?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/746196909141918502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/01/jquery-animating-background-positions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/746196909141918502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/746196909141918502'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/01/jquery-animating-background-positions.html' title='jquery animating background positions (and colors)'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3985806094102808659</id><published>2012-01-05T10:23:00.000-08:00</published><updated>2012-01-05T10:23:40.293-08:00</updated><title type='text'>juicy in 2012: bouncy topicgrid</title><content type='html'>This is a work in progress for my day job, but I'm digging it so far: squares that jiggle on hover, then expand to twice the size when you "hold".&lt;br /&gt;&lt;br /&gt;&lt;iframe border="0" height="360" src="http://kirkjerk.com/m/files/kirkdev/topicgrid/" style="border: none;" width="600"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}&lt;/style&gt;(Live demo from &lt;a href="http://kirkjerk.com/m/files/kirkdev/topicgrid/"&gt;http://kirkjerk.com/m/files/kirkdev/topicgrid/&lt;/a&gt;) These are all divs positioned absolutely with a containing div. The "shove the small blocks out of the way" routine our UX guy Marco was looking for was hard to wrap my head around at first. Say we're growing 0-0, doubling its height and width so it takes 4 spaces instead of 1, a net change of 3 spaces. We start by shoving the columns topped by 0-1 and 1-1 straight down, freeing 2 of the squares. We then shove 1-0 to the right, freeing up the final square. And to make room for 1-0, the column topped by 2-0 has to be pushed down. (But if the block we're growing is on the right side of the layout we change its position so that it grows to the left, and that changes which side our single column down is on.) It seems pretty simple (to me, now) when I write it out (3 groups of blocks to move: the 2 cols. underneath, the singleton off to the side, the single col. down to make room for the singleton) but I kind of had to sleep on it to get the general case.&lt;br /&gt;&lt;br /&gt;(The other UI guy Ben pointed out the cool flexible zooming grid at &amp;nbsp;the&amp;nbsp;&lt;a href="http://www.adidas.com/us/homepage.asp"&gt;Adidas homepage&lt;/a&gt;&amp;nbsp;-- that looks like it was an even cooler challenge.)&lt;br /&gt;&lt;br /&gt;The other fun and educational part was the "jiggle" when you hover the mouse over a block-- this creates a small juicy "toy" as you sweep your mouse across the whole area. My first idea was trying to use one of the bounce-y easings, but keep the block the same size. This did precisely nothing... I think the easings generally depend on multiples of the difference between two values like width/height or position so you can't "ease in place". I then tried the JQuery UI effect "bounce", but it assumes you have something that can be positioned "relative" on the page, and left the div stuck to the top left when it was done. So I rolled my own, using a series of animations (using the built-in linear easing instead of the default swing)- it animates to random x and y offsets, then animates to half the opposite of those values, then settles back to where it was.&lt;br /&gt;&lt;br /&gt;This isn't perfected yet, but it's pretty good. I had to look into different techniques for restoring the squares... &amp;nbsp;I thought always stop()ing the animation would help, but that just got blocks stuck. So now it just adds the move onto the animation queues, but it works out, in part because things are pretty briskly paced.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3985806094102808659?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3985806094102808659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2012/01/juicy-in-2012-bouncy-topicgrid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3985806094102808659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3985806094102808659'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2012/01/juicy-in-2012-bouncy-topicgrid.html' title='juicy in 2012: bouncy topicgrid'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3587758386941594087</id><published>2011-12-29T17:29:00.000-08:00</published><updated>2012-01-03T11:56:11.139-08:00</updated><title type='text'>osx vs windows redux</title><content type='html'>Ranting on obscure blogs is a bit like tossing nickels into the Grand Canyon, but... hey, a nickel!&lt;br /&gt;&lt;br /&gt;I sometimes jump the gun in criticizing Apple and OSX. Too often that comes from inexperience with OSX. In many cases, a serious criticism of "you can't do this on a Mac" (for example, easily copying the path information from an open Finder window into a "Save As" dialog) runs head on into a "Mac just does it a different way, you Windows-muddled fool" (you can drag the little folder icon on top of the Finder window!) and gets diluted into vaguer criticisms about "UI emphasis" and "potential confusion" (the way that drag and dropping that icon feels too much like a file system manipulation... and darn it, using string-based paths is sensible, if a bit nerdy.)&lt;br /&gt;&lt;br /&gt;So once more into the breach...&lt;br /&gt;&lt;br /&gt;One thing holding me back from switching to OSX for my work machine is a feeling that the keyboard support isn't up to snuff... specifically on Windows, nearly every text editor I use maps ctrl-left arrow and ctrl-right arrow to jumping words. Now there is&lt;i&gt; some&lt;/i&gt; inconsistency to it: some editors think an underscore is a word break, others don't, some jump to the start of the next word immediately, others jump to the end of the current word first. But at least the standard is there, and I don't have to interrupt my typing flow with mouse movements, or play "press and hold the arrow key 'til the cursor finally gets there".&lt;br /&gt;&lt;br /&gt;I thought this problem sprung from Apple's pro-mouse, anti-keyboard stance. The original Mac keyboard didn't even have arrow keys!&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Apple_Keyboard#Macintosh_Keyboard_.28M0110.29"&gt;See for yourself&lt;/a&gt;:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-HdqNKkTTWv0/TwM0fRz3III/AAAAAAAAAGo/eri4lVBmN4w/s1600/Apple_Macintosh_Plus_Keyboard.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-HdqNKkTTWv0/TwM0fRz3III/AAAAAAAAAGo/eri4lVBmN4w/s320/Apple_Macintosh_Plus_Keyboard.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;But of course, I was wrong. I was expecting that all the keys I was looking for would be mapped to cmd-, which is (roughly) the Mac equivalent of "ctrl". On OSX however, the cmd-arrow keys jump either to the&amp;nbsp;beginning/end of the line (left and right) or of the whole document (up and down). However, The&lt;i&gt; "option"&lt;/i&gt; key WAS mapped to what I wanted, with the left and right jumping of words.&lt;br /&gt;&lt;br /&gt;Arguably, Mac's use of these keys is more efficient and logical than the PC standards. There's an intuitive hook to how cmd-left/right goes to line endings, and cmd-up/down means the whole document. These keys can then play the role of home/end on PCs: home/end = line, ctrl-home,/ctrl-end=whole document. Furthermore home/end are two of the most wandering keys on laptop and compact PC keyboards, there has been no definitive consensus on where they should go, and sometimes they are mapped to special, laptop only "fn-" keys. So points to Apple for battening down the hatches on that.&lt;br /&gt;&lt;br /&gt;So I was wrong. Mostly. But can I say Mac has too many of the wrong kind of keys? Look at this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-YpdGnB7I98g/TwM4dqroiZI/AAAAAAAAAG0/Tar5bZIp4kE/s1600/keys.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-YpdGnB7I98g/TwM4dqroiZI/AAAAAAAAAG0/Tar5bZIp4kE/s1600/keys.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;"fn" "control" "option" and "command"! 4 different keys that mean roughly the same thing, "make the other key I'm pressing do something else". To make things worse, the little used key "fn" gets the most prime real estate-- the place where Fitt's Law implies the most important key should go. (To be fair, IBM/Lenovo Thinkpads make the same mistake, and it's even worse because a PC's ctrl key is much more important than the Mac's.)&lt;br /&gt;&lt;br /&gt;Here's the same image from a typical Windows keyboard:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zFxPFA-t6uM/TwM6-HwFcXI/AAAAAAAAAHA/CD_EKDxc0dk/s1600/pckeys.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="145" src="http://4.bp.blogspot.com/-zFxPFA-t6uM/TwM6-HwFcXI/AAAAAAAAAHA/CD_EKDxc0dk/s320/pckeys.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It's the same number of keys, but I think handled much more gracefully, with better differentiation. "ctrl" and "alt" are far away from each other. Plus in Windows, there's a stronger convention for when which is used: ctrl- combinations tend to be "do something now": copy, paste, save, new, etc. Alt- combinations are mostly used to pull down menus. (Windows used to have greater discoverability of that feature by underlining the accelerator letter on the menubar, e.g. &lt;u&gt;F&lt;/u&gt;ile and &lt;u&gt;E&lt;/u&gt;dit, but now (by default) those underlines are hidden until the user holds the alt key.)&lt;br /&gt;&lt;br /&gt;The windows-key is special, in most sense of the word: usually it means a quick hop to the start menu (and I love the way they put the cursor in a search box there... windows-key,"program name fragment", return is a very quick way to start a program that is not frequently used enough to merit a pin on the task bar.) The Windows key also has a few obscure key combos that are all OS-wide, like win-m or win-d for hiding all windows and showing the desktop. (Though weirdly, win-d is reversible by hitting again, and the older win-m is not.)&lt;br /&gt;&lt;br /&gt;(And it still seems odd to me that Microsoft managed to get their logo on all that hardware by all those manufacturers...)&lt;br /&gt;&lt;br /&gt;So wrapping up my arrow key rant, Mac feels a bit klutzy to me, and it's awkward to use and annoying to remember the distinction between "command" and "option" when going back and highlighting and copy words that I just typed. To make the whole scene worse, why isn't the Option (formerly Closed Apple Key) labeled with its icon,&amp;nbsp;&lt;img height="11" src="http://www.danrodney.com/mac/img/menusym-option.gif" style="-webkit-text-size-adjust: none; background-color: #edf3fe; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: 'Lucida Sans Unicode', 'Lucida Grande', 'Helvetica Neue', Helvetica, sans-serif; font-size: 11px; font: inherit; line-height: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: right; vertical-align: baseline;" width="12" /&gt;&amp;nbsp;?(And what kind of symbol is that anyway? To be fair I guess the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Option_key"&gt;Option Key has its uses&lt;/a&gt;, like for typing letters with accents and the like, but still there are aspects to it that seem half-baked.&lt;br /&gt;&lt;br /&gt;Rant over! I'm still on the fence about making the "switch" (and in part because I worry about Apple being such a dominant monoculture of computing) but thinking about the UI/interface it provides makes the potential transition easier for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3587758386941594087?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3587758386941594087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/osx-vs-windows-redux.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3587758386941594087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3587758386941594087'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/osx-vs-windows-redux.html' title='osx vs windows redux'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-HdqNKkTTWv0/TwM0fRz3III/AAAAAAAAAGo/eri4lVBmN4w/s72-c/Apple_Macintosh_Plus_Keyboard.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3086786597201255045</id><published>2011-12-22T12:23:00.000-08:00</published><updated>2011-12-22T12:23:30.853-08:00</updated><title type='text'>bonus: fireworks cheatsheet notes</title><content type='html'>So the designers at my work use a lot of Adobe Fireworks. It's a cool program. Its raw format is .png, but a cranked up .png that holds lots of stuff like layers, alpha transparency, and even vector information. For enginerds like me who tend to think in terms of pixels only (and maybe diving into crazy complexities like "layers") it's a lot to wrap our heads around... and watching a skilled artisan use it, and its ability to treat text and lines and pieces part as objects, even when they're not explicitly set on a different layer... it's eye-opening.&lt;br /&gt;&lt;br /&gt;So, as notes to my future self, I thought I'd write out just what I had to go through to make up the basic white-rectangle-with-drop-shadow images... in particular, how to use Fireworks to slice it into the top,middle, and bottom the final example used.&lt;br /&gt;&lt;br /&gt;Here are those notes:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;make a new image: ctrl-n, 500x500...&lt;/li&gt;&lt;li&gt;On toolbar stroke would be null (red line X, fill to white...), fill would be white&lt;/li&gt;&lt;li&gt;on the toolbar under vector, make the shape tool do rectangles not ellipse tool&lt;/li&gt;&lt;li&gt;draw the shape then handfix the W and H under Properties at the bottom (mostly the width)&lt;/li&gt;&lt;li&gt;Under Properties|Filters, Shadow and Glow | Drop Shadow&lt;/li&gt;&lt;li&gt;This pulls up some Filter properties. (By default the dropshadow is to the Southeast)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;so Filters is a list of effects added to this selection, you have to be careful not to make extra ones...&lt;/li&gt;&lt;li&gt;the arrows is distance, how far away the center of the shadow is from the center of the item... I want this at zero, centered, not off to one side&lt;/li&gt;&lt;ul&gt;&lt;li&gt;(which means I can ignore the angle for which direction it should go)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;I set the fuzziness bigger than 4, like 10 or so&lt;/li&gt;&lt;li&gt;you don't see changes applied 'til you close the filter mini-properties box&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Make sure the canvas itself has the null background selected (indicated with the red line) and you can see the gray and white boxes&lt;/li&gt;&lt;li&gt;Here I could select the rectangle with the selection tool, ctrl-c copy, ctrl-n (which autodefaults to the size of the thing in the clipboard), paste, then save. But of course I wanted my 3 slices...&lt;/li&gt;&lt;li&gt;now we need to use the slicing tool. You draw bounding boxes (including the dropshadow) and rely on the AI thing to find the right edges for you... I draw one for the top, bottom, and middle. At my first attempt I tried to close-crop the top and bottom without interior padding, but that messed up the shading of the corners, and I had to redo it.&lt;/li&gt;&lt;li&gt;Then I go to Export... the settings are QUITE a bit fiddly, what the helpful designer helped me figure out I wanted was "Export:Images Only" "HTML: [None]" "Slices:Export Slices" "Pages:Curent Pages" and "Include Areas without Slices" left unchecked&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;And that was it!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sometimes I dispair of ever deeply learning Adobe stuff. It seems like such a different, non-engineery, don't-try-to-understand-everything-we're-doing / intuitive system... or maybe the designers are just more used to. (GIMP. in contrast, is pure-Engineer, we-don't-give-you-any-convenient-defaults, no matter how logical it might be.)&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3086786597201255045?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3086786597201255045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/bonus-fireworks-cheatsheet-notes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3086786597201255045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3086786597201255045'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/bonus-fireworks-cheatsheet-notes.html' title='bonus: fireworks cheatsheet notes'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3298418384297229641</id><published>2011-12-22T11:26:00.000-08:00</published><updated>2011-12-22T12:12:24.992-08:00</updated><title type='text'>ie dropshadows with scale9grid... or not</title><content type='html'>(This is another one of those "see how the sausages get made", tales-from-the trenches post, vs a bright shining tale of victory and Zenlike CSS perfection.)&lt;br /&gt;&lt;br /&gt;So, dropshadows. Designers love'em! And why not, they bring an illusion of depth to the page and help set things apart. But man, they are a pain the butt to code sometimes... at least they are if you want to support IE. (I guess IE9 is starting to support this as well.)&lt;br /&gt;&lt;br /&gt;First, a note: the drop shadows I'm aiming for are kind of a fuzzy border all around the div, vs the kind hanging out on one corner (usually the lower-right.)&lt;br /&gt;&lt;br /&gt;Anyway, the CSS is still in that funky "each browser uses a prefix" state, so the code is like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; -moz-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; -webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);&lt;/span&gt;&lt;br /&gt;Not too bad, the result is like:&lt;br /&gt;&lt;br /&gt;&lt;style&gt;#basic_box{    box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);    -moz-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);    -webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.80);width:300px;height:100px;}&lt;/style&gt;&lt;br /&gt;&lt;div id="basic_box"&gt;Hi there!&lt;/div&gt;&lt;br /&gt;But of course that does nothing for IE &amp;lt;= 8. I fiddled around with some of IE's filters,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='gray', Positive='true');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;filter: progid:DXImageTransform.Microsoft.Shadow(color='#969696', Direction=135, Strength=3);&lt;/span&gt;&lt;br /&gt;but nothing was coming out right, either it made everyting blurry, or it was an old Win3.11 looking flat gray background, or the content of the div was rendering weirdly non-anti-aliased... we ended up going with a variation of this, and for a while letting IE users just hang with a thing gray 1px border.&lt;br /&gt;&lt;br /&gt;But I remembered this past spring when one of my co-UI guys was really excited about a plugin called&amp;nbsp;&lt;a href="http://code.google.com/p/scale9grid/"&gt;scale9grid&lt;/a&gt;. It's a pretty sweet of styling a div (as long as you don't mind depending on javascript and non-semantic CSS and images to do so) that can be any width or height, based on using an image as a &amp;nbsp;model for the borders (an image that presumably has a flat-colored center section where the content actually goes.) So you can have arbitrarily weird corners and sides and this plugin takes care off all the busy work.&lt;br /&gt;&lt;br /&gt;So in Fireworks (more on that in a bit) I styled up a nice alpha-channel (transparency) preserving PNG that is &lt;a href="http://kirkjerk.com/m/files/kirkdev/shadowbox/shadowboxer.png"&gt;shadowboxer.png&lt;/a&gt;:&lt;br /&gt;&lt;img src="http://kirkjerk.com/m/files/kirkdev/shadowbox/shadowboxer.png" /&gt;&lt;br /&gt;&lt;script src="http://kirkjerk.com/m/files/jquery.1.6.4.min.js"&gt;&lt;/script&gt;&lt;script src="http://kirkjerk.com/m/files/kirkdev/shadowbox/jquery.scale9grid-0.9.3.min.js"&gt;&lt;/script&gt;&lt;style&gt;#s9g_box{ background-color:white;  background-image:url("http://kirkjerk.com/m/files/kirkdev/shadowbox/shadowboxer.png"); width:200px; height:200px; padding:12px;}&lt;/style&gt;&lt;script&gt;$(document).ready(function(){$('#s9g_box').scale9Grid({top:12,bottom:12,left:12,right:12});});&lt;/script&gt;This can be used to make a box of any size.The code for this is pretty simple, in the CSS you need to set the background-image (something the page is a little slow to mention), the dimensions (I think), and some padding, so that your content isn't over the shadow itself:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; background-image:url("/shadowboxer.png");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; padding:12px;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then in jQuery, probably in the &lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(document).ready()&lt;/span&gt; you tell it how much of the sides of the original image you want to respect and use as the border:&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$('#element_id').scale9Grid({top:12,bottom:12,left:12,right:12});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="s9g_box"&gt;Hi there again!&lt;/div&gt;&lt;br /&gt;So, that's kinda nice. The trouble is, the panel we wanted it for was all animated. The width was fixed but the height was changing, and that goes beyond what scale9grid was designed for. It didn't change when the child content did, and you couldn't just reapply once the animation was done.&lt;br /&gt;&lt;br /&gt;So to let IE users back in on the fun, I decided to go with the old, slightly-gruesome, tried-and-mostly-true technique for fixed width things with funky borders: a special graphic-only div on top, the main content div with a repeating background, and a graphic-only div on the bottom. Sigh.&lt;br /&gt;&lt;br /&gt;The images I made up in Fireworks, and most of the other external files for this blog entry, are at&amp;nbsp;&lt;a href="http://kirkjerk.com/m/files/kirkdev/shadowbox/"&gt;http://kirkjerk.com/m/files/kirkdev/shadowbox/&lt;/a&gt;. I&amp;nbsp;imaginatively&amp;nbsp;called them "top" "mid" and "bot", and they can be used like this:&lt;br /&gt;&lt;br /&gt;&lt;style&gt;.top_box{ width:398px; height:14px;  background-image:url("http://kirkjerk.com/m/files/kirkdev/shadowbox/top.png");}.mid_box{  width:398px; height:218px;   padding:10px;  background-image:url("http://kirkjerk.com/m/files/kirkdev/shadowbox/mid.png");  background-repeat:repeat-y;}.bot_box{  width:398px; height:13px;  background-image:url("http://kirkjerk.com/m/files/kirkdev/shadowbox/bot.png");}&lt;/style&gt;&lt;br /&gt;&lt;div class="top_box"&gt;&lt;/div&gt;&lt;div class="mid_box"&gt;Are we having fun yet?&lt;/div&gt;&lt;div class="bot_box"&gt;&lt;/div&gt;The CSS then is something like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.top_box{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; width:398px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; height:14px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; background-image:url("top.png");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.mid_box{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; width:398px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; height:218px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; padding:10px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; background-image:url("mid.png");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; background-repeat:repeat-y;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;.bot_box{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; width:398px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; height:13px;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; background-image:url("bot.png");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What can I say, it works, and animates fine. One irritation was I first tried to cut the top and the bottom with no interior white padding, but that messed up the fading on the corners.&lt;br /&gt;&lt;br /&gt;It's depressing to get back to such a mundane solution, but at least I've reawakened my awareness of the potential of scale9grid, one more weapon in my UI Engineer arsenal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3298418384297229641?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3298418384297229641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/ie-dropshadows-with-scale9grid-or-not.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3298418384297229641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3298418384297229641'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/ie-dropshadows-with-scale9grid-or-not.html' title='ie dropshadows with scale9grid... or not'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7211182177799938898</id><published>2011-12-15T10:36:00.000-08:00</published><updated>2011-12-15T11:31:56.285-08:00</updated><title type='text'>image magick and text macros</title><content type='html'>After developing professionally for 15 years, I can appreciate when it's time to apply a quick and dirty solution.&lt;br /&gt;&lt;br /&gt;Sometimes it's my only option, a way of covering gaps in my knowledge-- for instance, I've never really had the chance to learn any Adobe product deeply, whether it's Flash, Photoshop, or Fireworks. And I've stuck with my manipulating tab-delimited files in Perl where more normal people might cozy up to Excel.&lt;br /&gt;&lt;br /&gt;So at&amp;nbsp;&lt;a href="http://alleyoop.com/"&gt;http://alleyoop.com/&lt;/a&gt;&amp;nbsp;we had a widget that would display sample math problems for various subtopics. Each image was a 380x136 png, but most had plenty of whitespace:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="1" src="http://1.bp.blogspot.com/-oP05j1AnqyQ/Tuo-7mWjoiI/AAAAAAAAAGQ/0CLAilgETPM/s1600/Volume.png" /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;We decided we didn't want to so much whitespace... but ideally we wouldn't have to have a design person resize all 204 images. What to do?&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Enter&amp;nbsp;&lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt;. This software has been around for a long while I think. A while back I used its Perl module as part of my image upload feature for my personal blog, so I could crop out extra white space on doodles and resize images to be more web-friendly on the server, rather than doing it locally and then reloading. And there's a handy Windows client.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The syntax is a little strange, but for trimming the file "Volume.png" I'd just do&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;convert Volume.png -trim Volume.png&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I chose the same file name for the output as the input (Weirdly, if I didn't specify the destination filename it would give me a file name "-trim".)&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So far, so good. But what' the easiest way to apply this command to all 204 files?&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I'm on Windows, and haven't bothered with CygWin, so I've learned a few coping tricks... like "dir /b" gives you a "bare" directory listing of just the filenames. I run the following command:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;dir /b *.png &amp;gt; trim.bat&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So now I have trim.bat, a flat file of filenames. Then I pull up trim.bat in an editor* and ran a macro that:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;home to to the start of the line and started the macro recording&lt;/li&gt;&lt;li&gt;shift-select to the end of the line&lt;/li&gt;&lt;li&gt;ctrl-x to cut the filename&lt;/li&gt;&lt;li&gt;type 'convert "'&lt;/li&gt;&lt;li&gt;ctrl-v to paste the filename&lt;/li&gt;&lt;li&gt;type '" -trim "'&lt;/li&gt;&lt;li&gt;ctrl-v to paste the filename&lt;/li&gt;&lt;li&gt;type '"'&lt;/li&gt;&lt;li&gt;down arrow to the next line, then home to jump to the start of it&lt;/li&gt;&lt;li&gt;end macro&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Then just hold down the macro replay key, and BAM, I have my ready to run batch file. Run it and my job here is done. (Macros are great, super fast to make with almost nothing to learn, just sometimes you have to think about the general case of what you're trying to do. Every developer should intimately know at least one editor with one button macro playback as well as a small set of text manipulation tools, like either Perl or awk and sed.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* on editors... lately I've been using Komodo Edit, despite its surprisingly long loading times. I kept my ancient copy of TextPad handy though, in part because its macro recording and playback was rock-solid and I sometimes had issues in Komodo Edit. But now it looks&amp;nbsp;&lt;a href="http://readwriteweb.com/hack/2011/12/infographic-what-tools-develop.php"&gt;like Notepad++ is what the cool kids are using&lt;/a&gt;, at least the ones not "cool" enough for developing on Mac. Can I say though, that given most Mac laptop's half-assed keyboard support (the lack of equivalents, or at least general obscurity, of simple keystrokes for Home, End, and ctrl-arrow to jump words) that I find this kind of thing much easier to do on Windows, and it's yet another reason I'm unlikely to switch, at least for my work stuff...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7211182177799938898?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7211182177799938898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/image-magick-and-text-macros.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7211182177799938898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7211182177799938898'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/image-magick-and-text-macros.html' title='image magick and text macros'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-oP05j1AnqyQ/Tuo-7mWjoiI/AAAAAAAAAGQ/0CLAilgETPM/s72-c/Volume.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7096561058882591214</id><published>2011-12-12T14:20:00.000-08:00</published><updated>2011-12-12T14:26:29.691-08:00</updated><title type='text'>animation nation part 2: introduction to raphael.js</title><content type='html'>&lt;div&gt;So the &lt;a href="http://kirkdev.blogspot.com/2011/12/animation-nation-part-1-processingjs.html"&gt;other day I was talking&lt;/a&gt; about making an animation for my company's registration process.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I quickly put together an animation proof-of-concept in ProcessingJS. I didn't go too far with it in part because IE is still in our target browsers, and ProcessingJS relies on the canvas object, so we couldn't use the result on the site.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;My thoughts turned to &lt;a href="http://raphaeljs.com/"&gt;Raphaël&lt;/a&gt;&amp;nbsp;in part because I knew it would work with IE. Superficially, Raphael is very similar to canvas-based APIs (in fact I thought it used a "shim" to let older versions of IE do canvas things) but really it's profoundly different... rather than a canvas of pixels, Raphael deals with SVG (&lt;a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics"&gt;Scalable Vector Graphics&lt;/a&gt;) vector objects. These objects are great because they deal with twisty lines and curves rather than squares, and you can scale them to any size without them getting pixel-y.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vector graphics require a different mindset than "regular". Specifically, Raphael is object oriented and once you've created your "paper" you add shapes and lines to it. Those shapes and lines then have attributes, similar to CSS attributes, that you can modify. The examples on the&amp;nbsp;&lt;a href="http://raphaeljs.com/"&gt;Raphael homepage&lt;/a&gt;&amp;nbsp;are impressive, and it's easy to make juicy effects, especially in terms of bouncy scaling and rotation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I wasn't crazy about the homepage's boilerplate for two reasons: one is I prefer something I can copy and paste into a blank document and hit the ground running. Here's some code that let me do that (once I pulled down a local copy of raphael-min.js)&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script src="raphael-min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;window.onload = function(){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; var paper = Raphael("thepaper", 320, 200);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; var circle = paper.circle(50, 40, 10);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; circle.attr("fill", "#f00");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; circle.attr("stroke", "#fff");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;div id="thepaper"&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second improvement I made was to use a name div as a canvas, rather than ask Raphael to provide the div and position it absolutely... I think it's more common that people will be embedding a bit of Raphael in a larger webpage, so an id'd div seems the way to go for that. However, that meant I couldn't let Raphael just run as commands directly in the script tags, I had to wrap it as a window.onload function (obviously, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(document).ready();&lt;/span&gt; is even a better bet if you're already using jQuery, I just wanted to remove the dependency.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Raphael documentation is a reference, not a tutorial, so you have to poke around... it probably helps if you know some of the basics of SVG.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In processing, I had made up a sine wave as a serious of short line segments. In Raphael, I figure I'd want a &lt;a href="http://haeljs.com/reference.html#Paper.path"&gt;Path&lt;/a&gt;: a path is a series of line and curve segments. Entertainingly, you define a path &lt;a href="http://www.w3.org/TR/SVG/paths.html#PathData"&gt;via a string&lt;/a&gt;, and a series of text commands. It reminded me of drawing with the language Logo and its turtle graphics in my youth.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So to see a Path in action, you can add this line to the boilerplate, which will draw a rotated chunky path.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;var p = paper.path("M50,50 L100,50 L100,100 L150,100 L150,50").rotate(45,50,50);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Some things to note:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Raphael uses the same kind of command chaining as jQuery, so I added the rotate command to the end.&amp;nbsp;&lt;/li&gt;&lt;li&gt;You can use commas or spaces as delimiters between commands and the arguments.&lt;/li&gt;&lt;li&gt;I used capital letters, so all the coordinates were absolute... if I had used lowercase, they would be relative to where we last drew.&lt;/li&gt;&lt;li&gt;By default angles are in degrees (i.e. 360 = circle).&amp;nbsp;&lt;/li&gt;&lt;li&gt;If I didn't specify the coordinates to rotate around, the Path would have rotated around its own center.&lt;/li&gt;&lt;li&gt;Raphael uses "painter order" rather than Z-indexing... the last thing you add to the Paper is what appears at front.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Once I was here, it still wasn't clear how to go forward in terms of making the animation I wanted. There's a pretty extensive set of animation features, but I couldn't figure out if there was a way to make the minor adjustments to the Path. (In fact, it turns out I can't even&amp;nbsp;&lt;a href="http://japhr.blogspot.com/2010/09/cant-animate-raphael-path-positions.html"&gt;rotate a Path&lt;/a&gt;&amp;nbsp;as an animation! Hmm.) So while I thought it would be "more Raphaelish" to make the objects once and then animate their attributes, it turned out I was going to have to do it similarly to the Processing version, and constantly create and destroy my path objects each tick.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To cut to the chase, here's what I ended up with, click kick to see it with some inertia, or just spin for a constant rotation:&lt;/div&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}&lt;/style&gt;&lt;iframe height="200" src="http://kirkjerk.com/m/files/kirkdev/helix/helix.html" width="100"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;div&gt;You can&amp;nbsp;&lt;a href="http://kirkjerk.com/m/files/kirkdev/helix/helix.html"&gt;go to the webpage to view the source&lt;/a&gt;&amp;nbsp;though it's a bit hacky and ugly...&lt;br /&gt;So comparing that animation to the original graphic:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-rPwQ7B2CKIo/TuZ6aHmYdsI/AAAAAAAAAF0/8X3SJo7mtHQ/s1600/DNAIcon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-rPwQ7B2CKIo/TuZ6aHmYdsI/AAAAAAAAAF0/8X3SJo7mtHQ/s1600/DNAIcon.png" /&gt;&lt;/a&gt;&lt;/div&gt;It's not 100%, but with the tweaking I did it's not bad. Our art guy was very pleased with the result.&lt;br /&gt;As the animation works, you can see where I had to add in additional "crossbeams" - the 2D original didn't have to worry about that. Also I couldn't quite figure out how to duplicate the "over under" cheat in the original, where they put a break in the underlying squiggle, so working with our art guy we decided to color one of the squiggles a bit darker.&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: -webkit-auto;"&gt;&lt;br /&gt;&lt;/div&gt;The thing is the animation flickered a bit on IE, and even on Firefox the constant motion was pushing the CPU to around 7-10%. I decided to punt-- I added a step button to move the animation one frame at a time, and then I laboriously constructed an animated GIF:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Yzx8NL2H9mk/TuZ73uVJRKI/AAAAAAAAAF8/IhED3_SIRNY/s1600/DNAIconAnimateNonStop.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-Yzx8NL2H9mk/TuZ73uVJRKI/AAAAAAAAAF8/IhED3_SIRNY/s1600/DNAIconAnimateNonStop.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Neat! Not quite as 3D as the Processing version, alas. (And since I was "cheating" and making a GIF anyway, I could have stuck with Processing.... in fact I might go and try that, since it's more powerful, and easier to push out a series of TIFs (rather than relying on screenshots like I did))&lt;br /&gt;&lt;br /&gt;Finally, we were looking for the animation to run for a bit, then stop, then restart. I made the GIF animate once, and then used jQuery like this when we wanted to see it spin:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;//first set up an offscreen image with the animated GIF:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;this.dnaImg = &amp;nbsp;new Image();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;this.dnaImg.src = '/components/onboarding/images/DNAIconAnimate.gif';&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;//later when we want it to animate, (re)set the&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;//src of the onscreen image to the offscreen one:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$('.dnago').attr('src',this.dnaImg.src);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Easy-peasy, and it added a lot of visual pizazz to that part of the site.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7096561058882591214?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7096561058882591214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/animation-nation-part-2-introduction-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7096561058882591214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7096561058882591214'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/animation-nation-part-2-introduction-to.html' title='animation nation part 2: introduction to raphael.js'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-rPwQ7B2CKIo/TuZ6aHmYdsI/AAAAAAAAAF0/8X3SJo7mtHQ/s72-c/DNAIcon.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2881822537142217093</id><published>2011-12-07T13:44:00.001-08:00</published><updated>2011-12-07T13:50:16.692-08:00</updated><title type='text'>animation nation part 1: processing.js</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;At work we thought it might be cool if we could jazz up the following bit of pseudo DNA (using Alleyoop's colors as the crossbars) that we are using during our signup process.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-oyn2mveIjU4/Tt_TqXggwEI/AAAAAAAAAFs/gPCsgdYi484/s1600/DNAIcon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-oyn2mveIjU4/Tt_TqXggwEI/AAAAAAAAAFs/gPCsgdYi484/s1600/DNAIcon.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I wondered if we could get a nice little 3D-ish effect by treating the helix strands as sin curves and then animating them by increasing the angle (Hey remember the &lt;a href="http://www.youtube.com/watch?v=2u3eQc_rx54"&gt;into to Superman II&lt;/a&gt;&amp;nbsp;? &amp;nbsp;Around 9 seconds in, the awesome spinning prison rings are actually 2 rings permanently welded together and then rotated as single unit... an awesome economical visual effect.)&lt;br /&gt;&lt;br /&gt;My goto language for this kind of thing is&amp;nbsp;&lt;a href="http://processing.org/"&gt;Processing&lt;/a&gt;. Processing is a little Java IDE and API that makes making applets really easy, and lets me leverage my 10-odd years of Java experience in a way that works on most any browsers to make gamejam games and my own toys. (With applet supporting waning over the years, I'm happy to see stuff like Minecraft exercising Java as a viable game platform.)&lt;br /&gt;&lt;br /&gt;An applet would be overkill for the task (not to mention raising the spectre of Content-y and plugin warnings) so I turned to Processing's little brother&amp;nbsp;&lt;a href="http://processingjs.org/"&gt;Processing.js.&lt;/a&gt;&amp;nbsp;It's an HTML5, javascript/canvas based version of Processing. It has 2 modes: one where it can (try to) run the exact same ".pde" files as the Java version, and another where it acts as a highpowered API to the canvas object for more traditional javascript code. I knew Processing.js might not be acceptable for use on our actual site, since it depends on the canvas object that is only now getting support by IE, but I decided to give it a whirl anyway.&lt;br /&gt;&lt;br /&gt;The pde "run the java code" mode is in preferred, but for my money it's not ready for prime time. It is essentially using a preprocessor to translate Java code into javascript, and the results aren't always pretty, especially for stuff involving classes and collections of mixed object types. The error messages are often extremely opaque or absent altogether.&lt;br /&gt;&lt;br /&gt;Despite the problems, Processing.js is still a lot of fun, especially with one of the inbrowser IDEs like&amp;nbsp;&lt;a href="http://sketchpad.cc/"&gt;sketchpad.cc&lt;/a&gt;. You can type code and almost instantly see results, part of the charm of both versions of Processing.&lt;br /&gt;&lt;br /&gt;Nearly every Processing program has two main parts: setup(), where one time activities are performed, and draw() which is called every frame. Most Processing programs (at least the ones I've written) clear the background every frame and draw the entire frame from scratch, but some just keep drawing on the same canvas.&lt;br /&gt;&lt;br /&gt;Here's what I came up with. Apologies for the code that follows -- it's mostly hacking around proof-of-concept stuff, and there are a lot of "magic numbers" there I tweaked to make it look good... not exactly like the model, but enough to see that a spinning 3D effect could emerge from a sine wave fragment place against the flipped version of itself and constantly having its starting angle increased. Essentially the variable x1 runs through the horizontal values, x2 is the next value (for drawing line segments) and we get the two y values by running the sin() function. And then at certain x1 values, we draw the cross pieces.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre-wrap; word-wrap: break-word;"&gt;void setup() {&lt;br /&gt;    size(200, 200); &lt;br /&gt;    smooth();&lt;br /&gt;    frameRate(30);&lt;br /&gt;    strokeWeight(10);&lt;br /&gt;} &lt;br /&gt;float off = 0;&lt;br /&gt;void draw() {  &lt;br /&gt;background(255);&lt;br /&gt;pushMatrix();&lt;br /&gt;translate(120,0);&lt;br /&gt;rotate(3.14 / 4);&lt;br /&gt;&lt;br /&gt;off += .1;&lt;br /&gt;for(float x1 = 0; x1 &amp;lt; 120; x1++){&lt;br /&gt;    float x2 = x1 + 1;&lt;br /&gt;    float a1 = off + x1 / 40;&lt;br /&gt;    float a2 = off + x2 / 40;&lt;br /&gt;    float y1 = 20 * sin(a1);    &lt;br /&gt;    float y2 = 20 * sin(a2);    &lt;br /&gt; &lt;br /&gt;    if((x1 +1) % 31 == 0){&lt;br /&gt;       stroke(255,0,0);&lt;br /&gt;       line(x1,100,x2,y2+100);&lt;br /&gt;       line(x1,100,x2,-y2+100);&lt;br /&gt;    }&lt;br /&gt;    stroke(128);&lt;br /&gt;    line(x1,y1+100,x2,y2+100);&lt;br /&gt;    line(x1,-y1+100,x2,-y2+100);&lt;br /&gt;}&lt;br /&gt;popMatrix();&lt;br /&gt; &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's the result (IE users are out of luck, in this way and in so many others...)&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://kirkjerk.com/m/files/kirkdev/helix/procjs.html" style="height: 200px; width: 200px;"&gt;&lt;/iframe&gt;&lt;br /&gt;Not half bad if I do say so myself! The effect was very sensitive to little tweaks.&lt;br /&gt;&lt;br /&gt;Next up: the same idea in Raphael.js... a very different tool that works on all the major browsers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2881822537142217093?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2881822537142217093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/animation-nation-part-1-processingjs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2881822537142217093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2881822537142217093'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/animation-nation-part-1-processingjs.html' title='animation nation part 1: processing.js'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-oyn2mveIjU4/Tt_TqXggwEI/AAAAAAAAAFs/gPCsgdYi484/s72-c/DNAIcon.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-6086902108232657145</id><published>2011-12-05T14:12:00.001-08:00</published><updated>2011-12-05T14:15:52.623-08:00</updated><title type='text'>worthy read</title><content type='html'>&lt;a href="http://www.asktog.com/columns/085BrowseVsSearch.html"&gt;Ask Tog about Search vs Browser on iOS&lt;/a&gt;. I need to figure out how to push my self ever more firmly into the "HCI expert" camp.&lt;br /&gt;&lt;br /&gt;I have an ancient copy of "&lt;a href="http://www.asktog.com/books/toi_detail.html" style="background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-size: small; text-align: -webkit-left;"&gt;&lt;i&gt;Tog on Interface&lt;/i&gt;&lt;/a&gt;" on my bookshelf, I should dust it off and give it a browse. (Or a search.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-6086902108232657145?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/6086902108232657145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/worthy-read.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6086902108232657145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6086902108232657145'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/worthy-read.html' title='worthy read'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3889206061849122880</id><published>2011-12-02T09:17:00.001-08:00</published><updated>2011-12-07T14:27:23.175-08:00</updated><title type='text'>javadvent 2011 and processing</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Dz2mXQdf1Yk/TtkMXFCkx8I/AAAAAAAAAFY/RPjRjJfL32A/s1600/javadvdent.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Dz2mXQdf1Yk/TtkMXFCkx8I/AAAAAAAAAFY/RPjRjJfL32A/s1600/javadvdent.png" /&gt;&lt;/a&gt;&lt;/div&gt;So, some years I make an Advent Calendar, with a different unique miniature videogame or virtual toy for every day of December up 'til Christmas... for this year it's at&amp;nbsp;&lt;a href="http://kirkjerk.com/java/advent2011/"&gt;http://kirkjerk.com/java/advent2011/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's a fun exercise in UI design, trying to come up with 25 fun but fairly intuitive interactions. (I still provide instructions, but I kind of wish I didn't have to.) Also, the style of Advent Calendars, with a small distinct treat every day, makes a kind of delightful "interface". The calendar itself is basically a copy and paste of the&amp;nbsp;&lt;a href="http://kirkjerk.com/java/advent2009/"&gt;2009 Edition&lt;/a&gt;&amp;nbsp;(except I made it so only one entry is visible at a time, multiple instances open tends to bog down machines.) It's HTML and CSS and Perl from when I didn't know any jQuery, and it kind of shows, though I think it gets the job done, and is fairly sophisticated at making it difficult to peek ahead.&lt;br /&gt;&lt;br /&gt;They entries themselves are written in a Java IDE/library called&amp;nbsp;&lt;a href="http://processing.org/"&gt;processing&lt;/a&gt;. I love keeping my Java chops maintained a bit, and these little bite sized morels were perfect to code on the subway, to and from work. Unfortunately, Java applet support seems to get shakier and shakier as time goes on...&lt;br /&gt;&lt;br /&gt;There is a javascript version called&amp;nbsp;&lt;a href="http://processingjs.org/"&gt;processing.js&lt;/a&gt;&amp;nbsp;which in theory runs the same programs, is all HTML5-y, and works natively in browsers. It has some awesome things like in-browser IDEs (&lt;a href="http://sketchpad.cc/"&gt;http://sketchpad.cc/&lt;/a&gt;&amp;nbsp;was my favorite) There are some drawbacks though: it doesn't support IE (at least before 9? Not sure) and it's far from 100% code compatible with the Java verison.&lt;br /&gt;&lt;br /&gt;But Processing is a fun language especially for fun and impressive prototyping. I also use it for the 2 hour "Klik of the Month" game jams at&amp;nbsp;&lt;a href="http://www.glorioustrainwrecks.com/"&gt;Glorious Trainwrecks&lt;/a&gt;, and even for the longer 48 hour "Global Game Jams". You can see some of both at my portfolio site&amp;nbsp;&lt;a href="http://alienbill.com/"&gt;alienbill.com&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3889206061849122880?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3889206061849122880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/javadvent-2011-and-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3889206061849122880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3889206061849122880'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/javadvent-2011-and-processing.html' title='javadvent 2011 and processing'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-Dz2mXQdf1Yk/TtkMXFCkx8I/AAAAAAAAAFY/RPjRjJfL32A/s72-c/javadvdent.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2840042689205550333</id><published>2011-12-01T10:56:00.001-08:00</published><updated>2011-12-01T11:07:14.878-08:00</updated><title type='text'>preload your images</title><content type='html'>&lt;br /&gt;Sometimes when building a dynamic site, you might want to load some images after the page has loaded but before the images are shown so that when they do show the appear instantly.&lt;br /&gt;&lt;br /&gt;I forget where I found this paradigm, probably somewhere on stackoverflow, but it seemed to work a treat:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;function preload(sources, prefix)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; var images = [];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; for (var i = 0; i &amp;lt; sources.length; ++i) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; images[i] = new Image();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var src = sources[i];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(prefix != undefined){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;src = prefix + src;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; images[i].src = src;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(Ha, I can tell it's not all my code, I never do "++i".) Sources is an array of image names, prefix is an optional parameter that might contain the URL for the directory where the images are located, so you don't have to include the path on each image name. Then when you actually show the image it should be ready to go, instantly.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2840042689205550333?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2840042689205550333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/12/preload-your-images.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2840042689205550333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2840042689205550333'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/12/preload-your-images.html' title='preload your images'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-4839068712913392645</id><published>2011-11-30T13:58:00.001-08:00</published><updated>2011-12-29T17:18:27.891-08:00</updated><title type='text'>windows kudos, osx phoodos</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;So here's something from Windows that I think belongs in a UI Hall of Fame. It's the Location bar of the Windows 7 File Explorer:&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-hQtssqRAmEM/Ttan3xeyBwI/AAAAAAAAAEg/L9fO7zUSsSA/s1600/before.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-hQtssqRAmEM/Ttan3xeyBwI/AAAAAAAAAEg/L9fO7zUSsSA/s1600/before.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: -webkit-auto;"&gt;It shows you the current folder location in a logical, breadcrumb manner. Hover over part of the current location:&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/-PW3zj3RRGQM/TtaoWZgHa2I/AAAAAAAAAEo/l55kKEZMdFQ/s1600/during.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-PW3zj3RRGQM/TtaoWZgHa2I/AAAAAAAAAEo/l55kKEZMdFQ/s1600/during.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BAM! It fades into a button, and you can click it and hop the folder's view to that location. That's brilliant! (Somewhat less brilliant because it's getting more obscure: (AKA I didn't realize it 'til just now:) click the arrow to the right to hop to siblings of that folder.)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;(UPDATE: OSX has a "Show Path Bar" option that brings up a similar breadcrumb-y view. You can even hop up to any of the parents, but you have to double click, which seems unfriendly to me.)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;But the really great part is clicking on the location bar just outside of the visible path:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-F3K45B7QGMo/Ttan2fJt9OI/AAAAAAAAAEY/92x5EaJRxIQ/s1600/after.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-F3K45B7QGMo/Ttan2fJt9OI/AAAAAAAAAEY/92x5EaJRxIQ/s1600/after.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;DOUBLE BAM! That is a text version of the path, pre-select for your Ctrl-C copying convenience. Now, even if you're not using the dear old command line much, it's still hugely useful: in any standard file dialog, you can paste that into the filename, press return, and now you're ready to save your file in that location. (OSX sort of does something similar if you start typing with a slash, but it's heart isn't really in it.)&lt;br /&gt;&lt;br /&gt;So I don't know if that is a "poweruser" usecase, but I find it hugely intuitive and fast, fast, fast. Now, there are imperfections in this system of text versions of the path-- if you click for a file path when you happen to be doing a search, the result is an unreadable mess that you can't really usefully paste anywhere. But there are other nice touches to the widget that I'm not even going into here.&lt;br /&gt;&lt;br /&gt;Speaking of standard file dialogs, here's a bit of crapness from OSX. Here's a file save as dialog.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-zCZ1i6cC1Wc/TtaqhMOihEI/AAAAAAAAAE4/PX8Jh43kX-w/s1600/Screen+Shot+2011-11-28+at+7.55.22+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="162" src="http://3.bp.blogspot.com/-zCZ1i6cC1Wc/TtaqhMOihEI/AAAAAAAAAE4/PX8Jh43kX-w/s320/Screen+Shot+2011-11-28+at+7.55.22+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;So that "Where" interaction,&amp;nbsp;showing a small list of common spaces you might want to Save To,&amp;nbsp;&amp;nbsp;is something relatively new in UI land. Windows does it too, but the dropdown menu is used to control a larger folder view. So you can jump to one of the standard areas, and from there, say, create a new folder, or go up a level, or do the usual folder manipulations:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-dk9E752i-IE/Ttasu8U3NeI/AAAAAAAAAFQ/djmZn96uXFE/s1600/windows.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="234" src="http://4.bp.blogspot.com/-dk9E752i-IE/Ttasu8U3NeI/AAAAAAAAAFQ/djmZn96uXFE/s320/windows.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And so I figured that that functionality must be somewhere in the OSX file dialog, that I could save somewhere other than exactly one of the pre-ordained file locations... but where? How do I get to it?&lt;br /&gt;&lt;br /&gt;Answer: that small triangle to the right of the filename. That changes the look of the dialog to this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-ayJMV3MqBAs/Ttaqi77UgII/AAAAAAAAAFA/0cVcBNDuvfA/s1600/Screen+Shot+2011-11-28+at+7.55.42+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="252" src="http://4.bp.blogspot.com/-ayJMV3MqBAs/Ttaqi77UgII/AAAAAAAAAFA/0cVcBNDuvfA/s320/Screen+Shot+2011-11-28+at+7.55.42+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;That's better... but why is it so hard to find and why is it like that in the first place? I like thinking through the challenges UI designers must have faced, because sometimes you realize there's a complicating detail... Why isn't the more flexible view part of the dialog to begin with? I guess to simplify things, stop people from getting overwhelmed with options, while satisfying an 80/20 (70/30?) rule about where a user wants to put something. So why is it arrow to the right of the filename, and not the "Where" dropdown? (It is functionality related to the location, not the filename...) I guess because the "Where" dropdown changes form enough in the new mode that the up arrow to put it back might get lost. But it seems unintuitive to me. (Meaning I had to go ask a more experienced OSX user where to go for it.) Combine it with the way I've lost my ability to copy and paste a path here, and I have to say, I find the Windows experience superior.&lt;br /&gt;&lt;br /&gt;(I know Mac fans stuck working on Windows probably miss the 3 column view for its folder viewer, along with the too-cool-by-half "Cover Flow", but for me, I'd rather have the ability to easily transfer path information around. &lt;i&gt;UPDATE: OSX has this functionality, by dragging the icon at the top of a Finder window onto a dialog. Even given my lack of experience with OSX, this seems a little fiddly to me, where I might think I was trying to move the folder to whatever location the dialog was open to.&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;Another OSX-ism I find irksome: the default Preview program is great for quick viewing, except it has no concept of "go to the next file in this folder". What's weird is that the basic functionality is in place: it does the right thing if you &lt;strike&gt;drag and drop a bunch of files onto it once, or &lt;/strike&gt;select the files and right click and hit "Open with Preview.app" (Sorry, I was wrong: Preview doesn't support drag and drop.) I have had friends who are bigger fans of OSX say I was expecting the wrong thing, that file systems are arbitrary ways of holding a bunch of files anyway, that a more realistic usecase is just using iPhoto for all this stuff, but, whatever man. It was a detail I think they could have done gotten better, and it makes my life on OSX less easy than my life with Windows.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-4839068712913392645?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/4839068712913392645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/windows-kudos-osx-phoodos.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4839068712913392645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4839068712913392645'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/windows-kudos-osx-phoodos.html' title='windows kudos, osx phoodos'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-hQtssqRAmEM/Ttan3xeyBwI/AAAAAAAAAEg/L9fO7zUSsSA/s72-c/before.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-6249065320763494546</id><published>2011-11-28T06:47:00.001-08:00</published><updated>2011-12-29T17:26:24.815-08:00</updated><title type='text'>why windows' taskbar beats osx' dock</title><content type='html'>OS preference is, generally, a subjective thing. With the gradual&amp;nbsp;ascendancy of Apple underway, I'd like to take a second and analyze how the two OSes relate, and where I think Windows has done a consistently better job. This will reflect some of my personal preferences (and, possibly, the way my mind has been warped by 15-odd years of Windows-isms-- any analysis like this has to recognize that we tend to like what we find familiar) but I will point to some objective differences between the systems.&lt;br /&gt;&lt;br /&gt;First, a random note on the screenshots: I'm one of those quirky people who puts the app controller on the side of the screen. I&amp;nbsp;&lt;a href="http://kisrael.com/2006/11/23/"&gt;wrote up why on my blog&lt;/a&gt;&amp;nbsp;about 5 years ago: there are a few advantages, first and foremost is how it makes better use of the "widescreen" format laptops and monitors now sport (I mean, have you seen how short the screen is on a 11" MacBook Air?)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-tCtwjoKWxXk/TtOmsAHJM8I/AAAAAAAAAEA/XrbHzMTnXyI/s1600/windows_task_bar.jpg" imageanchor="1" style="float: left; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-tCtwjoKWxXk/TtOmsAHJM8I/AAAAAAAAAEA/XrbHzMTnXyI/s320/windows_task_bar.jpg" width="69" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/-koLBScgMH24/TtOm4KEb5RI/AAAAAAAAAEI/DXte453Hmds/s1600/Screen+Shot+2011-11-28+at+7.39.36+AM.png" imageanchor="1" style="float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-koLBScgMH24/TtOm4KEb5RI/AAAAAAAAAEI/DXte453Hmds/s320/Screen+Shot+2011-11-28+at+7.39.36+AM.png" width="30" /&gt;&lt;/a&gt;So to the left is the Windows taskbar and the right is the OSX dock... both have their graphical bells and whistles. Windows (at least as of 7) has some&amp;nbsp;translucency&amp;nbsp;going on - on my work machine it's really sophisticated, with an "active window" highlight color and some pretty light effects as the mouse passes over it. The Dock has that terrifically fun "magnify" effect, where the icons fluidly grow and shrink as you pass the mouse cursor over it.&lt;br /&gt;&lt;br /&gt;The primary difference between these two bars is this: &lt;b&gt;The Taskbar is Window based, the Dock is Application based.&lt;/b&gt;&amp;nbsp;This is why I think the Windows approach is superior for a multitasking operating system: each window maps to a task, a bit of state I might want to return to, and the Taskbar offers a passive,&amp;nbsp;unobtrusive&amp;nbsp;reminder of each window and a way to get back to it. (Kind of a dynamic "todo list") With the Dock, each icon is an application. There is no direct jump to a given window, just that application. (OSX offers some other paradigms for getting back to where you were, more on that in a bit.)&lt;br /&gt;&lt;br /&gt;Let's start with Windows.&amp;nbsp;Every window gets its own place in the task bar... (before Windows 7, the "launch a new program" icons were either hidden behind the Start button, or later, on a little specialized "quick launch" piece of the taskbar. Nowadays you always have the option of "pinning" an application to the taskbar, which comingles the running and launching icons.) The difference between a Window of a running program and an icon to launch a new instance is obvious: the former is a button with a caption, the latter is just an icon. (&lt;strike&gt;The disadvantage is launching a new window of a running program from the taskbar is a bit awkward, it's the first option on the right click menu.&amp;nbsp;It's not that big of an issue thought because browsers and most document editors use File|New or Ctrl-N to open a new workspace.&lt;/strike&gt;&amp;nbsp;UPDATE: &lt;b&gt;WorldMaker&lt;/b&gt;&amp;nbsp;points out you can middle click on a running task button to pop open a new window.)&lt;br /&gt;&lt;br /&gt;With the Dock, the visual difference between a running and launchable program is minimized: a small white dot. Click on the icon and its windows move to the front. Again, to me there's a huge difference between a running program (carrying state I want to be reminded of or get back to) and a launchable program (which is a clean slate) and so I find Windows' approach to be superior.&lt;br /&gt;&lt;br /&gt;This App-centric approach carries through to the quick switching. With Windows, I hit alt-Tab and I see a sorted list of my windows. OSX has a similar function, but again I'm looking at placeholders for whole apps, not a window at a time, once I switch to the right app I still have to find the window I'm thinking of. I know there are different apps to adjust the OSX environment, but I think getting the defaults right is crucially important-- having to relearn how to get around a friend's computer running the same OS because they don't have the same "fix" installed stinks.&lt;br /&gt;&lt;br /&gt;It could be argued that I'm doing it wrong, expecting OSX to act like Windows instead of adapting to what OSX offers. For a long while OSX has had exposé, a single button that temporarily resizes and repositions all of your windows (or makes snapshot thumbnails, based on how you think of it) so that they are all visible at once. OSX Lion's Mission Control furthers that paradigm. While I might be getting old and curmudgeonly, I don't like&amp;nbsp;exposé as much as Windows' system, in part because it lacks the "quick bounce back" of alt-tab, where a quick tap of alt-tab brings me back to what I was last working on (Windows has a really good "most recently used" algorithm for tasks, an easy to miss but hugely important detail that Just Works.)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;UPDATE: OSX does have cmd-` (very easy to find above cmd-tab, kudos for that choice) that cycles through open windows of the current application. But this interaction is application oriented, you can't gracefully leap back to what you were doing in a different application like you can with Window's alt-tab.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;(I guess I should say, Windows 7's defaults are a bit different than what I'm describing here... I set Windows to "Never combine" Taskbar buttons, and so I don't see the roughly&amp;nbsp;exposé like thumbnails Windows makes now.)&lt;br /&gt;&lt;br /&gt;This differences harken back to one of the oldest differences between Windows and MacOS-- with Mac, there's one place on the whole screen where the "File" menus will appear: each app takes over that space. (It's kind of ironic that it took OSX so long to get fullscreen mode right.) This kind of points to the idea of Mac as "information appliance"-- the whole machine is dedicated to that app. On iOS I find this &lt;a href="http://betanews.com/2010/06/15/i-was-wrong-about-apple-ipad/"&gt;perfect and relaxing&lt;/a&gt;, but I find it irksome on a multitasking system. (I know people argue that there are advantages to the menubar-on-top paradigm of Mac, that you always know where to look, and your mouse can target the menu faster, but for me those bonuses are outweighed by having to figure out which menu bar applies to which window.)&lt;br /&gt;&lt;br /&gt;I have some more thoughts on Windows vs OSX, but that can wait 'til next time...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-6249065320763494546?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/6249065320763494546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/why-windows-taskbar-beats-osx-dock.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6249065320763494546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/6249065320763494546'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/why-windows-taskbar-beats-osx-dock.html' title='why windows&apos; taskbar beats osx&apos; dock'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-tCtwjoKWxXk/TtOmsAHJM8I/AAAAAAAAAEA/XrbHzMTnXyI/s72-c/windows_task_bar.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-4749003316089926738</id><published>2011-11-21T08:16:00.001-08:00</published><updated>2011-11-22T12:29:03.438-08:00</updated><title type='text'>room to write</title><content type='html'>Apologies for the less-than-fully-assed entry that follows:&lt;br /&gt;&lt;br /&gt;I thought a pretty common task for jQuery would be to make a textarea automatically expand as content was added into it. And a bit of googling shows that a number of people have taken a stab at it. But it looks like no one has gotten it quite right, and I don't have enough time and energy to fix that.&lt;br /&gt;&lt;br /&gt;The best I found is&amp;nbsp;&lt;a href="https://github.com/padolsey/jQuery.fn.autoResize"&gt;padolsey's jQuery.fn.autoResize&lt;/a&gt;. Once you include the .js file usage is trivial:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(document).ready(function() {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; $('textarea').autoResize();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are some configuration options as well.&lt;br /&gt;&lt;br /&gt;I'm not 100% enamored of it: if you edit the value manually (like by calling $("textarea").val()) , the thing is not resized, and while it has basic coverage for resizing when users paste in text, it gets a bit wonky.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-4749003316089926738?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/4749003316089926738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/room-to-write.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4749003316089926738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4749003316089926738'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/room-to-write.html' title='room to write'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7598133813774966873</id><published>2011-11-17T07:18:00.001-08:00</published><updated>2011-11-17T07:22:02.937-08:00</updated><title type='text'>prettier json</title><content type='html'>Yesterday I talked about JSON, and the inspect() method I use. While that example actually did some nice indenting, sometimes I have a mass of untabbed JSON I'd like to visually inspect. The best tool I've found for that is&amp;nbsp;&lt;a href="http://json.parser.online.fr/"&gt;http://json.parser.online.fr/&lt;/a&gt;&amp;nbsp;. Slightly confusingly it shows both the "String parse" and the "JS eval" versions of the string, but usually it doesn't matter which one you look at. The way it builds a treeview of the code is really nice.&lt;br /&gt;&lt;br /&gt;Before finding that page I used to just Google for "json pretty print" which would lead me to&amp;nbsp;&lt;a href="http://www.cerny-online.com/cerny.js/demos/json-pretty-printing"&gt;Cerny.js' entry&lt;/a&gt;&amp;nbsp;as well as&amp;nbsp;&lt;a href="http://jsonformatter.curiousconcept.com/"&gt;curiousconcept's&lt;/a&gt;. Both are ok in a pinch, I think the former sometimes got confused by special characters in the content, even if they were properly escaped.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7598133813774966873?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7598133813774966873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/prettier-json.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7598133813774966873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7598133813774966873'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/prettier-json.html' title='prettier json'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-1810458800725331771</id><published>2011-11-16T09:42:00.001-08:00</published><updated>2011-11-16T10:00:49.662-08:00</updated><title type='text'>loggin'</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/-MiIm6_naCas/TsP40Qd5OhI/AAAAAAAAADU/dOlzvEY9X1Y/s1600/2011.11.16.logging.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-MiIm6_naCas/TsP40Qd5OhI/AAAAAAAAADU/dOlzvEY9X1Y/s1600/2011.11.16.logging.png" /&gt;&lt;/a&gt;Yesterday I mentioned the importance of "log-based debugging". It's crucial to browser-based work, in part because alert()s and stepping through with the debugger mess up the timing of stuff, so they're not as much help for timing-related issues. I also think the act of putting in log statements forces a programmer to challenge their assumptions.&lt;br /&gt;&lt;br /&gt;For reasons that are obscure to me, at work we call our main debug function "ccdebug". Its code is like this:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function ccdebug(s) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; if (typeof console != "undefined" &amp;amp;&amp;amp; typeof console.log != "undefined") {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; console.log(s);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; }&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pretty simple! The check for console existing is necessary for preventing errors when the console isn't around...&lt;br /&gt;&lt;br /&gt;I've been using that for just under 100% of my log statements... poking around I realize we have equivalents for console.warn() and console.error(). In firebug, the former has a nice yellow highlight, and the latter even includes a stack trace. So to improve my practice, I should probably start differentiating my information and coding messages from messages for more serious problems.&lt;br /&gt;&lt;br /&gt;One other function I find useful, with both console.log() and good old alert():&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;function inspect(thing, indent){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(indent == undefined || indent == true){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;return JSON.stringify(thing, undefined," ");&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return &amp;nbsp;JSON.stringify(thing);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;div&gt;That's just a great way to see the content of data structures and what not. The indent makes it a lot more readable, so I include it as the default.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-1810458800725331771?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/1810458800725331771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/loggin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1810458800725331771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1810458800725331771'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/loggin.html' title='loggin&apos;'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-MiIm6_naCas/TsP40Qd5OhI/AAAAAAAAADU/dOlzvEY9X1Y/s72-c/2011.11.16.logging.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5988814146519508324</id><published>2011-11-15T14:34:00.000-08:00</published><updated>2011-11-15T15:10:06.812-08:00</updated><title type='text'>simplicity simplicity simplicity -- shouldn't that just be 'simplicity'?</title><content type='html'>The other day I was thinking of Richard Gabriel's classic&amp;nbsp;&lt;a href="http://www.jwz.org/doc/worse-is-better.html"&gt;The Rise of 'Worse is Better'&lt;/a&gt;. The article has a kind of old context, but I think its core is still valid. (I also appreciate the vacillation within the article; these are issues about style and mood where there won't be a single correct answer.)&lt;br /&gt;&lt;br /&gt;As the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Worse_is_better"&gt;Wikipedia Page&lt;/a&gt;&amp;nbsp;reiterates, the core components of "Worse is Better" are, in roughly descending order:&lt;br /&gt;&lt;dl&gt;&lt;dt&gt;Simplicity&lt;/dt&gt;&lt;dd&gt;The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. &lt;b&gt;Simplicity is the most important consideration in a design&lt;/b&gt;.&lt;/dd&gt;&lt;dt&gt;Correctness&lt;/dt&gt;&lt;dd&gt;The design must be correct in all observable aspects. &lt;b&gt;It is slightly better to be simple than correct&lt;/b&gt;.&lt;/dd&gt;&lt;dt&gt;Consistency&lt;/dt&gt;&lt;dd&gt;&lt;b&gt;The design must not be overly inconsistent&lt;/b&gt;. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either complexity or inconsistency in the implementation.&lt;/dd&gt;&lt;dt&gt;Completeness&lt;/dt&gt;&lt;dd&gt;The design must cover as many important situations as is practical. All reasonably expected cases should be covered. &lt;b&gt;Completeness can be sacrificed in favor of any other quality&lt;/b&gt;. In fact, completeness must be sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.&lt;/dd&gt;&lt;/dl&gt;The essay goes on to explain why these factors can be crucial to a technology really taking off.&lt;br /&gt;&lt;br /&gt;I find a rough analogy in my professional life as a UI Engineer when it comes to the selection of toolkits. I had a miserable time with "Wicket" and its bizarro blend of delicate flower Java class/HTML pairs. (It was barely ok for light work, but god help you in having to learn this whole lifecycle flow if something went wrong or you wanted to make your own component.) These days I've been arguing sticking with basic jQuery rather than taking on some heavier duty toolset like YUI or jsMVC.&lt;br /&gt;&lt;br /&gt;So I ask myself, am I just a stick-in-the-mud curmudgeon who hates to learn new stuff? That's at least partially true: I'm much more interested in what technology can empower me to build than in the tools themselves, so I'm only interested in new toolsets when they let me do something new or in a vastly easier way, not just something old in a slightly more concise way. But I think there's something deeper in my preference for light weight toolkits, more profound...&lt;br /&gt;&lt;br /&gt;I've said "People and computers should be judged by what they do, not by what (you think) they are." No one cares how finely crafted the objects in your code are, they just want to know, does it do the job well, and have you set yourself up to do the next few, slightly different jobs well.&amp;nbsp;When I'm debugging, it's because the system is DOING something wrong, and I need to correct that behavior. My tools are-- lo and behold-- a debugger! and thoughtful logging... (good old log-based debugging is a crucial tool. I say that's because it forces you to think about what your preconceptions are at each step of the way, and then show them in action. But there's a chance it might also be because the debugging tools I used in college were so awful and opaque. Also, debuggers mess with the timing of stuff.)&lt;br /&gt;&lt;br /&gt;Anyway, when I'm debugging, in a debugger, if I'm mostly looking at other's people code in the stacktrace, my job is much, much tougher. Most toolkits are extremely configuration heavy. (Toolkits by their nature don't just solve YOUR problem, but a hundred other problems as well, so you have to specify lots of things) It takes a fair amount of expertise and learning to set them up right, which costs time-- time you often don't have, the whole reason you're using the toolkit is for it to quickly solve your issue-- and when things break, there's often a huge gap between the misbehaving code and your error. The lighter the toolkit, the more likely the mistake is near where the debugger is showing the problem, the nearer the observed effect is from the code that caused it.&lt;br /&gt;&lt;br /&gt;JQuery, I hardly ever have super tough to understand problems with. The few times the issue shows up in "jquery.min.js" itself, its been where I'm setting some property IE thinks should be read only or some such. Other tools I used, like Java RichFaces, the situation was much, much hairier. But with basic Javascript calling jQuery when needed, I can get to the problematic code easily.&lt;br /&gt;&lt;br /&gt;Now this argument could be taken to an illogical extreme. I'm not saying you should code in assembly or anything like that... but your toolkits should be simple, reliable, and your widgets and libraries should be of the do one (hopefully difficult) thing and do it well.&lt;br /&gt;&lt;br /&gt;(Of course, someone pointed out another reason to hate toolkits is they put a coating over the 90% of coding that is easy and pleasant and 'hey I built this!' and leave behind the 10% that is difficult anyway, and how you earn your pay... in fact they usually make that 10% significantly harder.)&lt;br /&gt;&lt;br /&gt;Continuing the comparison to assembly, you still get people trying to spin Javascript as the Assembly language of the web, the code that all browsers speak, and it shows up in your debugger, but not what you want to be coding in. This kind of thinking is weak, because the additional layers, while slick and clever (epecially in the early baby tutorials) don't actually let you say stuff new. A concise essay about that in terms of toolkits is Uriel Katz'&amp;nbsp;&lt;a href="http://www.urielkatz.com/archive/detail/why-javascript-not-new-assembly/"&gt;Why JavaScript is NOT the new Assembly&lt;/a&gt;&amp;nbsp; and a longer one against CoffeeScript and other pre-processor type languages is&amp;nbsp;&lt;a href="http://blog.izs.me/post/10213512387/javascript-is-not-web-assembly"&gt;blog.izs.me's "JavaScript is Not Web Assembly"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5988814146519508324?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5988814146519508324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/simplicity-simplicity-simplicity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5988814146519508324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5988814146519508324'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/simplicity-simplicity-simplicity.html' title='simplicity simplicity simplicity -- shouldn&apos;t that just be &apos;simplicity&apos;?'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3502767296309674163</id><published>2011-11-11T10:48:00.001-08:00</published><updated>2011-11-11T11:03:36.286-08:00</updated><title type='text'>not so angry birds</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Today, our UX guy posted a link to&amp;nbsp;&lt;a href="http://www.mauronewmedia.com/blog/2011/02/why-angry-birds-is-so-successful-a-cognitive-teardown-of-the-user-experience/"&gt;Why Angry Birds is so successful and popular: a cognitive teardown of the user experience&lt;/a&gt;. This is the bulk of my resposne.&lt;/span&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-61rkm2s6xjc/Tr1vEPVxS7I/AAAAAAAAADM/TJFuWF8UYio/s1600/2011.11.11.content_bird.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-61rkm2s6xjc/Tr1vEPVxS7I/AAAAAAAAADM/TJFuWF8UYio/s1600/2011.11.11.content_bird.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;Cool article, though I disagree with what it assumes makes Angry Birds so popular. &lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The author is remiss in pointing out the obvious: some big chunk of Angry Bird’s addictiveness is because the base activity is a fun thing: it is fun and pleasant to launch a slingshot at a building of blocks. &lt;br /&gt;  &lt;br /&gt;At [Alleyoop, my College Readiness webcompany], we aren’t based on a core activity that offers such a low learning curve / high satisfaction + feedback . I think at the best points of [our Math practice and quiz subcomponent], kids can get that extra Zing! of satisfaction of a problem mastered, but in most other ways it’s a reach for us. &lt;br /&gt;  &lt;br /&gt;So with the article, I agree with some bits (the importance of pleasant and detailed visual design, even the inclusion of extra details like the chattering birds) and disagree with others (iPad icon spacing provoking a sense of tantalizing mystery? Puhleeze) &lt;br /&gt;&lt;br /&gt;I thought margie's comment was more insightful to the charm of this particular game: (highlighting mine) &lt;/span&gt;&lt;blockquote class="tr_bq"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;AB is a game for non-gamers. Gameplay is simple, the&lt;b&gt; rewards are many and often&lt;/b&gt;, hence, continued play from all players. Any game that increases in difficulty and/or timing &amp;amp; speed too quickly I’ll drop out of […]. ~ AB is always the same: slingshot, birds, structures w/pigs.&lt;br /&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I think the fact that players are frequently rewarded (it’s&lt;b&gt; easy to pass a level, not so easy to 3 star a level&lt;/b&gt;) plays a huge part in why AB is so popular, especially with people who are not hardcore gamers. &lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Other commentators talk about “quick retrying ‘til I get it right” is a big aspect, maybe one we can learn from. Not punishing failure so much is a hallmark of modern gaming. &lt;br /&gt;&lt;br /&gt;It’s funny too, the opening paragraphs: &lt;/span&gt;&lt;blockquote class="tr_bq"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Surprisingly, it is a rare client indeed who asks the opposing question: why is an interface so engaging that users cannot stop interacting with it?&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The funny thing is, that’s not “engagement” so much as “low level addiction”. And frankly, popular games use some of the same pattern as drugs—an initial big rush (of success, in the case of games), a long haul of trying to recapture that high, and it being made harder to do so. &lt;br /&gt;  &lt;br /&gt;(It’s funny contrasting that with the addictiveness of say Farmville—there the addiction comes from a web of social obligations. The gameplay itself is decidedly NOT very fun in the way slingshots-at-buildings is, though it does carry a pleasant sense of “I Made This” construction. (I haven’t gotten into it either but I think Empires &amp;amp; Allies has those social and building aspects, along with an empowering “strong kid on the block” aspect in the fighting) &lt;br /&gt;&lt;br /&gt;So I think [our company] would be well served if we could capture some of this addictiveness: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;well balanced challenges with quick redo&amp;nbsp;&lt;/li&gt;&lt;li&gt;a carefully ramped increasing difficulty&amp;nbsp;&lt;/li&gt;&lt;li&gt;pleasant and juicy UI&amp;nbsp;&lt;/li&gt;&lt;li&gt;social obligations&amp;nbsp;&lt;/li&gt;&lt;li&gt;a sense of building&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;The single biggest thing that Angry Birds and Farmville have that we don’t are a real feeling and visual model of steady progress. (With Angry Birds getting through a series of levels, with the chance to go back and do better, with Farmville a nicely expanded and built up farm.) [Our former point system is] now a currency. Badges were nice, but were always more of a novelty than a core “gotta catch ‘em all!” experience&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;BONUS:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Some more thoughts that were a bit too specific about Angry Birds as a game to be relevant to my company:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I think the article missed out one of the best UI bits for the "try again" factor: you get a little dotted line showing you what your last trajectory was, thus enabling a higher degree of fine tuning. This little dotted line is more&amp;nbsp;&lt;/span&gt;significant&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;than a lot of the things the article discusses.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another thought I had: if I was designing Angry Birds, I might try to give it a split view: a zoomed-in view of the current bird (allowing more fine control of the trajectory at the launcher, and then a fun closeup view of the structure being destroyed, or possibly a pan back to the smug pigs if you totally miss) and then a view of the entire playfield, visible at all times.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The thing is, I'm not sure if this system (more complex in its display, but simpler in its control scheme than panning and zooming Angry Birds) would be more or less satisfying than the current scheme. But when thinking about what deliberate choices Rovio made (vs, say, the delays once the bird has hit the building, which I think owes more to giving time to the physics engine to work things out than a deliberate design decision) alternative solutions to the challenges they faced should be discussed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3502767296309674163?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3502767296309674163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/not-so-angry-birds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3502767296309674163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3502767296309674163'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/not-so-angry-birds.html' title='not so angry birds'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-61rkm2s6xjc/Tr1vEPVxS7I/AAAAAAAAADM/TJFuWF8UYio/s72-c/2011.11.11.content_bird.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2536112381784250929</id><published>2011-11-09T12:45:00.000-08:00</published><updated>2011-11-09T12:45:56.433-08:00</updated><title type='text'>jsonp for cross-site fun</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So, today's fun:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;We run a few different servers for testing: www is our live site, cert is for final testing, test is for preliminary testing, and we hack DNS a bit so that dev loops back to each developer's machine.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;We have a single WordPress install that we use for our blog, as well as to store the content for certain activities on the site. My most recent project was to add a simple tag system that would change a WP slug like&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', Courier, monospace; line-height: 17px;"&gt;[lookup value="user.profile.firstName"]&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="background-color: white; line-height: 17px;"&gt;into a rest call to /rest/user/profile and substitution with the fieldName parameter. (I also added conditional tags, something like&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: 'Courier New', Courier, monospace; line-height: 17px;"&gt;[start_if value="user.grade" is="GRADE10"]Welcome to Tenth[end_if]&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;would display "Welcome to Tenth" only if the endpoint said that was their grade.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So when you just have the one WP install there's an obvious small problem when you want to test before pushing live, that while WP (which I keep accidentally calling "WordPerfect" not "WordPress", a habit that is catching on at work) can do its own preview, it's not part of the whole dev/test/cert/www cycle. We added a "src=http://dev.alleyoop.com" type parameter, telling the plugin where to pull its javascript guts and then rest calls from, but... d'ohh... the rest calls were failing, losing out to the draconian cross site scripting rules.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The cool kids solution to this is JSONP, JSON-with-Padding. (The&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/JSONP"&gt;wikipedia page for it&lt;/a&gt;&amp;nbsp;is a decent introduction.) The server needs to be configured to recongize a jsonp request, and then it forms a response of the form "&amp;lt;script&amp;gt;yourcallback(THE DATA)&amp;lt;/script&amp;gt;"-- script tags aren't beholden to the usual xss rules. (Which is kind of a headscratcher, given that running code from another site seems to be a lot more dangerous than just grabbing data, but sometimes you have to take what you can get.)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So, in practice, I made a version of our wrapper for getting JSON that added a parameter&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;dataType: "jsonp"&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;to the jQuery.ajax call. We then ran smackdab into a kind of known Firefox issue (I'm not sure if us using a more up to date version of jQuery would have helped or not) where Firefox thinks that the JSON, what with its hashes and : and all, looks like it's trying to generate labels (what is this, BASIC?) and spits up "invalid label"... our fix for that was in the middle tier, a &lt;a href="http://stackoverflow.com/questions/2822609/invalid-label-firebug-error-with-jquery-getjson"&gt;known solution&lt;/a&gt;&amp;nbsp;is that wrapping the data in an additional set of parentheses fixes it, so that's what we did.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="line-height: 17px;"&gt;There's of course a bit of a security concern when you're allowing shenanigans like this-- especially if we were showing content from one user to another user. We'll look for some ways to tighten that up.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2536112381784250929?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2536112381784250929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/jsonp-for-cross-site-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2536112381784250929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2536112381784250929'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/jsonp-for-cross-site-fun.html' title='jsonp for cross-site fun'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-526591649294250753</id><published>2011-11-09T09:31:00.000-08:00</published><updated>2011-11-09T12:59:24.879-08:00</updated><title type='text'>mobile flash in the pan</title><content type='html'>So the news is making the rounds,&amp;nbsp;&lt;a href="http://www.zdnet.com/blog/perlow/exclusive-adobe-ceases-development-on-mobile-browser-flash-refocuses-efforts-on-html5-updated/19226"&gt;Adobe to stop doing mobile browser Flash&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For some Apple fans, this is a giant validation of Apple's view that Flash was the wrong technology for portable devices. (And as&amp;nbsp;&lt;a href="https://twitter.com/#!/McFunkypants/status/134306476381577216"&gt;some have tweeted&lt;/a&gt;&amp;nbsp;ActionScript might still be viable for making standalone apps.)&lt;br /&gt;&lt;br /&gt;At work, our designer's response was "Aple wins!" and our lean startup guru marketing guy responded "The Internet wins!". That, along with&amp;nbsp;&lt;a href="https://twitter.com/#!/gruber/status/134178711493808128"&gt;Gruber's tweet thinking 2015 would mark the end of Desktop Flash players&lt;/a&gt;&amp;nbsp;got me thinking...&lt;br /&gt;&lt;br /&gt;What's next?&lt;br /&gt;&lt;br /&gt;The most common opponent for Flash is usually described as "HTML5" which seems a little funny to me-- technically, HTML5 is about the semantics of markup, more of a topic for wonks than anyone else.&lt;br /&gt;&lt;br /&gt;In practice, then It feels like there are two fronts for "not Flash", both powered by javascript. One is, and this is what I'm making my living with now, is what used to be called "DHTML"-- pages full of divs and graphics and one not, providing a faster and more interactive experience than the static pages of yore.&lt;br /&gt;&lt;br /&gt;The other is stuff that makes heavy use of the "canvas" object. A lot of my gaming buddies are way into this as a technology. It's pretty cool, but there are two giant challenges for it to overcome to take the place of Flash: one is support for sound is still kind of iffy, you really have to dig if you want something that is very cross-browser and can provide "real time", synchronized sound effects. The other is support in IE (version 8 and earlier) tends to be lacking. (There are &lt;a href="http://raphaeljs.com/"&gt;some libraries&lt;/a&gt; that use shims that do a good job of faking canvas support.)&lt;br /&gt;&lt;br /&gt;I'm not sure what this means for me... Flash was on my "I should learn this" list, and now it's a little lower down. &amp;nbsp;(I took one 2 day intro class and it was frustrating because the class was geared at designers, and focused on the timeline, which STILL confuses me, as opposed to ActionScript, which felt very&amp;nbsp;familiar&amp;nbsp;when I helped a friend recode a few things.)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;(UPDATE: Gruber also pointed to this&amp;nbsp;&lt;a href="http://news.cnet.com/8301-30685_3-57321494-264/flash-crippled-but-alive...for-now/"&gt;CNET article&lt;/a&gt;&amp;nbsp;that points out somethings Flash still does better than its alternatives...)&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-526591649294250753?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/526591649294250753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/mobile-flash-in-pan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/526591649294250753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/526591649294250753'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/mobile-flash-in-pan.html' title='mobile flash in the pan'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2843825742390430900</id><published>2011-11-08T10:26:00.000-08:00</published><updated>2011-11-08T10:26:46.321-08:00</updated><title type='text'>scope-a-dope</title><content type='html'>This is one of those posts that I'm a little nervous about writing, because I worry I might look a bit bad, since it represents a small bit of "trial and error" coding along with a slightly iffy theoretical understanding of the problem. Still, in the interest of being useful to my future self and maybe showing other people they're in the same boat, I'll put the process here.&lt;br /&gt;&lt;br /&gt;I was trying to do a bit of caching of some data&amp;nbsp;asynchronously.I had "neededEndpoints" that was a hash of the endpoints I needed to hit and store the data for in another hash, call it cache&lt;br /&gt;&lt;br /&gt;So here was my first attempt: (it didn't look so blatantly wrong when I coded it, I've stripped out stuff in the name of simplicity)&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;for(var endpoint in neededEndpoints){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;jsonGet("/rest/"+endpoint, function(res){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;cache[endpoint] = res;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The trouble with this code is that javascript is not block scoped like some other C-like languages, and so "endpoint" is effectively passed by reference, not by value, and the last value of "endpoint" was used for all the cache storing.&lt;br /&gt;&lt;br /&gt;I remembered in previous work we'd done here, we had a CreateDelegate function:&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;function CreateDelegate(scope, fn) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; return function () {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(fn != undefined){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;fn.apply(scope, arguments);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; };&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Usually we'd call it with "this" as the argument for scope, but I wasn't getting the results I expected. Googling I found&amp;nbsp;&lt;a href="http://blogs.lotterypost.com/speednet/2008/1/aspnet-ajax-half-way-between-createdelegate.htm"&gt;this page&lt;/a&gt;&amp;nbsp;that gave me the nudge I needed to come up with this:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;for(var endpoint in this.neededEndpoints){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;jsonGet("/rest/"+endpoint,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CreateDelegate({"ep":endpoint}, function(res){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;cache[this.ep] = res;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;})&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt; &amp;nbsp;);&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;So what's going on? The mental model I've come up with says CreateDelegate is in effect making a snapshot of the current state of things-- that's what a delegate is, in effect. It's actually the act of instantiation of CreateDelegate that makes the snapshot, and then the code inside it can have exactly the context we give it.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2843825742390430900?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2843825742390430900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/scope-dope.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2843825742390430900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2843825742390430900'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/scope-dope.html' title='scope-a-dope'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2743421200227371647</id><published>2011-11-08T08:17:00.000-08:00</published><updated>2011-11-08T08:24:12.858-08:00</updated><title type='text'>thoughts on keeping the global namespace clean</title><content type='html'>So one well known issue with javascript is that it's a bit too easy to pollute the global namespace.&lt;br /&gt;&lt;br /&gt;Personally I find this is a big issue more in theory than in practice, choose reasonably distinct function and variable names, and you hardly ever have a problem.&lt;br /&gt;&lt;br /&gt;Half the problem is that if you just start using a variable without a "var" declaration, it gets slapped into the global namespace. Douglas Crockford, among others, considers it a bit of misstep in the design of the language.&lt;br /&gt;&lt;br /&gt;(The other half of the problem is the same "bootstrapping" problem any language faces: how do you tell the system where code execution starts, and where is the tree of object and functions rooted ? C and Java have their main(); in Javascript, you can start putting function declerations and even calls anywhere, in practice there's a lot of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$(document).ready(function(){});&lt;/span&gt; )&lt;br /&gt;&lt;br /&gt;So, you can go a little crazy with loaders and tools to control your namespace and keep your private variables and functions private etc, and also with CreateDelegate() functions to pass thing to page elements and whatnot. This is overkill for most projects where you're more interested in the functioning of the site than making a reusable toolkit. (YMMV). A good compromise is "make one global variable per functional grouping". For example, today I was working on a "madlibs" controller (for eventual integration as a WordPress plugin) Part of the code for that was:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;var ao_madlibs = new function(){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; this.neededEndpoints = {};&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; this.doMadLibs = function(){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//CODE GOES HERE&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; } //end doMadLibs&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;}//end ao_madlibs&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;In practice I find this a good balance of control and ease of reading. One caveat, in the doMadLibs code I used jQuery's .each() function, and in the anonymous function in there, "this" had a different meaning, so I had to use the global reference ao_madlibs.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I was looking at a bit of coworkers' code... he's more of an architect, and cribbed this from FB's api code:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;if (!window.AO) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; window.AO = {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;processElements : function(){&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //do something&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; someVariable: {}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp;};&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;This code is using more of the associative array syntax, plus doing that check to make sure it's only called once. I find it's a little more "foreign" looking to me, but makes a good amount of sense if you're used to JS's variable syntax. Pick your poison I guess! Sometimes I do miss Java's class structure syntax...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The nice thing about using a global variable, to, is that you can really easily and concisely refer to your "functional grouping" in page elements and in other parts of your system, again without worrying about ever-changing meaning of "this" and using tons of oddball CreateDelegate functions... I find KISS (Keep it Simple Stupid) to be an important principle in making code I can read in the future, and in communicating my intent to other people looking at my code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2743421200227371647?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2743421200227371647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/thoughts-on-keeping-global-namespace.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2743421200227371647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2743421200227371647'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/thoughts-on-keeping-global-namespace.html' title='thoughts on keeping the global namespace clean'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5733289221869890880</id><published>2011-11-07T07:57:00.001-08:00</published><updated>2011-11-07T07:58:44.892-08:00</updated><title type='text'>quick hit: a link o' snippets</title><content type='html'>&lt;a href="http://www.catswhocode.com/blog/10-jquery-snippets-for-efficient-developers"&gt;http://www.catswhocode.com/blog/10-jquery-snippets-for-efficient-developers&lt;/a&gt;&amp;nbsp;has some decent little snippets, I liked the age verification one in particular, and the one for seeing if an image had loaded was good as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5733289221869890880?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5733289221869890880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/quick-hit-link-o-snippets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5733289221869890880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5733289221869890880'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/quick-hit-link-o-snippets.html' title='quick hit: a link o&apos; snippets'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-2115067290872714301</id><published>2011-11-04T10:20:00.000-07:00</published><updated>2011-11-04T10:20:55.618-07:00</updated><title type='text'>metablogger</title><content type='html'>So yesterday was the first day I tried making an embedded interactive bit... it wasn't as bad as I had feared (I've used other blogging software that has the WYSIWYG mode kind of running roughshod over the code you're trying to include), weirdly the one gotcha was that none of the parts seemed clickable... firedebug showed a "clickTrap" div around where I was expecting the action to be. &amp;nbsp;&lt;a href="http://dorianredesignstheworld.blogspot.com/2010/06/getting-bloggers-clicktrap-out-of-way.html"&gt;Doria's Design Notes had the fix&lt;/a&gt;, however, you need to put this as some CSS in the entry&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;style&amp;gt;div.blogger-clickTrap {display: none;}&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;br /&gt;Not sure what that's all about but the fix seems fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-2115067290872714301?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/2115067290872714301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/metablogger.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2115067290872714301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/2115067290872714301'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/metablogger.html' title='metablogger'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-3353264212178862764</id><published>2011-11-03T06:45:00.000-07:00</published><updated>2011-11-03T08:44:42.976-07:00</updated><title type='text'>a more pleasing easing</title><content type='html'>The other day I mentioned my admiration for making the jQuery animation default "swing". Today I'll talk about some of the other options provided by the &lt;a href="http://gsgd.co.uk/sandbox/jquery/easing/"&gt;jQuery Easing plugin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Used judiciously, animations can make transitions to the state of the page less abrupt. Fiddling with easings gives you more options to add a "physicality" to the objects in question. Together, animation and easings can add a pleasant physicality (or bit of "juiciness" as I've got people saying at work.) to otherwise boring pages. (There's a reason why these kinds of animations and a sense of physicality is deeply baked into iOS...)&lt;br /&gt;&lt;br /&gt;Actually, that page itself does a good job of showing usage... but I'm not crazy about the widget they give you to try out the various easings provided-- on that page, "The Clicker" always shows you 2 animations back to back (one for increasing the boxes size and one for putting it back) and so it's difficult to get a feel for each selection in isolation. Also, I think moving objects is a more common form of animation, and in general I prefer not to have to fiddle with select boxes. So I present: The Mover/Grower(tm). Like "The Clicker" it builds the list of easings by querying the module itself... you can set the speed, decide which (or both) of the things you want to animate, and then click to see any easing. (Click in rapid succession to combine.)&lt;br /&gt;&lt;br /&gt;&lt;script src="http://kirkjerk.com/m/files/jquery.1.6.4.min.js"&gt;&lt;/script&gt;&lt;script src="http://kirkjerk.com/m/files/jquery.easing.1.3.js"&gt;&lt;/script&gt;&lt;script&gt;var easingExample = new function(){this.isRight = false;this.isBig = false;this.init = function(){ this.mover = $("#easing_example div"); this.grower = $("#easing_example_grower");var linkarea = $("#easing_example_links");for (x in jQuery.easing) {  if (x != 'linear' &amp;&amp; x != 'swing' &amp;&amp; x != 'def')   linkarea.append('&lt;a href="#" onClick="easingExample.go(\''+x+'\');return false;"&gt;'+x+'&lt;/a&gt;'+' '); }}this.go = function(easing){var speed = Math.round($("#easing_example_speed").val());var task = $('input[name=easing_example_type]:radio:checked').val();if(task == 'both' || task == 'move'){var target = "360px";if(this.isRight){target = "0px";} this.mover.animate({"left":target},speed,easing);this.isRight = !this.isRight;}//end moverif(task == 'both' || task == 'grow'){var target = "400px";if(this.isBig){target = "100px";} this.grower.animate({"width":target},speed,easing);this.isBig= !this.isBig;}//end grow}//end this.go}$(document).ready(function(){easingExample.init();});&lt;/script&gt;&lt;style&gt;div.blogger-clickTrap {display: none;}#easing_example{border:black 1px dotted;width:400px;height:40px;position:relative;}#easing_example div {background-color:#3333cc;position:absolute;width:40px;height:40px;left:0px;}#easing_example_grower{height:40px;width:100px;background-color:#33cc33;}&lt;/style&gt;&lt;b&gt;Mover:&lt;/b&gt;&lt;br /&gt;&lt;div id="easing_example"&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;b&gt;Grower:&lt;/b&gt;&lt;br /&gt;&lt;div id="easing_example_grower"&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Speed:&lt;/b&gt;&lt;input id="easing_example_speed" size="4" value="800" /&gt;ms&lt;br /&gt;&lt;b&gt;Demonstrate:&lt;/b&gt;&lt;input name="easing_example_type" type="radio" value="move" /&gt;move&lt;input name="easing_example_type" type="radio" value="grow" /&gt;grow&lt;input checked="checked" name="easing_example_type" type="radio" value="both" /&gt;both&lt;br /&gt;&lt;b&gt;jQuery Builtins:&lt;/b&gt;&lt;a href="http://www.blogger.com/blogger.g?blogID=8729407087018325447#"&gt;linear&lt;/a&gt;&lt;a href="http://www.blogger.com/blogger.g?blogID=8729407087018325447#"&gt;swing&lt;/a&gt;&lt;br /&gt;&lt;b&gt;From easing extension:&lt;/b&gt;&lt;br /&gt;&lt;div id="easing_example_links"&gt;&lt;/div&gt;&lt;br /&gt;In terms of which of these to use, if you're in a hurry...our first use case for this was an object flying from off the screen-- "easeOutBounce" had the nicest feel to the landing.&amp;nbsp; Some of the "In" animations feel a little corny when they start, like a Hannah-Barbara cartoon character getting its feet under it before starting to run, but "easeInOutElastic" is subdued and pleasant.&lt;br /&gt;&lt;br /&gt;Some other caveats are that animations can feel choppy if there are too many at once, or if the page is still kind of loading, or if there's a json-ish query or what have you, so want to be careful and minimize other things going on on the page when the thing loads (for example, a second delay before a message notifiation flies in, or launching a JSON request on animation completion, rather than at the same time as the animation started.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-3353264212178862764?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/3353264212178862764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/11/more-pleasing-easing.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3353264212178862764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/3353264212178862764'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/11/more-pleasing-easing.html' title='a more pleasing easing'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-918737259835813600</id><published>2011-10-31T12:11:00.000-07:00</published><updated>2011-10-31T12:18:18.235-07:00</updated><title type='text'>color animation</title><content type='html'>&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;As a developer quickly learns, jQuery offers a nice toolkit to fiddle with CSS on the fly. In particular, you can use animate() to trivially make rough transitions smooth:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(".something").animate({"property-name":numericvalue);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The default easing (how it changes from the first state to the next) is called "swing", and gives a nice effect that implies the object has a bit of momentum. (It's a subtle touch of designer-influenced genius that they made the default "swing" rather than the nerdy, more-engineer-friendly linear...) More on easings later...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One seeming gap is that out of the box you can't use the animate() function on colors... &amp;nbsp;but now, "there's a plugin for that",&amp;nbsp;&lt;a href="http://www.bitstorm.org/jquery/color-animation/"&gt;Bitstorm.org's jQuery Color Animation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Put a reference to it atop your file:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script src="/path/to/jquery.animate-colors.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;and then you're free to do something like&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(".userProfileHolder .yoopTab.messages").animate({"background-color":"#ffffff"});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A few small caveats:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;with the version I'm using, you need to use r/g/b hex values, not the human readable colors like "white"&lt;/li&gt;&lt;li&gt;you need to make sure the object your modifying has a base color set (preferably in hex colors too.)&lt;/li&gt;&lt;li&gt;if you're changing, say, the background-color property, you may be implicitly setting the background color (or rather semi-explicitly leaving out the background color property) with the "background" shortcut property, which might cause problems. In today's case we were using a "background" property to show a transparent PNG, and then letting the parent's bckground color shine through. I broke up the "background" shortcut property into its individual parts and THEN set the background-color explicitly.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;That's it though-- it's might handy and makes for some nice looking transitions than just toggling from one color to another&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-918737259835813600?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/918737259835813600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/color-animation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/918737259835813600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/918737259835813600'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/color-animation.html' title='color animation'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7065449867242824045</id><published>2011-10-24T11:29:00.000-07:00</published><updated>2011-10-24T11:29:57.317-07:00</updated><title type='text'>FancyBox: prettier dialogs</title><content type='html'>&lt;br /&gt;So, one easy way of getting pretty (prettier than jqModal, anyway) modal dialog boxes is FancyBox. I've seen its distinctive "phillip's head" close button all over the place, so I'm guessing it's pretty popular.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-wN6GQ38KLEw/TqWujj0EWuI/AAAAAAAAAC4/EXvEtz_C8Po/s1600/fancybox.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-wN6GQ38KLEw/TqWujj0EWuI/AAAAAAAAAC4/EXvEtz_C8Po/s1600/fancybox.png" /&gt;&lt;/a&gt;&lt;/div&gt;Like jqModal, you put the content somewhere on your page, and then there are 2 functions, one for telling the library what should be in a dialog, and another for launching it.&lt;br /&gt;&lt;br /&gt;FancyBox's boilerplate is similar to jqModal, with 2 exceptions:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You call the "make this a dialog" on the link that refers to the div, not the div itself. I thought this was a bit counter-intuitive.&lt;/li&gt;&lt;li&gt;If you use jqModal's jqmWindow class it default would tend to hide the content before it's ready, but with fancybox we tend to put the dialogs inside a div which is then hidden.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Here's the code:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;meta charset="utf-8"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;title&amp;gt;Page Title&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;link rel="stylesheet" type="text/css" href="fancybox/jquery.fancybox-1.3.4.css" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script src="jquery-1.4.3.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script src="fancybox/jquery.fancybox-1.3.4.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;$(document).ready(function() {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; $("#fancyLaunch").fancybox();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;a href="#fancyDialog" id="fancyLaunch"&amp;gt;Show Dialog&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;div style="display:none;"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;lt;div class="jqmWindow" id="fancyDialog"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; HELLO AGAIN&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So pretty much the same.&lt;br /&gt;&lt;br /&gt;Disclaimer, I did establish that it is FancyBox (probably it's modal screen) that is interfering with other animations we have on the page, that FancyBox interferes in a way jqModal doesn't. But for simple tasks, FancyBox has the edge because it's less work to make it pretty.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7065449867242824045?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7065449867242824045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/prettier-dialogs-fancybox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7065449867242824045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7065449867242824045'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/prettier-dialogs-fancybox.html' title='FancyBox: prettier dialogs'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-wN6GQ38KLEw/TqWujj0EWuI/AAAAAAAAAC4/EXvEtz_C8Po/s72-c/fancybox.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-324296677678494465</id><published>2011-10-24T08:14:00.000-07:00</published><updated>2011-10-24T08:14:26.618-07:00</updated><title type='text'>jqModal: flexible dialogs</title><content type='html'>A common task is putting up a "modal dialog", a box that appears over the rest of the website.&lt;br /&gt;&lt;br /&gt;We've been having some trouble at work that might be related to the modal kit fancybox. (More on that later.) Meanwhile I've started investigating jqModal&amp;nbsp;&lt;a href="http://dev.iceburg.net/jquery/jqModal/"&gt;jqModal, "Minimalistic Modaling with jQuery"&lt;/a&gt;. Besides a possible timing issue we're seeing with fancybox, I appreciate how jqModal really strips things down to the basics, while still providing some sensible look and feel defaults. Here's the example boilerplate I came up with, just grabbing the js and the css from that link:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;meta charset="utf-8"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;title&amp;gt;Page Title&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;link rel="stylesheet" type="text/css" href="jqModal.css" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script src="jquery.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script src="jqModal.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$(document).ready(function() {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; $("#dialog").jqm();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;input type="button" onClick='$("#dialog").jqmShow()' value="show"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;div class="jqmWindow" id="dialog"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;a style="float:right;" class="jqmClose"&amp;gt;X&amp;lt;/a&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; HELLO AGAIN&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;The trick is putting the content in the div, and then blessing it with ".jqm()". Although there is a facility for turning any link into a dialog launcher, I like that the emphasis is on the programmatic launch, just calling .jqmShow() on that dialog. I did use the link-blessing pattern for the close, however.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Easy, and flexible.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-324296677678494465?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/324296677678494465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/jqmodal-flexible-dialogs.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/324296677678494465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/324296677678494465'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/jqmodal-flexible-dialogs.html' title='jqModal: flexible dialogs'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-1368520900101074321</id><published>2011-10-24T07:20:00.000-07:00</published><updated>2011-10-24T07:20:51.125-07:00</updated><title type='text'>easy rounded corners</title><content type='html'>So, probably old news to most developers here...&lt;br /&gt;&lt;br /&gt;IE should be ashamed at not supporting any standards for CSS rounded corners up 'til the very recent IE9. &amp;nbsp;Rounded corners looks better, designers are always asking for it, and faking 'em is generally a pain in the ass, involving polluting simple design with&amp;nbsp;gratuitous&amp;nbsp;graphics and/or ungainly structure.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-mxUKeAf0yiQ/TqVyTt2DkpI/AAAAAAAAACo/h3xkeJUxKiY/s1600/corners.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-mxUKeAf0yiQ/TqVyTt2DkpI/AAAAAAAAACo/h3xkeJUxKiY/s1600/corners.png" /&gt;&lt;/a&gt;&lt;/div&gt;The easiest solution to this is the&amp;nbsp;&lt;a href="http://jquery.malsup.com/corner/"&gt;jQuery Corner Plugin&lt;/a&gt;. In its simplest form you include the library:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script src="/path/to/jquery.corner.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;div&gt;and then something like this when the page loads:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;document.ready(function(){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; $(".selector_for_class").corner();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;});&lt;/span&gt;&lt;br /&gt;Unfortunately, you might get a small flash of square corners 'til the document ready kicks in, unless of course you're hiding items with a loading type screen.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The defaults for rounded-ness are well chosen, but if you want many more options you can check out&amp;nbsp;&lt;a href="http://jquery.malsup.com/corner/"&gt;the demo page&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The library uses native rounded corners where&amp;nbsp;available&amp;nbsp;(there were a few different standards, alas) and graphics for earlier versions of IE. In practice you sometimes get into trouble on older IE if the div is over a complex background.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Still, easy-peasy, and 9 times out of 10 it looks just great.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-1368520900101074321?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/1368520900101074321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/easy-rounded-corners.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1368520900101074321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/1368520900101074321'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/easy-rounded-corners.html' title='easy rounded corners'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-mxUKeAf0yiQ/TqVyTt2DkpI/AAAAAAAAACo/h3xkeJUxKiY/s72-c/corners.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-7824731640670341516</id><published>2011-10-19T10:52:00.000-07:00</published><updated>2011-10-26T07:41:30.072-07:00</updated><title type='text'>skeuomorphtastic</title><content type='html'>Skeuomorphic design is a difficult to spell buzzword for an easy to understand concept: in the UI world, it's making virtual things look like their real world counterparts. Sometimes it's just window trimming, sometimes it's the core of the interface.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://chausse.org/2011/02/skeuomorphism2/"&gt;Here's a brief rundown&lt;/a&gt;&amp;nbsp;on the thing. Apple has been a big proponent of this flavor of design, to&amp;nbsp;&lt;a href="http://gizmodo.com/5849940/ugh-god-why-apple-is-making-everything-look-like-an-ugly-wild-west?tag=apple"&gt;some people's rant-tastic dismay&lt;/a&gt;. I agree that the leather-ette look is pushing things a bit, but I'd like to hear Apple's side of it. I assume the hoi polloi must dig it, even as the fanboy elite sniff.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-hDrauP0tmwQ/Tp8Ng8HR28I/AAAAAAAAACg/in-Ho43TSQ8/s1600/2011.10.17.i_heart_skeumorphism.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-hDrauP0tmwQ/Tp8Ng8HR28I/AAAAAAAAACg/in-Ho43TSQ8/s320/2011.10.17.i_heart_skeumorphism.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;an image making the rounds&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;If you don't go crazy with it, by and large it's an aesthetic decision. (In some cases it can help instruct a user in the use of an unfamiliar interface, but other times you're stuck with the limitations of whatever the physical device is. So from a usability point of view, it's probably a wash.) Personally I prefer the opposite approach as championed by Microsoft and their sense of&amp;nbsp;&lt;a href="http://www.riagenic.com/archives/487"&gt;Authentically Digital&lt;/a&gt;, shunning most of the chrome and gratuitous shading of many other design paradigms.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;UPDATE:&amp;nbsp;&lt;a href="http://madebymany.com/blog/apples-aesthetic-dichotomy"&gt;James Higgs rips into Apple for the use of this style&lt;/a&gt;, calling it infantile&amp;nbsp;kitsch... I like any discussion of interface that can invoke the author Milan Kundera...&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-7824731640670341516?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/7824731640670341516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/skeuomorphtastic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7824731640670341516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/7824731640670341516'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/skeuomorphtastic.html' title='skeuomorphtastic'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-hDrauP0tmwQ/Tp8Ng8HR28I/AAAAAAAAACg/in-Ho43TSQ8/s72-c/2011.10.17.i_heart_skeumorphism.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-4914016712502452856</id><published>2011-10-18T07:14:00.000-07:00</published><updated>2011-10-18T07:14:12.803-07:00</updated><title type='text'>css selector 101</title><content type='html'>So, around a year and a half ago I started my new role as "UI Engineer" at Pearson, for the then unnamed College Readiness startup they were incubating, now known as&amp;nbsp;&lt;a href="http://alleyoop.com/"&gt;Alleyoop&lt;/a&gt;. &amp;nbsp;I had a lot to learn when I started out... while I had always thought the work I did on&amp;nbsp;&lt;a href="http://kisrael.com/"&gt;my&lt;/a&gt;&amp;nbsp;&lt;a href="http://loveblender.com/"&gt;own&lt;/a&gt;&amp;nbsp;&lt;a href="http://alienbill.com/"&gt;websites&lt;/a&gt;&amp;nbsp;gave me an edge as an engineer (I was used to doing sites front to back, including the frontends) I was kind of self-taught with a lot of the UI stuff, and a lot of best practices from the late-90s got stuck in my brain. (I know when I'm dealing with some old HTML of mine because I tend the tags in all caps: &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;TABLE&amp;gt;&amp;lt;TR&amp;gt;&amp;lt;TD&amp;gt;like this&amp;lt;/TD&amp;gt;&amp;lt;/TR&amp;gt;&amp;lt;/TABLE&amp;gt;.&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;Actually, in my heart of hearts I don't think it's a bad practice, it really makes it easy to see what's markup and what's content, but now it's so idiosyncratic, not to mention against all the "xhtml" standards, that even though it works and makes sense I don't do it.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I was fortunate that some of the first alleyoop projects involved working on existing prototypes that made pretty decent use of jQuery and heavy use of CSS. (I had used CSS before, but generally just to replace bad old &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;FONT&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; tags and what have you.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I had even done some fancy (for the time) work in in javascript, like this&amp;nbsp;&lt;a href="http://alienbill.com/2600/playerpalnext.html"&gt;online editor for Atari 2600 sprites&lt;/a&gt;. It made heavy use of&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;document.getElementById()&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;rather than the sophisticated selectors that would be available later.) We had outsourced this work to some experienced people, and I was able to learn from it, even as I took advantage of my engineering history to improve on the javascript.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Anyway, recently I was helping one of the content people here manage a CSS template in Wordpress, and it made me realize I could put some learnings here, just in case I don't use CSS and jQuery for a while and forget, or in this blog's mission as a possible instructional guide. (This blog entry is probably jack of all trades, master of none, not low level enough to be good for beginners, way too simple to be useful to a veteran, and not comprehensive enough to be a reference! Ah well.)&lt;br /&gt;&lt;br /&gt;So:&lt;br /&gt;HTML elements will generally be identified for purposes of CSS styling by:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;the kind of element they are- often a CSS stylesheet will apply a look to all elements of a type&amp;nbsp;&lt;/li&gt;&lt;li&gt;a style slapped on to the element itself, e.g&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;style="property:val;"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;the class you assign directly to them with &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;class="someclass"&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;(and while any element should only have one class tag, an element can have multiple classes, e.g.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;class="someclass someotherclass"&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;a style applied to an element with a certain id ala&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;id="my_unique_id"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;A combination of 3 and 1 where it's elements of a certain class name, but only elements of a certain type.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;A combination of 1 and 3, like where an element gets a style when it's inside another element of a certain class (for example all the divs i&lt;/span&gt;nside a class'd containing div.)&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;So for each of these, you have a different way of selecting them in the style sheet:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To review, in a stylesheet (or block of CSS style) the format is:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;selector {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; someproperty:someval;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; some-pixel-property:10px;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So what's the selector for each of these cases?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;For all elements of a type, it's just the tag name, e.g &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;div&lt;/span&gt;&lt;/li&gt;&lt;li&gt;If you're doing inline styles, you don't need to worry about the selector!&lt;/li&gt;&lt;li&gt;For class name, it's "." plus the name of the class, e.g. .someclass&lt;/li&gt;&lt;li&gt;For an id, it's "#" plus the id of thelement, e.g. #my_unique_id&lt;/li&gt;&lt;li&gt;For elements of a certain class AND of a certain type, you write the element type and then the classname, WITHOUT a space: e.g. div.someclass&lt;/li&gt;&lt;li&gt;For elements of a certain type WITHIN an element of a certain class, you use spaces: e.g. .someWrapperClass div&lt;/li&gt;&lt;li&gt;Finally, you can use commas when you want a block of style info to apply to different selectors, e.g.&lt;br /&gt;&lt;i&gt;elemselector1,elemselector2,.classname{&lt;br /&gt;&amp;nbsp; property:val;&lt;br /&gt;}&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;There is an art and balancing act to choosing the right type of selectors. In my early days, I noticed how classnames could be very similar to keys in the Hash Maps I used in programming languages like Perl and Java, so I tended to use a lot of unique classnames. Also, I wasn't yet comfortable with selector type 6, there, and could barely understand the code I was looking at. (On the other hand, it is very possible to get over specific with your selector hierarchies there! If you're too specific about that stuff, than you can't reuse the styling because it only works when embedded in that particular setting)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another rule of thumb is, if there are competing selector patterns, the more specific one tends to win, a style added via id is more specific than something applied to a whole class is more specific than something at the element level, so the "id" would win if there are conflicting CSS properties from different selector. (Of course &amp;nbsp;if it's different CSS properties, they will be all applied, rather than having to fight it out.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also,&amp;nbsp;I think people go a little nuts in avoiding inline styles; it violates the holy grail of "all beautification goes in the CSS file" but frankly trying to get a pure-content HTML page is a pipedream; and hell, that's what we have Content Management Systems for.) So if I need to nudge something a bit, and it's a style that is totally not reuasable, I might go ahead and style it inline. Sometimes it just makes more sense than making up an arbitrary key.&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;And that is how I cope with CSS selectors... I love, love, love that jQuery uses the same selector pattern. It makes like so much easier.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Also, as a "well duh" bit of advice to newbies: you probably NEED to have firebug on your system NOW if it's not there already. (It's also built into chrome, but I find Firebug a bit more deft) Being able to right click on an item and "Inspect Element" is a HUGE benefit, especially how it shows you what file the properties came from, as well as what other properties got ignored when there's one of those aforementioned conflicts. (The overridden property is indicated with a &lt;strike&gt;strikeout&lt;/strike&gt;.)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-4914016712502452856?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/4914016712502452856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/css-selector-101.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4914016712502452856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/4914016712502452856'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/css-selector-101.html' title='css selector 101'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-8298210169412796718</id><published>2011-10-17T08:08:00.000-07:00</published><updated>2011-10-17T09:24:17.709-07:00</updated><title type='text'>easy sortable tables</title><content type='html'>This weekend I did a great quick project with a nifty new (to me) jQuery tool -- I found my final creation immediately useful, see the final paragraph)&lt;br /&gt;&lt;br /&gt;The backstory: There's a videogame I enjoy destressing with called "Earth Defense Force: Insect Armageddon" (nothing more relaxing that using guns and rockets to save the earth from endless hoardes of giant insects and robots.)&lt;br /&gt;&lt;br /&gt;The game has a plethora of weapons, and while the game reveals some hard data of damage dealt and reload times and what not, it's not always easy to figure out what the most effective weapons are... enter&amp;nbsp;&lt;a href="http://www.gamefaqs.com/xbox360/606328-earth-defense-force-insect-armageddon/faqs/62919"&gt;twxabfn's EDF:IA Weapon FAQ&lt;/a&gt;&amp;nbsp;. It features a massive table with all 372 weapons listed. The trouble is... it's a massive table and a typical user is probably only interested in the weapons for the soldier type they're playing, and even then probably wanting to focus on weapon type or tier. (In short, they're probably looking for "what are the most powerful weapons for my character right now")&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-o0qHMujbZvU/Tpw_qJI5BWI/AAAAAAAAACY/kYGQ_KA7HVg/s1600/tablesort.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-o0qHMujbZvU/Tpw_qJI5BWI/AAAAAAAAACY/kYGQ_KA7HVg/s1600/tablesort.png" /&gt;&lt;/a&gt;&lt;/div&gt;So, I decided to make a more manageable UI to that big flat table. I found Christian Bach's &amp;nbsp;&lt;a href="http://tablesorter.com/docs/"&gt;excellent jQuery tool tablesorter&lt;/a&gt;. With about one line of code, it makes a regular table sortable... it's smart about sorting numeric values by number (and not alphabetically) and you can even sort multiple columns.&lt;br /&gt;&lt;br /&gt;The line of code in quetion is:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$("#myTable").tablesorter();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Put that in your document ready after including the js file like this:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;script src="/path/to/jquery.tablesorter.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;/span&gt;&lt;br /&gt;&amp;nbsp;and you're good to go, more or less... (optionally you can tell it which columns to sort on to begin with)&lt;br /&gt;&lt;br /&gt;A couple caveats: one is you need to use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;th&amp;gt;&lt;/span&gt; tags if you aren't already, and include &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;thead&amp;gt;&lt;/span&gt; (to wrap the header row) and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;tbody&amp;gt;&lt;/span&gt; (for the other rows) tags inside the table, something lazy or old school folks might not always do. The other thing to note is you won't get the nice up and down sort arrows or pretty formatting unless you also include one of the themes (two skinds are downloadable from the bottom of the page) e.g.:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;lt;link rel="stylesheet" href="&lt;a href="http://kirkjerk.com/vgames/edf/style.css"&gt;style.css&lt;/a&gt;" type="text/css" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;After adding sortable columns, I built some simple filters -- I added classes to each table row indicating what armor, type, and tier it was, put in select boxes with the available options, then wired it together with Javascript to call&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; $(".rowclass").hide();&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; on all the rows that weren't included with the current filter settings. I played with the idea of making a more complex UI with multiple selects or checkboxes (useful if you wanted to, say, compare Rocket Launchers vs Missile Launchers, or this tier's weapons to the next) but thought that for now the extra power wasn't worth UX complexity.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I also made a little readout of how many weapons were being displayed out of all available.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can&amp;nbsp;&lt;a href="http://kirkjerk.com/vgames/edf/"&gt;play with the finished product&lt;/a&gt;&amp;nbsp;and view source for coding details of the filters and line counts.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So in terms of being useful... yesterday I was able to run the numbers to see that the&amp;nbsp;&lt;span class="Apple-style-span" style="background-color: white; color: #3d3d3d;"&gt;SV Diablero mk2 was CLEARLY the best bet for close-in fighting for Level 5 Tactical Armor soldier, over any other shotgun or assault rifle, and that the&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #3d3d3d;"&gt;Long Wattkins mur Missile Launcher I was messing around with was a complete waste of time... like, I said, USEFUL! (For certain flavors of use.)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-8298210169412796718?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/8298210169412796718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/this-weekend-i-did-great-quick-project.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/8298210169412796718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/8298210169412796718'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/this-weekend-i-did-great-quick-project.html' title='easy sortable tables'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-o0qHMujbZvU/Tpw_qJI5BWI/AAAAAAAAACY/kYGQ_KA7HVg/s72-c/tablesort.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-8647924181650577841</id><published>2011-10-16T06:35:00.000-07:00</published><updated>2011-10-17T08:20:49.334-07:00</updated><title type='text'>boilerplate</title><content type='html'>I have a homebrew online database (in practice each db looks like a spreadsheet page, and then it autobuilds a form to let me edit and add entries. All backed by my old friends Perl CGI and flat files...) One of my databases is "jquery", and that's the one I'm hoping to convert an entry at a time to this blog.&lt;br /&gt;&lt;br /&gt;Enough jawing, lets get to the meat of the thing!&lt;br /&gt;&lt;br /&gt;One of the things I like about jQuery is that it's low overhead, you don't have to type too much to get things going. (My memory is verb-based rather than noun, good at remembering how things interact rather than exact syntaxes, so I appreciate easy-to-remember things like that.) Still, I find it handy to have the "boilerplate", the barebones code ready to go for a new HTML page that uses it.:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!doctype html&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta charset="utf-8"&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Page Title&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;link rel="stylesheet" type="text/css" href="style.css" /&amp;gt;&lt;br /&gt; &amp;lt;script src="&lt;a href="http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js%22%3E%3C/script%3E"&gt;http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/a&gt;&lt;br /&gt; &amp;lt;script&amp;gt;&lt;br /&gt; $(document).ready(function() {&lt;br /&gt;     alert('Hello world!');&lt;br /&gt; });&lt;br /&gt; &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;Content Goes Here&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;i&gt;Thanks for the Improvements Ossian!&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;That's a good start! There might be some meta tags I'm leaving out, I'll look to improve it. But that boilerplate lets you know that hey, things are working, and it reminds me of the syntax for the link and script tags.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;As a note, I used to think it was cool to link directly to remote .js files when invited to do so, but now having been burnt a few times by URLs that went away, I'm a big fan of pulling down the file, and making sure your page is self-contained. and as free of external dependencies as possible.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-8647924181650577841?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/8647924181650577841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/boilerplate.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/8647924181650577841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/8647924181650577841'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/boilerplate.html' title='boilerplate'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8729407087018325447.post-5012602848331017856</id><published>2011-10-16T06:15:00.000-07:00</published><updated>2011-10-16T06:15:31.534-07:00</updated><title type='text'>yadb - yet another dev blog</title><content type='html'>This is my new blog, designed to help me keep track of things I've learned about UI and UX development. For now, that means a lot jQuery, with some general HTML5, CSS, and design thrown in.&lt;br /&gt;&lt;br /&gt;This isn't just meant as a "notes to myself" blog, though I'm not expecting any big following. Besides replacing my private database of developer notes I've been keeping, this blog might serve to give potential employers and coworkers insight into how I think about UI... it's a little scary because I might&amp;nbsp;inadvertently&amp;nbsp;air some "dirty laundry", places where my opinion goes against conventional wisdom, or times when I'm willing to make shortcuts in the name of expediency, or otherwise let my old curmudgeonly hacker self shine through. On balance I think it will be worth the risk.&lt;br /&gt;&lt;br /&gt;My job title is "UI Engineer", and I think UI is a fun place to be: it's the boundary of where the people meet the machines, and boundaries are always interesting areas. In my experience, there are two types of UI/jQuery developers: design people who are pushing to be engineers, and engineers who are pushing to be design people. I'm in the latter category, and I'd like to think that gives me a bit of edge in making powerful, delightful, "juicy" UIs, even as I have my own challenges in learning great design and graphic arts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8729407087018325447-5012602848331017856?l=kirkdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kirkdev.blogspot.com/feeds/5012602848331017856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kirkdev.blogspot.com/2011/10/yadb-yet-another-dev-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5012602848331017856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8729407087018325447/posts/default/5012602848331017856'/><link rel='alternate' type='text/html' href='http://kirkdev.blogspot.com/2011/10/yadb-yet-another-dev-blog.html' title='yadb - yet another dev blog'/><author><name>kirkjerk</name><uri>http://www.blogger.com/profile/15605658292036699663</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Rlq9sbKazVs/SYnDk7YEGtI/AAAAAAAAAAM/uS5V_xhSGIM/s1600-R/paperbill.jpg'/></author><thr:total>0</thr:total></entry></feed>
