Archive

September

Rendur: sharing is caring

Friday the 11th, 12:29 AM
I've added the ability to save your work to the cloud! You can now share your projects and snippets with friends.

Here is a quick proof of concept for material design form elements: http://rendur.com/?n=YoungWrongLake. Click the 'Save' tab to fork the project.

As always no login/sign up is required so you should assume that anyone can view, delete and modify your saved code. Use this more as 'throw away' storage, not a place to store your personal code library.

To be clear: This service is provided as a convenience. You should not rely on it functioning securely or privately for any period of time. Don't save any sensitive or private information with this service.
June

Moving to angular, one piece at a time.

Friday the 26th, 4:18 PM
I'm currently in the process of of moving a massive ecommerce application from jQuery to angular. Since nearly everything depends on everything else, it becomes necessary for our new angular components to speak to the legacy jQuery code, and vice versa. I've written a few convenience methods you may find useful.

EDIT: so in practice, these work great! however, they don't trigger Angular's internal digest cycle. you'll likely want to write a convenience method that does that for you after issuing a message, or leveraging a service from within Angular. Such a method would look very similar to broadcastAngularEvent, except you'd only need a single argument (app), and once the appScope is found, you'd appScope.$apply()

// function for communicating with angular apps from outside angular.
function broadcastAngularEvent( app, message, messageData ){
var x, appScope, appSelector, selectors = [
'ng-app',
'ng_app',
'data-ng-app',
'x-ng-app' ];
for( x in selectors ){
appSelector = "*[" + selectors[x] + "=" + app + "]";
appScope = angular.element(document.querySelector(appSelector)).scope();
if( !!appScope ){ return appScope.$broadcast(message, messageData) }
}
}

// get and use Angular services from legacy code
function getAngularService( app, service ){
var x, appInjector, appSelector, selectors = [
'ng-app',
'ng_app',
'data-ng-app',
'x-ng-app' ];
for( x in selectors ){
appSelector = "*[" + selectors[x] + "=" + app + "]";
appInjector = angular.element(document.querySelector(appSelector)).injector();
if( !!appInjector ){ return appInjector.get( service )}
}
}

// broadcast events from within angular that jQuery code can consume.
function legacyBroadcast( eventName, eventData ){
var legacyEvent = document.createEvent('HTMLEvents');
legacyEvent.initEvent(eventName, true, true);
legacyEvent.eventData = eventData;
$window.dispatchEvent( legacyEvent );
}

/* catch these events like:
window.addEventListener('MY_EVENT', function( eventObject ) {
alert( eventObject.eventData );
});
*/
May

Recursively Search JSON Object

Thursday the 14th, 1:7 PM
I recently had a case where I needed to find a piece data in a rather large object. Since i couldn't be certain of its exact location within the object, i wrote a method to recurse through the object and return instances.

function findInObject ( srchObj, srchStr, resultSet ) {
var oKey, resultObj = {};
resultSet = resultSet || [];

for ( oKey in srchObj ){
if( srchObj.hasOwnProperty( oKey )) {
if ( oKey == srchStr || srchObj[ oKey ] == srchStr ){
resultObj[ oKey ] = srchObj[ oKey ];
resultSet.push( resultObj );

}
if ( srchObj[oKey] instanceof Object) {
findInObject( srchObj[oKey], srchStr, resultSet );
}
}
}
return resultSet;
}
April

Notes

Wednesday the 1st, 11:2 AM
my brain

I've been working on my notes application (previously) and have simplified the concept a lot. The application now runs smoothly on mobile browsers (maybe not safari? i dunno).

rad:

  • •   can be run completely offline. no one is storing a copy of your notes but you

  • •   can be run off the cloud. write notes on your computer. read them on your phone

  • •   relational organization. notes are stored in relation to one another. So you might have a 'work' note, with notes for specific projects or meetings. those in turn can have more detailed notes and so on. you aren't confronted with a massive wall of information, just what is pertinent

  • •   check lists. in you note settings, you can treat child items as a check list which can be marked as done


http://gregtaff.com/notes/
May

New functionality for rendur

Monday the 12th, 4:29 PM
rendur2.4
Added a dark theme, line numbers, the ability to export to an HTML file, and the ability to include external CSS and javascript files. Additionally, the DOM/window being modified is now an iframe, entirely sandboxing the environment from Rendr's memory space / dom structure.

rendur lite

rendur lite
March

Multi Column Sort in javascript

Thursday the 27th, 1:38 PM
Some time ago, I wrote a function that would generator sort methods that would allow you to sort arrays of objects using a shared child property. One of the obvious short comings was that it would only sort by a single property (or column).

I've been tinkering with an alternative and have finally arrived at something stable.

function getSortMethod(){
var _args = Array.prototype.slice.call(arguments);
return function(a, b){
for(var x in _args){
var ax = a[_args[x].substring(1)];
var bx = b[_args[x].substring(1)];
var cx;

ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;

if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
if(ax != bx){return ax < bx ? -1 : 1;}
}
}
}


Usage is simple. Just supply the column names as arguments, prefixed with +/- to indicate ascending or descending.

ex: items.sort(getSortMethod('+price', '+priority', '-rating', '-reviews'));

Here is a live demo.

card deck interface

Tuesday the 25th, 1:55 PM
card deckwas working on a card deck interface for a mobile site, but it turns out that it just doesn't perform well enough - but i thought someone might dig. works in desktop webkit too - but i've only specifically tested chrome.

Unicode Browser 2.0

Monday the 24th, 2:57 PM
unicode viewerI have the Unicode Browser a face lift, and added the ability to just to specific blocks of the unicode set. Should be a little more useful and easier to look at now.

blending modes with javascript

Friday the 21th, 6:16 PM
blending modes with javascriptI've put together a quick and dirty proof of concept that will make an image blend with its background using photoshop-like blending modes with javascript - specifically multiply, screen, and overlay. Its just a proof of concept/rough around the edges so there isn't a re-usable interface or anything like that. I intend to use this with phone gap to post-process images coming off the camera. If i do, I'll update this post with a more polished interface.
February

Notes To Self

Thursday the 13th, 4:0 PM
notes to self
Working another little personal project which I'm calling Notes To Self. The concept is simple - create, sort and store notes. By default, it saves the notes to localStorage, but supports Google Drive so you can access the same set of notes between computers. One this is a little more solid, I'll begin working on a mobile version - which is where this seems most useful.

Update. This has evolved quite a bit. focusing more on the mobile implementation. I'll update again when I have a beta to play with.
October

Sierpinski triangle generator

Monday the 28th, 12:29 AM
Sierpinski Triangle
Fun little canvas toy i put together that generates a sierpinksi triangle between any three points. Sierpinski generator.

CSS3 tooltips

Thursday the 17th, 12:17 AM
CSS3 tooltip previews
Been tooling around with a tooltip framework that leverages CSS, and as little markup as possible. I've whittled the markup down to just two divs. Example:
<div class="tipContainer green bottom">
<div class="tipContent">this is a sample tool tip</div>
</div>
You can see a working demo here: CSS3 tool tip demo

styleable, keyboard accessible select element

Wednesday the 2nd, 12:57 AM
I was frustrated by the inability to style select elements, so I made my own. Pseudo Select DEMO. Not only is it styleable, but you can tab through the options.
styleable, keyboard accessible select element
November

rendur in IE

Friday the 16th, 11:27 AM
With the release of the IE 10 preview, I tested rendur and its basic features and it all seems to work - more or less. As a result, Ive enabled additional features for all versions of IE [because I can't be bothered to target IE 10]. So if you're an IE user, enjoy. But seriously - just go get Chrome or Firefox.
June

save files in rendur

Friday the 8th, 7:58 PM
Thanks Jon for the idea! Using localStorage, you can now save and load files you're working on in rendur. Click "file" in the title bar, type in a file name and click "save". Since these are retained using localStorage, be aware that clearing your internet cache/temporary files will delete them. Also, as usual, IE folks get nothing.
May

get a textarea's current line number and content.

Tuesday the 15th, 6:40 PM
just a quick and dirty piece of code to grab the line number and content from the current line of a text area. haven't tested it outside of firefox and chrome so your mileage may vary.
function getLine(edit){
var start = 0;
var lineNumber = 0;
var content = "";
if(typeof edit.selectionStart == 'undefined') {return false}

start = edit.selectionStart;

lineNumber = edit.value.substr(0,start).split("\n").length - 1;
content = edit.value.split("\n")[lineNumber];

return {"lineNumber": lineNumber, "content": content}
}

minor update to rendur

Tuesday the 15th, 1:34 PM
rendur 2.3
The rendur editor now uses tabs instead of spaces (since firefox now supports tab-size. sorry chrome/safari/ie) and you can resize from three corners, rather than 1. The resize control is invisible - so just hover over the corners. Also gave it a minor face-lift and removed targeted editing. Did anyone actually use that?
March

quick and dirty code benchmarking.

Friday the 9th, 3:17 PM
totally unscientific, buuuut if you want a rough idea of which way of doing something is faster....
function bench(fn, iterations){
    
    var start = new Date().getTime();
    for(var i = 0; i < iterations; i ++){
        fn();
    }
    var end  = new Date().getTime();
    return (end-start);

}


var fn1 = function(){ ... }
var fn2 = function(){ ... }

var times = 50000;

alert(bench(fn1,times) + " : " + bench(fn2, times));
February

defer code execution till jQuery plugin is loaded

Saturday the 25th, 5:5 PM
On a big enough application, you'll have 5-10 jQuery plugins. if you're lazy loading JS files as necessary, you can't always be certain that the plugins you need are ready to go.

I wrote a quick and dirty method to defer your code till your plugins are ready.
pluginReady = function(plugin){
if(!jQuery.Deferred){
return;
}

// return a deffered object that will resolve when the plugin is available.
var pluginDef = jQuery.Deferred(),
pluginInterval = window.setInterval(function () {
if (!!jQuery[plugin]) {
pluginDef.resolve();
}}, 300),

// give up after 10 seconds
pluginTimeout = window.setTimeout(function (){
window.clearInterval(pluginInterval);
}, 10 * 1000);

jQuery.when(pluginDef).then(function () {
window.clearInterval(pluginInterval);
});

return pluginDef.promise();

};
September

quick and dirty input masking

Wednesday the 28th, 1:55 PM
I was recently tasked with adding formatting to a telephone number input field. I found this great masked input plugin which was fast, slick, and easy to use. Unfortunately, it bricks hard in the android web browser. I believe this is because of the android browser, not the plugin, but I can't be sure. The crux is, i couldn't use it and had to admit defeat, or find a replacement asap. I wrote this quick and dirty input masking function in a couple hours. Its not as smooth, but it works.
March

css warp

Saturday the 12th, 6:5 AM
September

unicode viewer

Friday the 3rd, 8:18 PM
unicode viewer
June

updates to Rendur

Wednesday the 30th, 2:21 PM
Rendur now includes jQuery so that you may use it when roughing out javascript behavior, and supports indenting a block of text at once. Its still a bit rough, and shift + tab to unindent is not finished yet.

UPDATE: shift + tab now works and selection is persisted. IE folks, once again, get nothing.

What is Rendur? render is a a itty bitty web app which allows you to rough out html/css/javascript quickly. You can see CSS and HTML changes as your type. The javascript sandbox is crude, but effective.

joby cummings

Saturday the 26th, 6:14 AM
7 sins
Pages and pages of really great stuff at Joby flickr stream.
[Joby's website]
March

goopy wasp hive

Monday the 22th, 7:1 PM
hive Im not super in love with it, but this is my latest arts.

remove duplicates from an array

Sunday the 14th, 7:11 PM
Ive been doing some really fun things with javascript lately, but not a lot of new ground worth posting about. I did however stumble upon a clever way removing duplicates from an array. I had a massive array which was 80% duplicates. The standard method which I had been using of two for loops - one nested in the other - was eating too many cycles. The solution was to exploit the map object - which does not allow duplicate keys.

Array.prototype.unique = function(){
var uniqueArray = [];
var workMap = {};

for(var i = 0; i < this.length; i++){workMap[this[i]] = 0}
for(x in workMap){uniqueArray.push(x)}

return uniqueArray;
}

This reduces the number of iterations from nn to n2 which is no small gain when dealing with large arrays!
November

1up

Wednesday the 11th, 5:35 PM

rendur tweaks

Monday the 9th, 1:24 PM
rendur shadow

No big deal. Rendur now has native dropshadows and rounded corners. IE folks get nothing.

Jellyfish!

Monday the 9th, 1:17 PM
because ive been looking at a lot of illustration by ernst haeckel
October

where the wild things are

Friday the 30th, 9:41 PM
where the wild things are

Lamp shade

Tuesday the 13th, 11:19 PM
lamp I made a lamp shade. how 'bout that?
September

More from Metanet

Thursday the 10th, 12:1 AM
N Remember that game studio I told you about that made my favorite game? They've just announced the next game they're going to be working on. Office Yeti.
July

super easy inheritance in javascript

Monday the 27th, 5:20 PM
One of the things that have always rubbed me the wrong way with regard to javascript libraries is that they often try to shoe horn javascript into a class based model. Javascript was intentionally designed to be a prototype based language. Rather than simply bitching about it, I decided to look into developing a concept of inheritance that was in step with javascript's conceptual roots.

First, a bit of background. The type of OOP you're most likely familiar with is class based. Remember Plato's theory of forms? There is an infinitive, unconjugated, universal concept of horse, and then there is this horse and that horse. This is how class based OOP, works more or less. You have a Horse class, and then instances of Horse. Prototype based OOP is different. It's much more bendy and flexible. Inheritance is achieved by cloning instances of existing objects. So for example, mammal is just an object with a few methods and properties. Human is a clone of mammal but with a postRandomCrapToFacebook() method.

mammal = {
sound: "",
eyes:2,
blood:"warm",
talk: function(){alert(this.sound)},
eat: function(){alert("munch munch")},
sleep: function(){alert("zzzzzzzzz")}
}

pig = ((new function(){}).prototype = mammal);
pig.sound = "oink";
pig.talk();
pig.eat();
pig.sleep();

porky = ((new function(){}).prototype = pig);
porky.sound = "thats all folks";
porky.dance = function(){alert("ta da!")}
porky.talk();
porky.dance();

dog = ((new function(){}).prototype = mammal);
dog.investigate = function(){alert("sniff sniff sniff")};
dog.sound = "BARK BARK!";
dog.investigate();
dog.talk();

yorkie = ((new function(){}).prototype = dog);
yorkie.sound = "barkbarkbarkbarkbark";
yorkie.investigate();
yorkie.talk();
yorkie.sleep();

granted, this is a bit wonky: yorkie = ((new function(){}).prototype = dog);

you'd probably want to create a function that would handle your cloning. Maybe something like this:

function copyOf(sire){
progeny = function(){};
progeny.prototype = sire;
return progeny
}

yorkie = copyOf(dog);

This is neat because you can have complex family trees, stitching functionality from this prototype into the next while each remains a functional object. There are no immovable static forms that merely serve as unalterable templates. I'm aware that many developers are "HORRIFIED and DISGUSTED" by this concept, but its really kind of liberating once you've acclimated to it.
May

beautiful motorcycles

Saturday the 9th, 2:45 PM
77 yamaha
just lots and lots of high quality photos of beautiful motorcycles. bikeexif.com.

globe projection

Thursday the 7th, 3:58 PM
projection Awesome page illustrating some of the different methods of projecting a 3D sphere onto a 2D surface. Check out the youTube clip at the end. http://www.crowded.fr/2009/04/20/la-projection-myriahedrale/
April

Playing with tables and css3

Thursday the 30th, 2:53 PM
Zebra stripes without stripe classes. Eventually, we'll actually be able to use this stuff......
table

table {border-top:0px solid;border-bottom:0px;}
td {padding:15px 10px; margin:10px 0px; border-bottom:3px solid #CC2D82; }
th {border-bottom:3px solid black;padding:20px 10px 0px 10px;text-align:left;}

th:nth-child(2n) {background:#5DB2FC}
th:nth-child(2n+1) {background:#75D1FF}

td:first-child {border-left:3px solid #CC2D82;}
td:last-child {border-right:3px solid #CC2D82;}
tr:nth-child(2n+1) td:nth-child(2n) {background:#FC5DB2}
tr:nth-child(2n+1) td:nth-child(2n+1) {background:#FF75D1}
tr:nth-child(2n) td:nth-child(2n) {background:#E8E8E8}
tr:nth-child(2n) td:nth-child(2n+1) {background:#FFFFFF}
tr:nth-child(2n) td:first-child {border-left:1px solid white;}
tr:nth-child(2n) td:last-child {border-right:1px solid white;}

[update: just realized that this is only working on ff3 on osx so the code is useless to 98% of all people, but I'm leaving it since its still fun. Ive replaced the example with an image so the rest of you can see what you're missing out on]

Free Radio. 'Free' as in beer

Thursday the 9th, 12:55 AM
If you aren't doing anything tonight, you should watch Free Radio. Vh1 @ 11pm, 10pm CT

post its

Friday the 3rd, 4:43 AM
did a few drawings on postit notes with a 005 felt tip. full size versions here and here.

skullGuana
March

sketch - Zeno

Tuesday the 31th, 4:45 AM
zeno
February

Rendur 2.2

Friday the 13th, 2:34 PM
rendur2.2

Finally made the switch to Rendur 2.2
The syntax highlighting is still not as fast and as solid as I like, but its still very usable. Also, rendur 2.1 was broken in FF3 so upgrading was a pressing matter. As always, please provide any feed back or ideas.

Whats new in 2.2

  • javascript sandbox

  • syntax highlighting for html and css. This is turned off by default (firefox only)

  • ability to turn realtime editing and syntax highlighting off.
    (select "Rendur 2.2" tab. When realtime editing is turned off, click the appropriate tab a second time to render your changes)

  • targeted editing. (firefox only) Click the target (?) to select an element and edit it's content while leaving
    the rest of the documnet untouched. Click any item in the targeted element's ancestry to
    edit that element.

  • minor layout/interface adjustments

December

venomous proto-mammals!

Tuesday the 23th, 1:45 PM
Euchambersia
This is Euchambersia, a therapsid [mammal-like reptile] from the late permian. It displays an "absence of postcanine teeth in association with a maxillary pit and grooved caniniform teeth" meaning it likely employed venom to dispatch it's prey. Neat huh! Also, check out the sharovipteryx, a gliding reptile with the flight membrane spread between its BACK legs. madness.
November

syntax highlighting

Tuesday the 18th, 3:33 PM
Ive been toying with the idea for a long time - adding syntax highlighting to rendur that is. There were a couple technical challenges standing in the way, but I feel that I've mostly circumvented them. I haven't officially moved rendur to the new version yet - since it still needs more testing, but you can get a feel for it here: rendur with syntax highlighting. Hit me up with feedback. Please. ( I hope it goes without saying that this will not be enabled for IE. Screw IE. Might support safari if i get around to it. )

css highlighting
example of CSS highlighting

I have also added the ability to turn off real time editing as this can be rather processor intensive if you're working on a large page, or with embedded objects. Ive also added the ability to turn off syntax highlighting since slightly older systems can choke on all the cycles it eats. Remember, this is javascript, not native desktop code :)

render with new options Keep reading for a technical detail of some of the challenges I had to work around:
First and foremost is adding color to a text area. This is no minor task since emulating a textarea with a div was far more work than I wanted to do, and textareas do not support coloring portions of their contents. I solved this by setting the background to transparent and placing a div behind it with it's innerHTML linkedd to value of the textarea.

Coloring the text, rather than highlighting would have been ideal. I actually toyed with that possibility by means of setting the transparency of the textarea to 50% so the colors of the div below would show through. This had the unfortunate side effect of also making the scroll bars, text selections of text insertion caret semi transparent. I think when rgba() is more widely available, this will be possible.

The other complete pain was keeping the scroll offset of the div linked with that of the textarea. Sounds like it would be easy right? Turns out firefox refuses to fire the onscroll() event. Wtf firefox. (the bug associated with this is marked fixed, but as far as firefox 2 is concerned, it most certainly is not.) This stings me more because I am not used to you letting me down :( The workaround wasn't pretty but it worked. It involved tracking the mouse down/move/up events on the textarea and syncing during each event. This is one of the biggest processor hogs. I will likely rewrite it to delay the sync function call a few milliseconds and cancel any sync calls which are older than the most recent sync call. I then had to trap the mouse wheel scroll but that was surprisingly simple


javascript fun

Wednesday the 12th, 7:0 PM
for fun Just mucking around with javascript, having fun. Javascript fun. Utterly useless - doesn't do a damn thing but entertain for 10-15 seconds.

PS - don't expect it to work in IE. It was fun to write, but not that fun.

The Loneliness Engine

Monday the 10th, 4:27 PM
In 1971 a small advertisement appeared in the back pages of Scientific American. It read, simply:

Never Be Alone Again.

It has been estimated that some thirty-five people responded to the ad, and another seventeen the following year. However, it cannot be ascertained at this point whether these fifty-two participants comprised the entirety of mail-in replies or merely selected out of a larger pool. In either case, each of the fifty-two respondents received a package approximately six weeks after enclosing twelve dollars in an envelope and sending it to a P.O Box in St. Paul Minnesota. The package contained a simple lightboard, various cables, a 103A modem, and a black button that depressed with a satisfying click. Those given to perusing the advertisements of Scientific American had little trouble connecting the pieces. The lightboard sparkled with an array of small LEDs, in seemingly random formations — the button alone did not seem to have purpose or effect, lying dormant beside the cables. In fifty-two living rooms, puzzled men and women stared at the board, trying to understand the patterns of light. And patterns there were: around 5:00pm, a great number of lights flashed on, so too around 9:00 am. During business hours there was mostly blackness on the board. Late in the night, clusters shone, and in the pre-dawn hours, there were always one or two. Slowly fifty-two souls began to realize that the tiny lights must ignite when other users turned their systems on, that each LED was another person who had seen the St. Paul ad, so was staring intently at the board, who was alone, who was like them. The button presented a mystery — though each one of them experimented with it innumerable times, the lights did not seem to be affected. Through the winter, fifty-two boards glittered in the dark, and fifty-two people watched the other lights, steady, unblinking, silent and anonymous, but somehow comforting.

In St. Paul, Minnesota, Milo Barnes sat at the switchboard of an AT&T public branch exchange. He worked the night shift, connecting jack to jack, watching the lamps light as calls connected, the drone of human conversation in his ears. He was a quiet man, taciturn towards his fellow operators, isolated in his threadbare chair. One of the only black families in his rural hometown, he had never had many friends. His parents had been farmers: onions, greens, root vegetables. Milo had gone to the city after a brief try at college, and found himself enveloped by the warm arms of Ma Bell. He remained introverted and painfully shy, despite being surrounded by a cloud of lively talk every night. In the eighteen months that the 103A modems were active, he never mentioned his thoughts to anyone, was never caught taking them from branch offices, moved through the PBX like a ghost.

In March 1972, the lightboards began to blink. It was not a very great logical jump for Barnes’ enthusiasts to recognize Morse code, and it was, after all, a short and simple message, repeated endlessly.

All’s well that ends well yet

Rose-Marie Gascoigne of New Orleans was the first to answer. She had sat with her lightboard for hours each evening, accompanied by two disinterested tabbies. She said later that her heart had “just plain stopped” when the lights began to flicker on and off. “The whole world just held its breath. I could hear the blood rushing in my head. I knew what to do–what the hell else was that damn button for? It just took me a couple of days to work myself up to it. It was like sending a message to God.”

She reached out to the all but forgotten black button, and tried to remember what she knew of Morse.

She was not the last. Danny McKitterick sent his message from Portland just minutes after Rose-Marie, by all accounts, and in the very small hours of a Minnesota dawn, Milo Barnes sat breathless among his jacks and his lamps as one by one they flashed on and off, a slow and tremulous human server in the days before the whole of the world was networked thus, finishing his line, answering his brief, quiet message, lights in the dark:

Though time seem so adverse and means unfit though time seem so adverse and means unfit though time seem so adverse and means unfit

Over and over, again and again. Milo must have smiled–it is a comfort to think of him smiling. While the other operators worked around him, oblivious, he sent out a new message to each machine that had supplied the coded response he sought, and this one was simpler than the others, more direct, and more frightening.

Pick up the phone at midnight.

As the moon came up in St. Paul, Milo Barnes closed his eyes and slotted a silver jack into place. And another, and another. San Francisco to Cheyenne. Phoenix to Charlotte. Seattle to Sacramento.

New Orleans to Portland.

Milo sat among his lamps and wires, his hands taut, and held his breath.

In Louisiana, Rose-Marie Gascoigne held hers, and put her ear to her receiver.

“Hello?”

The Loneliness Engine | Invisible Games
October

holy crap thats fast!

Friday the 24th, 8:42 PM
The super alpha build of the next version of firefox [code name:minefield] is pretty DAMN fast. download minefield.

Complex dynamic array sorting

Thursday the 9th, 7:16 PM
Have you ever wanted to sort an array in a non-standard way? Have you ever wanted to sort an array of objects by one of the properties common between the objects in the array? Continue reading!

I will move through this topic as if you have no idea how awesome Array.sort() is. If you know some already, you may want to skip a bit.

Say we have an array that looks like this:
["A","a","C","c","B","b"]

When we sort it, we would expect: AaBbCc right? Well, I would anyway. Turns out we get ABCabc. Pretend you REALLY want AaBcCc, or some other non-standard sorting result. You can still use Array.sort()! It turns out that Array.sort() accepts a single argument. The expected argument is a function which will itself accept two arguments. The function should compare the two and then pass back -1, 0, or 1 depending on what you'd like to do. Return a value of 1 or greater if the first value should be first, a value of -1 or less if the second value should be first, or 0 if they are equal. This is allows us to sort an array of numbers (since by default, the sort function will sort numbers alphabetically - meaning 1,2,26,33,4,5,6 etc).

a quick and dirty mock up might look like this:
sortedArray = myArray.sort(function(a,b){return a-b});

awesome! Now we can sort by all manner of arbitrary and senseless rubrics. We could sort an array of strings but their length rather than alphabetically like so:
myArray.sort(function(a,b){return a.length-b.length});

Now, lets say that instead of an array of strings or numbers, we have an array of objects. [{object},{object},{object}] I don't know what would happen if you tried to sort them, but I would have to imagine nothing useful coming out the other end. In order to sort the objects, we need a rubric or a rule. If all the objects share a member value or property, we can use that and write a function like this:

myArray.sort(function(a,b){
valueA = a.price;
valueB = b.price;
if(valueA < valueB){return -1}
if(valueA > valueB){return 1}
return 0;
});


Omg this is getting exciting! Can you feel it? All of a sudden, huge arrays of complex objects can be thrown to the native javascript methods rather than writting your own cumbersome sorting functions. The problem I ran into is that if you want to sort your array by multiple dimensions, the sorting methods replicate like leporidae and before long, you've got pages of them (cause you'll need two for each dimension. One to sort ascending, and one to sort descending). Its too bad that Array.sort() wont pass two additional arguments to the sorting function - one for the member property and one for the direction.....

And then there comes a point in every boys life where he finally finds a reason to write a function which returns a function as the output.

i now present - getDynamicSortMethod()

function getDynamicSortMethod(sortProperty, direction){
var thisMethod = function(a,b){
var valueA = a[sortProperty];
var valueB = b[sortProperty];
if(typeof valueA != "number" && typeof valueA != "object"){
var valueA = a[sortProperty].toLowerCase();
var valueB = b[sortProperty].toLowerCase();
}
if(direction.toLowerCase() == "up"){
if (valueA < valueB) {return -1}
if (valueA > valueB) {return 1}
}else{
if (valueA > valueB) {return -1}
if (valueA < valueB) {return 1}
}
return 0;
}
return thisMethod;
}


we can then use this function to do all manner of crazy sorting! Assuming we had an array of objects like:
{
name: "A car",
price: 40000,
year: 2008,
maker: "Tesla",
otherData: "as needed"
}


We can perform the following sorting operations:
sortedArray = myCarInventory.sort(getDynamicSortMethod("maker","up"));
sortedArray = myCarInventory.sort(getDynamicSortMethod("price","down"));
sortedArray = myCarInventory.sort(getDynamicSortMethod("year","up"));

September

THE NIGHTINGALE SONG

Friday the 12th, 2:38 PM
One morning, one morning, one morning in May,
I spied a young couple, just making their way.
Now, one was a soldier, and a brave one was he,
And the other was a lady, and a fine one was she.

And it’s “Where are you going?” said the soldier, so free.
“I’m going to yon river; it’s flowing for me.
Going down to yon river, and sit by that spring,
And watch the water gliding, hear the nightingale sing.”

And, “May I go with you as you journey along?
If I’m to go with you, I’ll sing you a song.
I’ll sing the old Concordance, and I’ll make my fiddle ring.
Then we’ll watch the water glide and hear the nightingale sing.”

Said the lady to the soldier, “I’m lonesome and blue,
And I think from your actions that you’re lonesome, too.
We’ll just walk together, then we’ll sit by that spring,
And we’ll watch the water glide and hear the nightingale sing.”

Now after they’d been there for an hour or two,
Out from his satchel a violin he drew.
He played the old Concordance; oh, he made that fiddle ring,
Then he'd watch the water glide and hear the nightingale sing.

Said the soldier to the lady, “It’s time I should go.”
“Oh, no,” cried the lady, “Play me just one tune more,
For I had rather hear your fiddle, or just tap a string,
Than to watch the water gliding and hear the nightingale sing.”

So he tuned his old fiddle to a much higher key.
He played the Shamrock of Erin--oh, he played it so free.
He played the Shamrock of Erin, and he made his fiddle ring.
Then they watched the water gliding, hear the nightingale sing.

Said the lady to the soldier, “Will you marry me?”
“Oh, no, my fair lady, this never could be.
I have a wife in Scotland with children twice three,
And that, with the army, is plenty for me.”

“Goodbye,” said the soldier, with a parting caress.
“Tomorrow I must be at the throne of Queen Bess,
But when I come back, it will be to this spring,
Then we’ll watch the water glide and hear the nightingale sing.”

“Goodbye,” said the lady, and she gave him her hand.
“I’ll think of you often in Ireland’s fair land,
For I had rather hear your fiddle, or just tap a string,
Than to watch the water glide and hear the nightingale sing.”
mp3

sometimes...

Wednesday the 10th, 4:1 PM
Somtimes, I wish the zombie apocalypse would happen.

movers, shakers

Wednesday the 10th, 12:43 AM

mover
Ive been toying with the idea of redesigning the portfolio, just because I don't get to play with very much fun javascript anymore. Here is a *rough* prototype. Don't click if you're using IE - I haven't bothered to test it there and Im sure it will throw errors at you. Click the large or small boxes to bring them into focus.
June

song to the siren

Thursday the 26th, 5:32 PM
On the floating, shapeless oceans
I did all my best to smile
til your singing eyes and fingers
drew me loving into your eyes.

And you sang "Sail to me, sail to me;
Let me enfold you."

Here I am, here I am waiting to hold you.
Did I dream you dreamed about me?
Were you here when I was full sail?

Now my foolish boat is leaning, broken love lost on your rocks.
For you sang, "Touch me not, touch me not, come back tomorrow."
Oh my heart, oh my heart shies from the sorrow.
I'm as puzzled as a newborn child.
I'm as riddled as the tide.
Should I stand amid the breakers?
Or shall I lie with death my bride?

Hear me sing: "Swim to me, swim to me, let me enfold you."
"Here I am. Here I am, waiting to hold you."

-Tim Buckley

errands and heroics

Tuesday the 24th, 4:49 PM
hero stepping from the ordinary
I love this picture for the bag carried by the man... as if on the way home from the grocery store, he decided to inspire the whole world as a casual after thought to a day spent getting ready to prepare dinner.

the whole world is [...] harmless enigma made terrible

Sunday the 22th, 9:54 AM
I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth. - Umberto Eco

list select

Tuesday the 3rd, 2:28 PM
list select Just about worthless but you might get a kick out of it. I whipped up a list select widget which allows you to make a list (ul) selectable (click within the list drag up or down to select items). Unusable in its current form (code isn't pretty) but could be groomed into something nice.
May

apply to children

Thursday the 22th, 6:10 PM
ok, haven't gotten around to pairing down that javascript mentioned below into the relevant parts. I may or may not at some point. However, while waiting for a project to build (arduous task indeed) I wrote a bit of javascript that takes a node and a function as parameters and recurses through its children, passing each node to the parameter function. I trust you can see the use in that :) heck, maybe you cant. In any case, I made something pretty with it. enjoy. applyToChildren function below:
function applyToChildren(myNode, fn){
fn(myNode);
if(!!myNode.childNodes.length){
for(var i=0;i<myNode.childNodes.length;i++){
applyToChildren(myNode.childNodes[i],fn);
}
}
}
April

bullet proof input behavior mod

Tuesday the 29th, 8:18 PM
After struggling to develop a standards compliant, unobtrusive, browser agnostic means of filtering input keystrokes, I have finally devised a simple and elegant solution. Hell yeah. go me.

What is worth taking with you:

Each browser handles events differently. The trick was learning how to stop the event in some cases and how to allow the event to proceed in others. Sounds like cake, but when you assume that you don't have complete control over the particular event (element.onkeydown = myFunction(){} vs element.addEventListener()) and then account for the differences between IE and FF, things get sticky. Ill post the relevant pieces of the code later.
March

SCIENCE!

Thursday the 20th, 12:13 AM
Harvard has put together a video library of short films which illustrate various scientific concepts. If you haven't already seen the inner life of the cell do so now. There is a great piece of it which depicts a kinesin molecule dragging its cargo along a microtubule.

I just watched the video which explains the chemical motor that creates most of our cellular energy (ATB). The video and motor are called "F1 - F0 ATPase".

i have been dreaming about this.

Monday the 17th, 4:17 PM

osm javascript function

Thursday the 13th, 2:17 AM
This clever fellow devised a function which will take markup described using JSON and then create the described nodes for you, saving you the time of writing out all that DOM code or falling back on innerHTML. see: createElements();

safari, firefox 3, rendur and !important

Wednesday the 12th, 4:4 PM
UPDATE: Ive added the javascript sand box for IE users - just because it was easy and I suppose there is no good reason not to.

With the firefox 3 beta available, i decided to see how my different sites would render and behave. turns out - rendur.com now breaks, but the same way that safari breaks. sucked because it meant that Id have to fix it, but good because it meant that I could possibly get it working for safari too. After a surprisingly small amount of work, rendur is now functioning in safari and FF3. (The difficulties appear to be with how each browser deals with '!important' declarations.) Like IE, safari doesn't reinterpret style sheets on the fly, so only the markup and javascript tab are enabled. Better than nothing I suppose. rendur.

uneasy truce

so freaking metal.

Wednesday the 5th, 8:44 PM
I have moved from lowly contractor to official employee. oh ye sweet sweet health care. No longer shall I pay out of pocket for x-rays!

UMCS

Monday the 3rd, 8:10 PM
ultra mobile chop sticks - FINALLY. ok seriously though: want.
UMCS
February

css column dividers

Thursday the 28th, 7:3 PM
if you know the width of two columns, but not their heights, you can still give them a divider that will always extend to the bottom of both. example.

column divider example

whats going on - it turns out that its the margin that causes an element to wrap to the next line, not its physical dimensions. the column divider is actually the right border of the parent element. The second column has a negative right margin equal to its width plus its margins. fun huh?

test

Saturday the 18th, 10:37 PM
test