Wednesday, December 31, 2014

animal advent ala ed emberley: director's commentary 11-15

Day 11: Bat

I might have made this one a little harder than it had to be... I should have made it a complex polygon-ish thing rather than a bunch of triangles (you can see the "skeleton" when it deconstructs.

I labeled each of the corners with letters, and this was the cheat sheet I used:
I liked the speed up / slow down inertia I put for the flapping cycle, rather than have it be "flapping / not flapping".

Day 12: Dachshund

This one was kind of fun. I was trying to think of an interaction (a friend suggested a hot dog bun could kind of float up and envelop the "dog" but that was kind of against the grain of the interactions and ended up with something a lot like Noby Noby Boy.  In theory it might have been better if it stayed on the screen a bit more. (I started a revamp that shrunk the dug down as it covered up more real-estaste, so it was always on the screen, but I ran out of gumption to finish it when it turned out to be uber-tricky to figure out, since I don't actually track where I'm drawing, I just use a series of rotations and translations.

Day 13: Shaggy Dog

This gal's "scribble" effect is unique among the puppets. It's subtle, but each scribbled segment redraws at random intervals. (Shades of "Dr Katz Therapist"'s Squigglevision.) I had some odd trouble between the Java/Javascript version and little "spikes" appearing, which I got under control but not completely resolved - I think it was some kind of rounding issue.

I think the tail wagging, head tilting, and ear adjustment give her a lot of personality

Day 14: Pig

Probably my least favorite of the puppets. (I had a coworker pick what to do next from the book... but I veto'd her first idea of this curly-doodled sheep, since I wasn't sure how to draw the curlicues.) It's about the only animal that's an outline rather than solid-filled, and I think that detracts. Also the interaction was nothing special, the tail unwinding a recycle of the trunk stretch I had already made for the elephant.


Day 15: Elephant

This one pleased me. It was about the third or fourth I had made, so I was hitting my stride a bit, and learning just how fiddly some of these could be! Sometimes the hardest part was the coloring in; when a kid is drawing, she has no problem doing "color in between these two lines", but when my program had it as two pre-defined shapes, it was a little tricky, and needed some cleverness in parts. In this case, the S (which was already a bit "interesting", constructed by 2 tangential circles) had to color in its top half but not its bottom.

Also I like how I made the trunk bend, by increasing the radius of the bottom circle while decreasing how much of the trunk arc it actually drew in.

Also, Go Tufts Jumbos!

Sunday, December 28, 2014

animal advent ala ed emberley: director's commentary 6-10

Day 6: Mice

This one didn't come out as well as I might've hoped. It's one of the few that has no action just on the mouse (in part because the original drawing wasn't very suggestive of animation.) I tried to make up for it by drawing many mice, but the 8 I first tried slowed things down too much in javascript mode, so I went to 3 in a classic "3 blind mice" mode. And I never got the switch from one circle to another as smooth as I thought it would be.

Day 7: Crow

One of my final entries. Kind of simple, but I love the way Emberley's "KAW" looks.
Day 8: Pelican

A good, middle-of-the-pack entry. A lot of personality with the puppetry, I think.

Day 9: Frog

This was the very first puppet I made, once I had the idea to make Emberley puppets. (I was inspired by a tiger I had put together for this year's advent calendar, before i had a theme.) I think it's really charming, and really set up the idea of trying to put in a little extra: the wiggle, the eye tracking, etc. A few puppets later I must have changed how I figured the stroke width for the deconstructed mode, the "D" forms are pleasingly chunky here.

Day 10: Crab

Not sure if I did this one before or after I visited Baltimore! Like the Pelican, I like the personality this one carries.

Thursday, December 25, 2014

animal advent ala ed emberley: director's commentary 1-5

Now that my advent calendar is finished for this year, I wanted to post about the individual entries.

The code is kind of a mess, and evolved in an ad hoc kind of way, with some irregularities in the syntax of the function. It's not easy to teach a computer to draw like a kid! And sometimes I'd throw in a new function just to make the computations easier.

The project README.md (as seen on the github project page explains some of the typical logic I employed. There was some inconsistency to when I would use pushMatrix() and popMatrix() and translate() vs just drawing the primitive in a different location, a lot just depended on what animation or effect I was going for.

Day 1: Snake

Even though this is the first entry, it was made in the middle of the pack.

I think its sinusoidal motion came out rather well, not bad for an opener, given how limited the source material was. The way the snake moves to the mouse location was added later, when I realized I wanted every puppet to do something with "normal" mouse motion and something special on the mouse click.

I still don't know how many users of the site didn't realize something special would happen when you used the mouse button... or for that matter, that you could go back and forth to the "deconstructed" version by pressing the "Go" button that starts the thing off, and then flies to the upper corner and becomes a "<->" button.

Actually, the "Go" button neatly solved a problem I had on iOS, where the first click would be ignored- it's actually there to make sure the canvas has focus.

Day 2: Spider

Springy motion is a crowd-pleaser, and easy to make: simple x-speed, y-speed, always attraction to the center (where the thread is nailed down) and always a gravity... a lot of tweaking so the thread was stretched to a reasonable at length when the thing was at rest.
Day 3: Bug

I was able to leverage the http://kirkdev.blogspot.com/2013/09/seeker-and-you-shall-finder.html for this little guy.

At first it only did turn and move on button, but then I added turning just on mouse,  in a similar spirit to adding stuff to the snake, so normal mouse behaviour had some puppet like effect.


Day 4: Chick

This was the second puppet I created, and honestly one of the most dull.

Mostly I wanted to prove that I could reuse the library I had stasted building up with the frog.
Day 5: Turtle

One of the final ones I created. Kind of cute, though without much of a puppet effect, and for the interaction I was hoping to get more of the visual effect of a coin reaching the end of its spin, right before it shudders to a stop.

Tuesday, December 23, 2014

modern web tricks

I made my annual virtual advent calendar again, and this year I focused on the work of Ed Emberley. I'll do a "director's commentary" for the 25 puppets once they've all been unlocked, but for now I'd like to talk about some of the little tricks I used in assembling the main launch page for this year's calendar.

(It has been drawn to my attention that some of my work online is older, and doesn't exemplify best web coding practices, and so going into the future I'm determined to always try and put my best face forward with this stuff (and shake some old functional-but-ugly habits I picked up along the way.))

Ed Emberley has a series of books teaching kids and grownups how to draw things one simple shape (a square, a circle, maybe a letter) at a time. I highly recommend them!

My first idea for the layout was with a wide, highly horizontal view for each day.
It did a good job of reflecting the layout of the books, where the construction of the animal is shown as new shapes  in a kind of landscape format. However, it didn't look very calendar-like; I "user tested" the early draft with some friends and the response was along the lines of "what is this?" So I switched back to my traditional 5x5 grid.

Another idea that came from my "beta testers" (Jeremy Penner) was this:
I definitely think it'd be nice to show which days you've visited. Perhaps by showing the animal it becomes? Right now it's pretty tough to go "I wanna play with the whale again", but I see the appeal in getting a surprise when you open up a present.

Great thought, and obvious in retrospect. I made a screen capture for each puppet, so before you had seen it, you see all the pieces that make it in a square (with a day # overlay), but once you've played with it, the abstract list of pieces is replaced with a playfully cropped portrait.

I really think this adds to a sense of discovery and progress in the site. As previously blogged I used browser Local Storage to remember what puppets the user had seen, and then set the day to the portrait if it had been viewed already. Games and some sites use similar techniques, and I really like how the pile of portraits grown. Of course it's limited to only working if you consistently use the same browser, but I couldn't see away around that without offering an account system or tie-in to facebook or some such, which would be overkill (and risks a sense of "well why do they want THAT"). Local Storage was a good compromise.

I decided to display each puppet in a modal dialog (using jqModal.) In previous years I had made each day its own page, but keeping it as a single page app felt better to me. I thought about using a hash/anchor for back button support and bookmarkability, but the small advantages were outweighed by the potential for confusion.

I was still worried about the "what the heck is this" factor, so I did a 26th puppet, a bird, to display at the top, in both deconstructed and puppet form. The thing is, I was shy about having a processing.js app running all the time (especially with some of the heavier puppets, running two things at once wouldn't have been a good idea for performance and battery life reasons) but I still wanted a sense of playful animation, so I converted a series of a screenshots to an animated GIF using ImageMagick. I made the output not loop, and then had the onmouseover reset the src, retriggering the animation when the mouse was moved over it:

<img src="img/shakeATailFeather.gif" onmouseover='this.src="img/shakeATailFeather.gif"'>

I also used setTimeout to trigger the same thing at random intervals, in case the user didn't try hovering.

Each puppet has 3 images associated with it: the portrait, the deconstructed pieces, and then a grayed out, locked deconstructed. (I also used ImageMagick to make the grayed out version.) Assuming I wanted to precache, that would be a lot of roundtrips to the server, so I constructed a CSS sprite sheet for all 75 images. Each was 160x160 and so I set up an explicit .img class (I probably could have been more sophisticated and used different css selectors) for plucking it out of the sheet:
.img {
    width:160px;
    height:160px;
    background-image: url('spritesheet.png');
    
}

The ImageMagick syntax for generating the sheet was

convert image1.png image2.png [...] imageN.png -append spritesheet.png

That makes a big vertical strip, and I made a perl script to construct the CSS for each image, something like

snake .img.seen{
       background-position: 0px -320px
}

The pattern there is that the y offset is (-1 * size of image * image number).

Finally I could tackle the appearance of each day. I used the css nth-child() selector to alternate red and green, and used a .5 opacity for the number overlay. (For the unlocked days, at least. For locked entries I had a starker white number that was over the greyed out deconstructed pieces image) I wanted to draw attention to the current day, so I decided to have it flash gold (well yellow) using a CSS animation:
.advcal .day.today.unpicked {   
    animation-name: homeCycle; 
    animation-duration:1s; 
    animation-direction:normal; 
    animation-iteration-count:infinite;
} 
@keyframes homeCycle {
  50% {color:yellow}
} 
(I also put in webkit version of these properties.)

For an increased sense of playfulness and interaction, I used CSS transition for the :hover over the squares.

I was glad to have the opportunity to practice CSS animations and transitions, since it's a relatively new technology. I had a little trouble finessing some of the states via classes alone, though, so while I didn't use jQuery for the color cycling I did use it for some of the image showing and hiding.

After launch, I added sharethis.com's widgets for social media sharing and some light view tracking. (In retrospect, I might have had a conflict with their use of the URL anchor hash had I been using that to follow the opening of the puppets.)

You can see the results on the live web site or in the github project page. As you can see, there's a lot of things that a mobile web engineer should be familiar with, and he or she should always be willing to experiment with different layout ideas, and test them with friends.


Wednesday, December 10, 2014

unix/osx find

To find files in (and below) the current path, less than 14 days old:

find . -mtime -14 
Older would be +14. More variants here, including date ranges, minute-level stuff, etc.

Friday, November 28, 2014

css spritesheets

CSS spritesheets, putting a bunch of images in one big image (so that http round trips are minimized) and then using CSS to just show the correct image subset of the full sheet, is a good trick to know about. (I suddenly started wondering if advances in the http protocol would make them less crucial, and allow multiple files to be downloaded in one gulp, so to speak.. googling to check that out brought me to a page saying you should embed images as encoded text in the CSS which seems to be taking it a bit too far!)

Anyway, I found it convenient to use good ol' ImageMagick. This page goes into some detail, but the net-net was doing:
convert img1.png img2.png img3.png -append spritesheet.png
was all I needed. That gave me a single .png with all the images in a vertical stack. I then made a quick perl script to generate the css, something like
.img {
    width:50px;
    height:50px;
    background-image: url('spritesheet.png');
}
.img.thing1{
       background-position: 0px 0px
}
.img.thing2{
       background-position: 0px -50px
}

(I had 25 of these to do). The important thing here is the offset, which is increasingly negative for each subsequent image.

The HTML was then something like
<div class="img thing1"></div>
<div class="img thing2"></div>
This raises best practices / style questions. W3Schools recommends using the img tag with a placeholder for the src (lest your html be invalid), ala:
<img class="thing1" src="img_trans.gif">
I see that it's kind of cool to keep things an image (even better would be list item tags or other semantically meaningful html tags) but going back to the old "transparent GIF" placeholder thing gives me the creeps!

Also you can run your generated file through an online image compressor... and there are even other online tools to smush the image together and give you the resulting CSS.

Thursday, November 27, 2014

localStorage

One of those things I grew up living with out (because it didn't exist in most browsers) and so don't always think of: localStorage is trivial to use in modern browsers, and provides decent support when you want to store some state across sessions, but don't want to make up a backend server to support it.

You have to be ok with not getting state back if the user is using a different device or browser, but then again, that's always true unless you've actually made some kind of server-side account system. (Which also has UX implications, in terms of a lot of people have "make an account to use this fatigue". And also "link to my FB account" fatigue.)

Anyway, window.localStorage; it's just sitting there, waiting for you, with old Old Skool messing with cookies.
localStorage.setItem("someKey",someThing);
and later
localStorage.getItem("someKey");
or you can even use array-like syntax:
localStorage["someKey"];

The only caveat it is many or all browsers will coerce your data to a string, so most likely you want something like
localStorage.setItem("someKey", JSON.stringify(someThing));
and
someThing = JSON.parse(localStorage.getItem("someKey"));
(with an appropriate safety checks)

Sunday, November 16, 2014

yosemite fullscreen

Even though it was reviled as being inconsistent and unpredictable, I preferred the old OSX "zoom" button behavior, where it (kinda sorta) maximized the window within the context of the current set of windows over the new "take over the whole screen world" pattern it has in Yosemite. I often want a bit more real estate for a given window, and rarely am I thinking "boy I wish I was looking at this window AND NOTHING ELSE MATTERS IN MY COMPUTER'S WORLD".

Besides predictability (especially when resizing browsers; some people found it odd that it didn't always try to be as wide as possible) I suppose Apple is trying to catch an iOS-like sense of "focus on this one thing" monotasking, and so they hide the dock and title bar. Personally, I think this is a UX misthink; a flavor of multitasking (or at least quick task switching) is fundamental to many people's use of a laptop or desktop.

(I like how Windows 7 did it; the window still takes up the full screen, but then you can reposition it)

Anyway, you can hold "option" when you click the green circle, and then gets the old zoom behavior; I just wish there was a way to switch which one was the default.

Friday, November 14, 2014

friday 5:30 pm kinds of problems and shaking old habits

One problem with being in the industry a decade and a half or so is that old habits die hard.

FOR EXAMPLE, I suspect some possible future employers will be thinking I'm a cave-dwelling Netscape 4.7 barbarian unless I go refactor out the use <table> for layout purposes on those sites I wrote in 2005 or so.

(THAT SAID, CSS only recently is anywhere near caught up with tables in its ability to position multiple objects relative to each other- the fact that this page on fluid width equal height columns even suggests monstrosities such as
margin-bottom: -99999px; 
padding-bottom: 99999px;
points to some serious limitations! (That hopefully flexbox et al will be resolving...) But really, I think <table> is a shibboleth, since if you're using <div> for display, you're pretty far from the html5 dream of the Semantic web anyway..)

ANYWAY. Old habits. One was in my use of console.log(). Earlier versions of it weren't very smart, it would just cast everything to a string.  And so I developed habits of doing stuff like this:
console.log("the thing is "+JSON.stringify(thing));
but that of course meant I would miss out on chrome's ability to display the object in the console in clever, expandable way.
But console.log happily also takes multiple arguments now too! So you can do
console.log("the thing is ", thing);
which is the best of all worlds; getting rid of JSON.stringify() cruft, having an expandable view of thing, and still having a human readable caption.

FINALLY, before I realized/remembered about how flexible chrome's console.log() is, I learned the hard way that JSON.stringify() on a variable set to a function gets very weirdish results. Just don't do it. I thought I was going nuts with my ability to curry a function until I realized it was because I was throwing JSON.stringify() into the mix.

Thursday, November 13, 2014

getting closure

Just a reminder about Self Excuting Anonymous Functions.. they're a great way to avoid polluting a page's global name space if you are making a script to be included on someone else's page (like in the window.onload event, where you don't want to leave a remnant.)

Some code I did today had bits like this:

(function (){
var oldOnLoad = window.onload;
window.onload = function(e){
//DO SOME COOL STUFF
if(typeof oldOnLoad  == "function"){
oldOnLoad(e);
}
}
})();

That was a decent way to not overwrite any existing window.onload code, but oldOnLoad isn't in the global space, because of the use of the closure.

best practices in templating

Some dueling articles! You Have Ruined HTML is negative about the "hipster languages" and the mix of HTML destined for the DOM with various controlling structures. The rebuttal is HTML Wasn't Made For Apps.

Among other things, the former article talks about the complexity of the looping filters (sometimes the complexities they introduce in the code to get some sweet, sweet syntactic sugar is a poor tradeoff) and the opacity of the error handling and debugging.

The rebuttal points out, among other thing, how ugly building DOM ala React is. This reminded me of the bad old days of Perl CGI; there were libraries to build a page in code, via structural elements, but it was a much better idea to use Perl's << quote syntax for extended, multiline quotes, embedding HTML as minitemplates, complete with variable substitution. (Sometimes I still feel there's a divide with coders who are closer to backend engineers, and want to avoid making raw DOM, and coders who are closer to designers, who want to make DOM directly, but with the flexibility of looping and conditional structure.)

The answer, as usual, is somewhere in the middle. For a while I had a bias for treating the DOM as a static billboard the Javascript would write to (at carefully predetermined and loosely coupled points) but I've learned how handy a good templating tool can be.  I think the best practice is to try to keep your chunks of template as modular as possible, and moving complex logic to code. (Where it's probably easier to test against anyway)

I'm kind of interested in what choice the various frameworks make in terms of tag-like, attribute-based markup (e.g. <div ng-if="somecondition"></div>) vs "out of band" markup (for instance with {{handlebar}} style structure.)  Sometimes the former seems a little cluttered to me, because it mixes the semantic levels; your control structures look like DOM content you'd expect the browser to render, and when you inspect elements you see that unrenderable stuff. On the other hand, the {{handlebar}} tags will make a terrible mess if you ever look at code in unprocessed form, and so are a bit less designer-friendly.

Sunday, November 9, 2014

remove smart quotes via javascript

I always have minor twinges that I am not typographically-morally upright enough to prefer "proper quotes" to "inch marks". 

But smart quote characters create more problems than they are worth. I used to run suspect text through the  Dan Hersam's Filter but I realized I should just take the basic code and put it more directly into my workflow. 

Here's the function I came up with, pass in the id of an input element and it will replace its contents with a safer, if less typographically pure, version.


function unsmartquote(id){
    var element = document.getElementById(id);
    var s = element.value;

    s = s.replace(/[\\u2018\\u2019]/g, "'");
    s = s.replace(/[\\u201C\\u201D]/g, '"');
    s = s.replace( /\\u2014/g, '--' );
    s = s.replace( /\\u2026/g, '...' );
    s = s.replace( /\\u00A9/g, '&copy;' );
    s = s.replace( /\\u00AE/g, '&reg;' );
    s = s.replace( /\\u2122/g, '<sup>TM</sup>' );
    s = s.replace( /\\u00BC/g, '<sup>1/4</sup>' );
    s = s.replace( /\\u00BD/g, '<sup>1/2</sup>' );
    s = s.replace( /\\u00BE/g, '<sup>3/4</sup>' );
    s = s.replace(/[\\u02DC|\\u00A0]/g, " ");
    element.value = s;

}

It took a little longer than I had expected to make this, I got bit by double slash for the unicode escape sequence merging into single slash by the time I was trying to copy and paste the code

Friday, November 7, 2014

zuck's half-answer to "why a second app"



(This is probably just a "things that irks me rant" in a "let's talk about some UX!" shell)

The Verge has an article: Mark Zuckerberg finally explains why he forced you to download the standalone Messenger app.

The need to install Messenger as a separate app (after months and months of ignoring the main FB app's pleas to, with promise of how "fast" it was) irked me mightily. I consider smartphone front page app space valuable - but I am interested enough in getting notified about activity on FB (whether post comments or messenger, the difference isn't all that much to me, really) that I had to carve out two places, since I would miss the notification badge on a secondary page. (Later I came to split the difference: the only app folder I have on my iPhone's first page is now "social media" in general, including Messenger, some dating sites, and some things for work I usually use on the laptop, while FB's main app gets to sit on the page itself.)

Anyway, for me the heart of his explanation was:
We saw that the top messaging apps people were using were their own app. These apps that are fast and just focused on messaging. You're probably messaging people 15 times per day.
 I am messaging people 15 times a day. Or at least 4 or 5. But it's the "But not on FB" that's Zuck's problem, the sentence he leaves out at the end of that. He'd love FB to be as critical for people in the quick messaging sense as it is in FB's traditional niche.

I don't know what FB's IM numbers are, but if the usage by me and my friends is anything to go on, the IM there is secondary. You use it when you aren't looking for a quick response, and you use it because if someone is on FB, they have access to a keyboard, and it's probably more physically convenient to tap out a response. (I know I'm talking like an old guy, where the web is more my native communication form than mobile.)

But FB is the big dog that sees this bone some other dogs are fighting over (Apple's iMessage and WhatsApp in particular) that, despite the delicious bone it has on its own plate, it wants to go and get a piece of that, no matter how many user's toes they step on. They want to own quick communication as well as the longer term "oh yeah that jerk I knew in middle school" longer term stuff.

Anyway.

FB, Tumbler, and Twitter collectively sucked a lot of the air from the independent web of the mid 2000s, because their value proposition of "build a centralized collection of possibly interesting stuff from people you know and/or expect to make or find cool stuff" is strong; it beats having to go from site to site, and hardly anyone bothered with RSS feeds for that (which I tend not to like, because it takes away the UX flavor I find critical in knowing where I saw something...)

the principles of rich web applications

7 Principles of Rich Web Applications is a pretty good read!
  1. Server rendered pages are not optional
  2. Act immediately on user input
  3. React to data changes
  4. Control the data exchange with the server
  5. Don’t break history, enhance it
  6. Push code updates
  7. Predict behavior

Wednesday, October 29, 2014

angular changes

I'm not anti-frameworks any more, but a buddy twittered me Have the Angular Team lost their marbles? outlining some changes coming down the pike, especially in "html plus extra bits" area, stuff like
<input type="text" [value]="newTodoTitle">
 <button (click)="addTodo()">+</button>
I really wonder about making such radical changes in syntax. (On the other hand, looking at Ember.js, I kind of liked that their templating takes the stuff out of the tags, and just uses the handlebars as a "this is out of band" marker, whether it's templating or logical structure.) Still, angular doesn't seem like a great choice if you wanted a stable platform going into the future. But it sure is popular in these parts.

Tuesday, October 28, 2014

who's that on my dang port?


On unix-y systems, 
lsof -i :8080
will show you processes listening to port 8080. You might have to sudo it.

Monday, October 27, 2014

notes to self: java HttpURLConnection weirdness

We have a suite of external tests we run for one of our adservers that happen to be written in Java and I'm writing a new test to ensure a cookie has been properly placed.

The connection code I ended up making was like this:
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection connection = (HttpURLConnection) currentUrl.openConnection();
connection.connect();
What's odd about that is that we are setting whether to follow redirects on a static class field. Also, empirically it has to be done before the openConnection() on currentUrl (an instance of URL). Frankly it kind of feels like programming via side-effect (as my coworker points out this pretty much breaks any sane threading model).

Update: this stackoverflow question about why is "setFollowRedirects()" a static, class-wide method. It turns out there's an instance-specific "setInstanceFollowRedirects()" that you can call after creation... the page suggests that it would have been less confusing and more in line with the convention used elsewhere if  the two were called "setDefaultFollowRedirects()" and "setFollowRedirects()", respectively.

The other weird thing is that while a response might have multiple "set-cookie" lines, some of the convenience functions HttpURLConnection provide assume the field name can be used as a unique key, so that getHeaderField() returns a single String, even if there were multiple lines using. A stack overflow article gave me the following:
    static String[] getAllValuesForHeaderKey(HttpURLConnection con, String header) {
        List<String> values = new ArrayList<String>();
        int idx = (con.getHeaderFieldKey(0) == null) ? 1 : 0;
        while (true) {
            String key = con.getHeaderFieldKey(idx);
            if (key == null)
                break;
            if (header.equalsIgnoreCase(key))
                values.add(con.getHeaderField(idx));
            ++idx;
        }
        return values.toArray(new String[values.size()]);
    }
Which is roughly the same as getHeaderField() but returns an array of Strings instead.


Saturday, October 25, 2014

the fun of placeholder content

So, still a work in progress, but I'm helping my cousin with his portfolio website. He was able to construct a decent idea of the layout he wanted at wix.com but got frustrated when he wasn't able to customize the interaction the way he wanted to.

For simple stuff like this, it's generally easier to build up from scratch than to hack a generated page's complex HTML. It was an interesting challenge to make a system that would be easy for my cousin to customize without mucking with code; I use "data-" tags so that the "table of content" type links know what section to open, and it should be pretty easy work to show him the structures to use.

I didn't have a lot of placeholder content to work with, and I was having trouble getting traction without it, so I generated a bunch of images and thumbnails. I parsed out some colors from w3schools' html color page and http://listofrandomwords.com/ for words (got my editor macro mojo working to push it into code) I then made a image generator in processing for the squares, fullsize and thumbnail.

I took a snapshot of its current state and put it in my devblog archive. But one cool thing is we were able to grab the domain WDJ3.com (his initials) -- always fun to find a relevant 4-letter .com domain!

Friday, October 17, 2014

growing up

I am accepting that (most?) interesting jobs are using frameworks.

I still think that framework use can bring on 80/20 rule Dietzler's Law hells, and almost by definition makes debugging tougher (since what you're looking at in the browser is more and more removed from the code you as a developer actually wrote - a coder is forced to the techniques of holism without the fallback of reductionism) but there are some pluses, and a lot of smart people really embrace these advantages.

But I mean it's so humbling, going from knowing near-everything relevant (DOM and CSS and Javascript) to knowing near-nothing (trusting the framework to do the right stuff but having it provide whole new worlds to learn) and I need to muscle through.



Even though Plain Old JQuery (along with some clunky Server Side Include for rough reusable modules) proved its value for a rich and complex application at Alleyoop, I have to accept that not everyone believes this is a sustainable, scalable pattern - and also I might not have really rich experience with "one page applications", we got much better mileage when we switched to logical functional breaks tied into various html pages.

I have to remind myself of the learning curve I had to master, to get talented at bending jQuery and CSS to my will.  Sometimes I think the big frameworks fanbase has a lot of folks who actually don't dig HTML5/JS/CSS basics as much, so they don't mind the gap between browser and written code. But this is an unfair assumption.

Meanwhile:
What's Wrong With Angular, a retort Defending Angular, and then the original author assembled a piecemeal list of Angular.js alternatives; getting the functionality that people long for "À la Carte", not buying whole houses when you just want the hightech kitchen.


Tuesday, October 7, 2014

angularjs mistakes

The Top 10 Mistakes AngularJS Developers Make. At work, we agree that Batarang looks pretty awesome, and maybe the author is a bit too harsh on jQuery.

Sunday, September 28, 2014

the processing/processing.js gap

Trying to learn about making some prettier graphs I decided to resurrect an old "drag the anchor and control points of bezier curve" toy I made a while back.

I like that this toy actually taught me about bezier spline curves; that I could make a composite curve by setting the endpoints of two different curves to the same x,y and then putting the control points on the same line... (the two lower curves on this example are sort of doing that)

You can play with the toy here. I had a harsh lesson making the web/processing.js version once the processing (Java) version was working fine: I had overloaded the processing functions line() and bezier() to take a new Point class, but in the Javascript translation, that had overshadowed the native functions full stop -- without Java's object typing, it couldn't tell which version I wanted to call.

The fix was simply renaming the functions to something that didn't collide with the built-in functions. I often say processing.js is a "good 90-95% solution" for translating Java to js, but that remaining 5-10% is pretty confusing to debug!

Saturday, September 27, 2014

p5.js boilerplate

I haven't checked but I'm pretty certain that the most used Google search for this site is "site:kirkdev.blogspot.com boilerplate". Which is what I use when I want to find my basic html5 template in a hurry.

Similarly, while I've messed messed around in p5.js before, leveraging my years of Processing mojo in a more purely javascript-y way, I don't have the usual "ceremonial" stuff down pat, and so to reduce the friction of starting a new project, I gift my future self with the following:

UPDATE: Remember you may want to use something like 
python -m SimpleHTTPServer 8000
(and then view http://localhost:8000
to run a little server,  if you are loading files etc)


UPDATE: I'm now providing myself two versions, the first is simpler, uses global functions, and puts the canvas on the page for you. The second only puts one variable in the global namespace and lets you have more control over the CSS styling of the canvas, but requires prefixing all P5 calls with a variable (e.g. p.line(x,y); not just line(x,y);) Also you could substitute p5.js or p5.min.js with one another or use the CDN links 
https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js
https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js

Global Mode:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>p5.js boilerplate</title>
<script src="p5.js"></script>
<script>
function setup(){
    var canvas = createCanvas(500, 500);
    canvas.parent("canvasParent");
};
function draw(){
    stroke(random(255),128);
    line(random(500),random(500),mouseX,mouseY);
}
</script>
<style>
    body {
        background-color: #333;
        color: #bbb;
        text-align:center;
        font-family:sans-serif;
    }
    a {
        color: #bbb;
    }
    #canvasParent {
        background-color:#3d3d3d;
        padding:20px;
        display: inline-block;
    }

</style>

</head>
<body>
  <div id="canvasParent"></div>
    <h2>title <a href="view-source:.">source</a></h2>
</body>

</html>


Instance Mode:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>p5.js boilerplate</title>
<script src="p5.min.js"></script>
<style>
    #appCanvas {
        width:500px;
        height:500px;
        border: solid 1px black;
    }
</style>

<script>
var app = function(p) {
    p.setup = function() {
        p.createCanvas(500, 500);
  };
    p.draw = function(){
        p.stroke(p.random(255),128);
        p.line(p.random(500),p.random(500),p.mouseX,p.mouseY);
    }
}

var myApp = new p5(app,'appCanvas');
</script>
</head>
<body>
<div id="appCanvas"></div>
</body>
</html>

It contains some arbitrary bits that I find useful (I like to work at 500x500 because of my blog, for instance) but is pretty minimal, easy to reset once copy and pasted. And I added just a touch of fun to the draw() routine, so I can see it working. (You can see it in action on my website, where I have a random copy of p5.js)

I love the idea of p5, though I admit having to remember to prefix every command with "p." (or whatever variable I've assigned) is annoying.

In other dev blogging... on FB I posted this:
I really feel like a better person, empowered and creative and capable, when I take time to sit and hack in an environment I'm fluent in, especially sitting in front of a big monitor rather than just grabbing time on the subway. Between a techie conference, helping friends in need, a band gig, and various social fun stuff, I haven't had a solid morning or afternoon for that for weeks.
I wonder if this feeling is anything like what people who get nurtured by being out in nature feel when they go camping. I mean, different, obviously, but deeply resonate and restorative nonetheless.

Oh. The other thing: I just realized that for YEARS a gmail filter I set up has been shunting all mail notifications of comments added here away and out of my inbox. I was getting too much material from the "OpenOffice.org" list, so I created a filter for "[dev]'. Turns out that filter wasn't as literal as I had assumed, so something like "[Kirk's UI Dev Blog]", or anything with the word "dev" in it, was shoved away as well. Ah, technology.

Wednesday, September 24, 2014

upcoming browser coolness - destructuring and web components

This past weekend my employer was kind of enough to foot the bill (and I was kind enough to sacrifice a weekend) for the No Fluff Just Stuff conference, 2 1/2 days of lectures on various topics. The emphasis is a bit more Java and fullstack than I try to be these days, but there was still a track for the front end, especially Angular.js and other js toolkits.

Two of my favorite takeaways were technologies that are not quite ready for prime time (Or to quote William Gibson: "The future is already here — it's just not very evenly distributed.") One is a tidbit from ECMAScript Next, the flavor of Javascript that should be running in your browser in a year or two.

10 years ago, I was blogging about a weird asymmetry in Java and most other C-derived languages (I know C didn't originate all of these things, but it certainly popularized it) - the unit of subroutine is a "function" which (probably because of its mathematic roots, or possibly because of what it's easy to make a compiler do) can take multiple parameters in, but can only return one thing. Perl, for one, didn't have that problem. A subroutine could have a return statement like
    return ($result1, $result2);
and a bit of calling code could easily grab each argument in a named variable:
    ($thing1,$thing2) = mySubroutine("foo","bar");

In fact, Perl uses this kind of in-array-variable-naming in lieu of traditional named parameters, so while C/Java/Javascript has something like
    function myFunction(String arg1, String arg2) {
Perl relies on a special variable "@_" to be the array of arguments, so a similar subroutine might start
    sub mySubroutine {
      ($arg1,$arg2) = @_;

It turns out that "in-array-variable-naming" has a formal name, and that is"destructuring", and it's going to be part of the next generation of Javascript!  In short, a function could return an array (as it can now) something like
    return [result1,result2];
but in the future the calling function could be doing something like
    let [thing1, thing2] = myFunction("foo","bar");
("let" is another bit of the new hotness, with easier to understand behavior in terms of scoping relative to "var". There are some neat syntax for packing up arrays, destructuring objects (vs lists) and what not as well.)

So that's pretty hip.

The final seminar I attended was on Web Components and Polymer. These are a kind of awesome way of writing your own tags to extend HTML5 - for example, you might include a Google Map as a single set of tags, or a chessboard display, or one of a bajillion bits of functionality. Each component gets its little shadow DOM, so conflicts in CSS and the like are avoided. (Polymer is just one implementation of the emerging WebComponents spec, but it seems good at using a "polyfill" technique to bring legacy browsers into the fold.)

I'm not quite sure why Web Components feel like the obvious future to me, and the Right Thing, when Angular.js feels like a weird, gratuitously complex set of kludges. I thought "making up our own HTML5-ish syntax" was one of things I hated about Angular, but I guess if you get the syntax and scoping cleaner, it's a pretty cool thing.

(https://www.polymer-project.org/apps/topeka/ is a nice demo of some of this flexible future.)

Still, I don't feel 100% at ease with Angular's "monitoring mapped memory to drive DOM changes" paradigm, its sometimes arcane syntax (oh, inject your dependency by an array consisting of a bunch of strings and ending with the function that does the work!-- though the conference pointed out how this is a pattern of protecting against "uglify" scripts that might try to rename globally shared variables), infamous learning curves, pushing of its own flavors of paradigms (ala factory vs service vs provider), extensive folder structures, etc etc -- or the way that Angular 2.0 promises to bust through some of the unfortunate syntax issues by making all your old code obsolete.

All that said, Angular might be the best bet in this direction that's here now, and I'm glad Web Components has shown me some of the light about getting into named components, not just an infinite future of <div> decorated in jQuery...

PS Another cool site is http://todomvc.com/, that walks you through the same basic example in a host of Javascript MV* frameworks...

Tuesday, September 16, 2014

the 7-minute no-look workout page

People at my company have been doing the The Scientific 7-Minute Workout. There are a ton of apps and pages and videos for this, but we were using http://www.7-min.com/. It's a decent site, but I realized there were some UX improvements that could be made. I noticed that I, and others using the side, would often:
  • announce the upcoming exercise (reading it from the page)
  • glance at the screen (some times difficult when on the floor!) near the end, and then count down the final "3...2...1" to alert peers
  • wonder what the "halfway point" was for exercises that didn't have a "switch sides" prompt midway through.
So I took these ideas, remade the illustrations, and ended up with kirk's no-look 7-minute workout page. (I also parlayed it into an open-source github project.)

The code is a bit inefficient, relying on setting up a big hoard of javascript timers, one for each page event. I'm toying with redoing it so it uses a single interval timer, but so far the current version seems to function ok. 

For sounds I used my own lowLag.js library. To make the voices, I used OSX's "say" command, using the India English voice "Veena" (some of the voices sound really off), dumping the result to an aiff file, and then using LAME to encode as MP3. (Happy to see firefox seems to be supporting MP3s now.)

The commands for that were:
say -v "Veena" "good job" -o goodjob.aiff
and
lame goodjob.aiff --preset medium goodjob.mp3

I didn't have permission to reproduce the NY Times illustrations, so I traced over and made some of my own. (I used ArtStudio on the iPad to trace over an existing set on a different layer.)

The only other clever bit was the old "python webserver" trick. 

It was nice iterating on this with "real users", i.e. my coworkers and myself. At first the "tick" was a bassdrum sound, but then didn't translate well over video chat. (Similarly, I may have to increase the contrast of the progress bar at the bottom.)

Anyway, the 7 Minute Workout is kind of fun. I'm skeptical about it, in some ways, and suspect we don't push ourselves enough while doing it, but still, it's better than nothing, and feels good to get through!

Thursday, September 11, 2014

dietzler's law

There are a lot of UI-centric build systems out there. As an old-skool web guy, some of them seem like overkill; but then again, I'm skeptical about the need to load content from a CDN, compressed, and bungled into one giant file, about whether that pulls its weight when you're in an agile mode. (As a final step, it becomes less onerous, and has more potential for being useful, but if you do it rarely than the automation isn't as crucial.)

I google for "Maven vs Rake" (Rake being "Ruby Make") and found this article, Why Everyone (Eventually) Hates (or Leaves) Maven. It cited a "law" -- technically about Access, but applicable to Maven as well as framework selection in general, that rings very true to me:
Dietzler’s Law for Access: Every Access project will eventually fail because, while 80% of what the user wants is fast and easy to create, and the next 10% is possible with difficulty, ultimately the last 10% is impossible because you can’t get far enough underneath the built-in abstractions, and users always want 100% of what they want.
The article cites a brilliant example of "composable systems", how systems that contain of simple, "do one thing, do it well" subsystems chained together are better than monolithic constructs: More Shell Less Egg is where 6 piped together unix commands trumped 10+ pages of beautiful Knuth Pascal for a simple word frequency task.

I think Javascript in particular lends itself to "composition over inheritance"; yes, there is a prototype system that can make it object-oriented-ish, but really, I don't think it's the language's most natural paradigm. By making function definitions as easy to assign as an integer, you can really make composable systems work well - and the simple elegance of JSON acts as a pretty decent glue language, just like plain, line and tab delimited text via pipes did for Unix. And as an extension of that, I prefer libraries with take-what-you-need functionality over big monolithic "this is how we do this" frameworks.


Friday, September 5, 2014

wavepot

I don't understand this enough to do much with it, but http://wavepot.com/ , where you can make sounds and tracks via math in real time, in the browser, is amazing.

Friday, August 29, 2014

frameworks are waterfall-ish

Geek time! Thinking about how I so strongly prefer libraries, where you call the code, to frameworks, where their code calls you. (More or less.)

Looking at the trouble I've had lately with frameworks, it seems like there's always some mismatch between the end result we're trying to produce, and what the framework does naturally - and the hacks to get from point A to B are UGLY. To that extent, I realize frameworks are inherently "Waterfall"-ish, because you have to have a good idea what you're coding from the very outset. Libraries tend to be more swappable, and you're less beholden to the clever Frameworks makers having pre-guessed your requirements.

Don't get me wrong; Agile always gets messy. But I think the messiness that results from keeping things simple is easier to cope with than the messiness of hacking around something complex.

coping skills: monitoring DOM changes

Debugging other people's code is tough, especially when there's heavy use of frameworks.

In this case some other code was changing the contents of a DataTable cell, and I didn't know how to track down what code was making the change.

Turns out Chrome and Firefox have pretty good facilities for adding breakpoints based on DOM changes! In Chrome's Elements tab, right click on an element, and there is a convenient "Break on..." menu, with a few convenient options for the type of change you're worried about.

I've worked with so many primitive environments that I'm sometimes a bit more adept with log-based / println style debugging, but my debugger mojo has grown reasonably strong as of late. (The nice thing about log-based debugging is it really forces you to think about the assumptions you're making, and you're less likely to get swamped by a flood of information.)

More Information at Stackoverflow (as usual).

Tuesday, August 26, 2014

wheel library

Gábor Berkesi sent me an interactive version of the hooptime information disply I posted the other day. It uses his wheelnavjs library, working to make it easier to make little dial and circle based navigation widgets -- good use of SVG!



Monday, August 18, 2014

piece on frameworks

I don't agree with all of it, but this Opinionated Rundown of JS Frameworks echoes many of my concerns about some of the popular systems out there, especially Angular.

Also, Why Libraries are better than Frameworks -- I guess a lot of what I think has been argued under the terms libraries vs frameworks, sometimes described as "if I call the code from my code, it's a library, if their code calls my code, it's a framework". I really think libraries lead to much easier to debug things!


Friday, August 15, 2014

the ux of time, the ui of p5.js! (hooptime)

Over the past few years I've realized that I use an idiosyncratic visualization for certain kinds of time; I see the cyclic nature of the twelve months of a year and the seven days of a week in the form of a circle, both going counter-clockwise. I spent some time today generating images reflecting this view. Here's a reflection of what a week is like for me:
I guess the specific rotation and counter-clockwise direction reflects a dash of synesthesia, and also how important physical layout is to my sense of recall -- if I'm trying to do a week-based day calculation, I'll often use my hand to as an arrow to mark my place in the week, in the same way I'll still unconsciously shape an "L" with my left hand to recall which direction is which. 

I'm less certain why I place the weekend down. My best guess is see that as the start and stop of a week, and is either "heavier" or "where the week meets the road" (to stretch the physical metaphor, since I view myself as moving in the fixed week-wheel rather than it moving to accommodate me.) The counter-clockwise motion then springs from that - I read left-to-right, so the Saturday-Sunday "start" to the week is in that "forward" direction, and thus drives the rest of the loop. 

Years are even more strongly laid out in my mind's eye: 

Here the calendar starts at the top, as one might expect, but I think that's because I view a year as progressing from school year to school year, with the loveliness of summer vacation anchoring as the base (though a separate desire to have the numeric transition be straight up tilts the thing a bit.) 

Neither visual is strongly color-coded for me, but week vs weekend and the various seasons have a different ephemeral feel, here color-coded for grins. 

As a side note, I used a new technology for this, p5.js -- the same processing.js I've used for years, but now as pure javascript, rather than going through some weird java-to-js convertor. Highly recommended! You can check out the working page and source code if so inclined.

(Incidentally, I looked into doing this with CSS trickery, but man, the CSS shapes page uses such crazy, inflexible hacks... relying on how if the div is tiny and the border is REALLY wide, then one side of the border looks like a triangle, and messing with border radius makes circles, and then you can get :before and :after going for extra stuff... bleh, it's a mess that breaks quickly when you try to adjust it.)

Tuesday, August 5, 2014

snapshotting music and video from streaming

I have a strong preference for paying for music. (Though I'm spoiled, and am less inclined to pay for whole albums.) I looked everywhere (err, meaning iTunes, Amazon, and general Google) but could not find an MP3 for Novel's Peach (a slightly raunchy hophop slow jam)

I tried the OSX app "Grappler", but it has been failing me lately. However a friend pointed me to http://www.deturl.com/ a kind of metasite with links to various "grab file from streaming" services.  http://convert2mp3.net/en/ was able to make an MP3 from the video, and then http://www.telechargerunevideo.com/ was able to grab a different youtube movie that I had previously uploaded, but that the OSX app Grappler was choking on. (Grappler wasn't able to do the Peach MP3 because "video not available on mobile").

Again, I pay for music (albeit, in a entitled way) whenever I can, and hope people dig on supporting artists as well.

Friday, August 1, 2014

PROTIP: Use OSX "Preview" to trivially fix janky iOS Photo EXIF issues

iPhone 5 macro mode isn't half bad. Although the lens isn't up to my Canon's quality, the touchscreen helps...

But more importantly I have a good-enough fix for my iOS EXIF workflow I was ranting about the other day.... I realized the easiest (Apple-centric) way for me to correct EXIF rotation on iOS photos is to open the image in OSX Preview and hit cmd-Save... then I can drag it straight into my dropzone.js powered webpage, and I'm set. (Sometimes I think I should just use tumblr so I can participate in the sharing, but I would lose the "what did I post on this date in previous years" ability.)