MacOSX has Grapher?

Did anyone else know this?

I thought it was a cool discovery, so for all those nerds out there who want to graph things like acceleration, easing…

Cmd + Spacebar “grapher” that shit.

Traversing/Navigating Objects in Javascript

Once in a while, you learn something and go years before encountering the same scenario again. By that time you’ve probably forgotten all about it’s idiosyncrasy. Well…

I just spent 2 hours messing around with Javascript Objects. You see early on, I adopted a strict use of dot syntax. It jived with me so that’s what I used. I would use javascript arrays as well, but in my mind the two were mutually exclusive…not true. It turns out, if you can’t use dot syntax (let’s say you’re using dynamic variables to traverse an object instead of looping through every single property) then you can use an array syntax. Yes, that’s frickin correct…on object literals, you can treat them like arrays.

Now I actually knew this at one point, but forgot it years ago because I have a process for things and somehow that process has precluded me from encountering dynamically generated object traversals.

Anyway, fuck, here it is:

 

var obj = {
    thing: 1,
    things: "some more shit",
    thingz: {
        stuff: 2,
        stuffz: 'awh man!'
    }
}

console.debug(obj.thingz.stuffz);

 

So we’re all used to that, but it turns out, this works as well:

 

var obj = {
                    thing: 1,
                    things: "some more shit",
                    thingz: {
                        stuff: 2,
                        stuffz: 'awh man!'
                    }
                }

                console.debug(obj.thingz.stuffz);

                var t = "thingz";
                var s = "stuffz";

                console.debug(obj[t][s]);

 

Crazy shit right? Well not really, but sometimes its good to remember the small stuff… It can save you from say, having to traverse an entire object with an “if” statement looking for a string.

Anyway…

Sending JSON Headers from PHP

I ♥ data. My favorite way of sending data to the front end is of course, JSON. So here’s a quick snippet to get you up and running with some JSON destined for the front end.

First off, PHP is great with arrays. Luckily there’s a nifty little function PHP includes called “json_encode()”. It takes a multidimensional PHP array and converts it to JSON. However, in order to interact with it correctly on the front end, your AJAX script is going to need to know it’s “content-type” JSON. So here goes….

$arr = array('data', 'data2' => 'more data', 'data3' => array('even', 'more', 'data'));

header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
echo json_encode($s_floors);

Basically all I’m doing is filling an array with some string data and setting some headers to make sure the client browser recognizes the data as JSON. The most important header is the last one “application/json” tells the browser to expect something it can work with in Javascript. Then in the front end you might do something like…

$.get('example.php', function(data) {
                    console.dir(data);
                }, "json");

This script (requires jQuery) grabs data and expects to receive JSON. That’s it!

K, bored, bai!

Defaulting Images When Originals Don’t Exist

I needed to a profile image of some people recently. However, the profile images are hosted on another server and some people don’t have pictures. Unfortunately there’s no sure fire way to test for the existence of an image on a remoter server other than a cURL script to load a header and check for a 404 error. Since I’m loading over 600 images on one page, I needed a simpler solution…

The answer is to load your first image in an object tag, if that image doesn’t exist, you can include a default child image to take it’s place. Check it:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
<title>Object Test</title>
</head>
<body>   

  <object data="http://stackoverflow.com/does-not-exist.png">
    <img src="https://stackoverflow.com/content/img/so/logo.png">
  </object>

</body>
</html>

An HTML only solution is kinda nice once in a while. Bam!

Load jQuery from Google with Fallback to Local File

Quick one today, because I have shit to do…

If you don’t know why you should load your jQuery file from Google read about some of the advantages here.

But what if for some reason Google’s CDN is unavailable…like say you’re working on the site from a local copy and U haz no interwebs???

Write a simple script that checks for jQuery in the namespace, if it doesn’t find it, load a local copy:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>window.jQuery || document.write("<script src='javascripts/jquery.min.js'>x3C/script>")</script>

That’s it. It tries to load google’s, if “jQuery” is undefined, include the local version.

F**k if I Know

Hey all, I don’t know what this is…

I was making it to run some tests – on whether or not isolating live video of people’s faces in a google + hangout was possible. It turns out, not really – yet. Anyway I made this test to see if there was a way to show only a portion of a video – which there is. But if your talking about layering 2 – 3 videos on top of eachother, then you have issues. The problem is the video itself doesn’t disappear behind the overlaying div. If you try to just round out the borders on the iframe, then the video doesn’t work…

So I came to the conclusion that you cannot layer a person’s face on another person’s face using the hangout API, face tracking and a little border-radius magic on objects or iframes…bummer. But here’s the test anyway:

Click here for a demo…

<!--
Note - I have to create a grid of 4 divs to overlay and allow only center circles
to be show - not pretty but it might work...
-->
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
        <title>Test</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script>
            (function($) {
                $(window).load(function() {

                    var elem = $('#overlay');
                    var iframe = $('#if');

                    setInterval(function() {

                        var randTop = Math.floor(Math.random()*50 + 20);
                        var randLeft = Math.floor(Math.random()*50 + 20);

                        var reset = Math.floor(Math.random()*100 + 100);
                        var randOffset = Math.floor(Math.random()*50 + 50);

                        elem.css({
                            top: randTop + 'px',
                            left: randLeft + 'px'
                        });

                        iframe.css({
                            top: randTop + 'px',
                            left: randLeft + 'px'
                        });

                        setTimeout(function() {

                            if(reset > 150) {
                                elem.css({
                                    top: (randTop - reset - randOffset) + 'px',
                                    left: (randLeft - reset - randOffset) + 'px'
                                });

                                iframe.css({
                                    top: (randTop - reset) + 'px',
                                    left: (randLeft - reset) + 'px'
                                });

                            } else {
                                elem.css({
                                    top: (randTop - reset + randOffset) + 'px',
                                    left: (randLeft + reset + randOffset) + 'px'
                                });

                                iframe.css({
                                    top: (randTop - reset) + 'px',
                                    left: (randLeft + reset) + 'px'
                                });

                            }

                        }, 600);

                        setTimeout(function() {

                            elem.css({
                                top: '0px',
                                left: '0px'
                            });

                        }, 1100);

                    }, 2000);

//                    setTimeout(function() {
//
//                        elem.css({
//                            top: 20,
//                            left: 20
//                        });
//
//                    }, 2000);
//
//                    setTimeout(function() {
//
//                        elem.css({
//                            top: -150,
//                            left: 0
//                        });
//
//                    }, 4000);
//
//                    setTimeout(function() {
//
//                        elem.css({
//                            top: 80,
//                            left: -50
//                        });
//
//                    }, 6000);
//
//                    setTimeout(function() {
//
//                        elem.css({
//                            top: 80,
//                            left: 150
//                        });
//
//                    }, 8000);
//
//                    setTimeout(function() {
//
//                        elem.css({
//                            top: 0,
//                            left: -150
//                        });
//
//                    }, 10000);

                });
            })(jQuery);
        </script>
        <style>
            section {
                display: block;
                margin: 0 auto;
                width: 420px;
                position: relative;
            }

            iframe {
                position: absolute;
                top: 0;
                left: 0;
                z-index: 10;
                transition: top .5s ease-in-out,left .5s ease-in-out;
                -moz-transition:top .5s ease-in-out,left .5s ease-in-out;
                -webkit-transition:top .5s ease-in-out,left .5s ease-in-out;
                -o-transition:top .5s ease-in-out,left .5s ease-in-out;
            }

            #container {
                width: 420px;
                height: 315px;
                position: absolute;
                top: 0;
                left: 0;
                background: green;
                border-radius: 210px;
                border: 50px solid red;
                z-index: 20;
            }

            #overlay {
                width: 234px;
                height: 221px;
                position: absolute;
                top: -46px;
                left: 0;
/*                background: blue;*/
                border-radius: 252px;
                border: 136px solid white;
                z-index: 30;

                transition: top .5s ease-in-out,left .5s ease-in-out;
                -moz-transition:top .5s ease-in-out,left .5s ease-in-out;
                -webkit-transition:top .5s ease-in-out,left .5s ease-in-out;
                -o-transition:top .5s ease-in-out,left .5s ease-in-out;
            }
        </style>
    </head>
    <body>
        <div id="wrap">
            <header>

            </header>
            <section>
                <div id="container">
                    <iframe id="if" width="420" height="315" src="https://www.youtube.com/embed/vptfm9D6owo?rel=0&autoplay=1&wmode=Transparent" frameborder="0" allowfullscreen></iframe>
                </div>
                <div id="overlay"></div>
            </section>

            <footer>

            </footer>
        </div>
    </body>
</html>

It works by taking using css transitions for the animation – then every 2 seconds, javascript passes some location changes to the video and the overlaying div. These location changes automatically animate with css3 transitions and are randomly placed. At the end of every 2 second loop, there’s a reset so the overlay and video return to:

top: 0px;
left: 0px;

Let me know if you’re interested in a real explanation and I’ll write one up…

HTML5 vs. Flash in the Infinite Battle of the Inconsequential

I just got an email at work comparing Flash to HTML5 in an info graphic…this is unprecedented…

One thing before I begin my self righteous diatribe: The reality is that both technologies (actually HTML5 is really a combo of JS, CSS and HTML5) are good in certain situations an not others…there’s no silver bullet. You would not find me arguing for an HTML5 banner ad (yet) and I wouldn’t suggest a flash based site for a company specializing in iPad ads.

That said, here’s the deceptively objective email and graphic below:

From: No one in particular
Date: Tue, 31 Jan 2012 14:46:16 -0600
To: interactive SF <not_a_public_email@private.com>
Subject: HTML vs. Flash

Yet another infographic comparing lima beans to kazoos.

Credit: Another Person.

Someone at work.

This email was sent with the attached info graphic:

Here’s the email I would have sent if I wanted someone to argue with…

I feel (respectfully of course) that this info graphic might as well be arguing for the horse and buggy at the point the automobile came about. Sure, there were no gas stations, no paved roads, and let’s face it…99% of people were using horse and buggy. But that didn’t stop progress did it? Even though automobiles clearly don’t have support for saddles…

IMHO

Mike

Alas, I don’t feel like arguing about this for a couple of reasons:

  1. Reality. Most people argue on the basis of “should” or “could.” While I support idealism , it’s all a waste of time. The reality is that both technologies exist side by side and will continue to be useful in various situations. HTML5 will continue to gain support in the web development community for it’s open and standards based approach. Flash will continue to do things HTML5 only has wet dreams about (in the short term atleast).
  2. Time. Tell ya what, let’s argue about this in five years when we have more information to argue with.
  3. Paradox. There’s a reason hind-sight is 20/20. We can’t predict the future, which is why we can’t ignore new technologies. Besides, flash has been around, and while I’m all for innovation…we’re lazy. Doesn’t it make sense to try on a new field where new discoveries are made almost daily?

Dude.

Interactive Tablet Ad Examples

I’ve been looking for a directory of iPad ad examples and I can’t find anything…

So here’s what I’ve pulled together:

USA Network | White Collar | HTML5 Gamified Banner Ad on the iPad from Glow Interactive on Vimeo.

Camaro : iPad Ad from Fabio Seidl on Vimeo.

IBM Smarter Cities Rich Media Campaign on iPad from Crisp Media on Vimeo.

Hitachi on Bloomberg Businessweek from Crisp Media on Vimeo.

Oppenheimer Funds on Wall Street Journal from Crisp Media on Vimeo.

Point Roll Lincoln Ad: MKS Small

Best practices for iPad ads here: iPad Best Practices

How to make a killer iPad Ad here: Killer iPad Ads, by Conde Nast

You can also grab the iAd gallery (an app that puts on demand iAds in your pocket on your phone or iPad): iAd Gallery

5 Best practices for iPad Magazine App Ad development: iPad Ad Development

Tablet comparison chart: Mashable

Tablet ad showcase: Crisp Media Ad Showcase

If you see something that’s missing or needs to be included on this page please drop me a line or leave me a link in the comments.

Contact Mics

Since I need someplace to catalog potentially useful technologies (essentially stick them in a digital filing cabinet for use later) and I don’t have the time to code demos as often as I’d like, I’ve decided to start talking about devices, patterns, creations and all manner of tech as well as code demos and my own creations.

First on my list would be the contact mic.

Contact Microphone Photo
This tiny microphone acts basically like a tiny seismometer to detect vibrations from touching a surface associated with the mic.

It operates by turning tiny vibrations into electrical signals. Think of an electrical stethoscope, it operates by amplifying signals from something called a “piezoelectric transducer” essentially turning any surface into an instrument. One could for instance, take a hard surface like a table or window, attach a contact mic and listen for amplified signals caused from touching, scratching, impacting or generally interacting with the surface. However, the possibilities don’t stop with creating amplified sounds from surfaces. You could also listen for vibration frequencies and determine which sound patterns they are closest to. Then emit those sounds instead, creating a more interesting interactive device. Example below:

However, the power of this technology doesn’t stop here. If we can detect frequencies then we could potentially detect gestures. If we can detect gestures, we could effectively make a multi-touch system from say a tree. We could then browse the internet or make an interactive art installation, from our tree…

This technology would be exploratory in much the same way the kinect is right now. It would allow users to create different results from interactive with a surface in slightly different ways.

As always, let me know if you’re doing anything cool with this…

SOPA Script

I thought it would be interesting to make a script to censor your content to help draw attention to how ridiculous SOPA is. So I made something you can drop onto your site and it’ll automatically censor parts of your content (note this requires jQuery).

DEMO or DOWNLOAD

It’s fairly straight forward. First we set a window load event and wrap it in a closure so we don’t make the ‘$’ conflict with any other libraries.

(function($) {
    $(window).load(function() {

    });
})(jQuery);

Then we want to grab all the elements that might have text in them. There’s a special jQuery function here called “each” it simply takes the array of all the elements in jQuery selector and loops through them, passing in an “index” to an anonymous function:

(function($) {
    $(window).load(function() {
        $('h1, h2, h3, h4, p, span').each(function(index) {

            // each element in here

        });
    });
})(jQuery);

Then we’ll split the content up by spaces so we can loop through each word of the the content.

(function($) {
    $(window).load(function() {
        $('h1, h2, h3, h4, p, span').each(function(index) {

            var contentArr = this.textContent.split(" "),
                collector = '';

            for(var i = 0; i < contentArr.length; i++) {

                // each word in here

            } // end i

        });
    });
})(jQuery);

Then we’ll set a random number 1-100 and determine if the number is lower than 35%. This will censor about 35% of our content. We’ll test for this and replace the word with censored content. We’ll also add our words to the “collector” which will replace the content in each of our elements:

(function($) {
    $(window).load(function() {
        $('h1, h2, h3, h4, p, span').each(function(index) {

            var contentArr = this.textContent.split(" "),
                collector = '';

            for(var i = 0; i < contentArr.length; i++) {

                var rand = Math.floor(Math.random() * 100);

                // block out about 35% of the words on the page
                if(rand < 35) {

                    // replace the word with censored characters here

                }

                collector = collector + contentArr[i] + ' ';

            } // end i

        });
    });
})(jQuery);

Finally, if we are going to replace the word with censored characters then we’ll add another loop that gets the length of the word and replaces it with black blocks. Finally here’s the whole thing:

(function($) {
    $(window).load(function() {
        // get all text
        $('h1, h2, h3, h4, p, span').each(function(index) {

            var contentArr = this.textContent.split(" "),
                collector = '';

            for(var i = 0; i < contentArr.length; i++) {

                var rand = Math.floor(Math.random() * 100);

                // block out about 35% of the words on the page
                if(rand < 35) {
                    var censorBar = '&#9608';

                    for(var t = 0; t < contentArr[i].length; t++) {

                        censorBar = censorBar + '&#9608';

                    }

                    console.debug(censorBar);

                    $('footer').html(censorBar);

                    contentArr[i] = censorBar;

                }

                collector = collector + contentArr[i] + ' ';

            } // end i

            // i could put some css transition or fade on this to make it more interesting

            $(this).html(collector);

        });
    });
})(jQuery);