<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kevin Hoyt</title>
	<atom:link href="http://blog.kevinhoyt.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kevinhoyt.com</link>
	<description>Hey, Hoyt!</description>
	<lastBuildDate>Thu, 23 Feb 2012 04:35:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Drawing with CSS</title>
		<link>http://blog.kevinhoyt.com/2012/02/drawing-with-css/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=drawing-with-css</link>
		<comments>http://blog.kevinhoyt.com/2012/02/drawing-with-css/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 21:53:56 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Creative]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=225</guid>
		<description><![CDATA[From time to time I run across somebody that has pushed CSS to the point where they can draw pictures with only markup.  There are a few interesting older CSS behaviors that make this possible, and of course some new tricks such as gradients as well.  In being inspired by some of these examples, I [...]]]></description>
			<content:encoded><![CDATA[<p>From time to time I run across somebody that has pushed CSS to the point where they can draw pictures with only markup.  There are a few interesting older CSS behaviors that make this possible, and of course some new tricks such as gradients as well.  In being inspired by some of these examples, I couldn’t help but try my hand at the technique on an image I see nearly every day &#8211; the Adobe logo.</p>
<p><a title="Adobe Logo in CSS" href="http://www.kevinhoyt.com/playground/css/logo/logo.html"><img class="alignnone size-full wp-image-226" title="Adobe Logo with CSS" src="http://blog.kevinhoyt.com/wp-content/uploads/2012/02/adobe-logo-css.png" alt="" width="315" height="415" /></a></p>
<p>Since the Adobe logo does not have any gradients, and is fairly blocky to begin with, it made for an easy subject for a first attempt.  I was able to manipulate the border width and thickness, as well as width and height, to draw the triangles that make up the logo.  It may, however, surprise you to find that I have also drawn the letters of the logo with only CSS.  Letter stems are rectangular elements, and the circular parts are tuned corner radius values from CSS3.</p>
<p><strong>Going to Extremes</strong></p>
<p>Then I got to wondering “If I have reliable pixel control over elements with CSS, then it seems like I should be able to draw just about anything.”  Bitmaps are after all just two dimensional arrays of color values (pixels).  Of course I wouldn’t want to code every pixel by hand, but if there was a way I could get pixel color values in an automated fashion, that might lead to some interesting results.</p>
<p>Then I recalled that you can get pixel values from the canvas element in HTML5.  I could just code the canvas to have the image directly, but that wouldn’t be any fun &#8211; after all, if I was going to hard code the image, I could just use an image element.  To make the project really interesting I would need a way to load a user-supplied image.</p>
<p>At the HTML5 Live conference in London, Christian Heilmann of Mozilla fame gave a talk on many of the bad things web developers do that have since been replaced by more modern techniques &#8211; usually due to updated standards.  One such example was to avoid the old input element with a type of file for loading an image.  The more modern version of that technique is drag and drop, which is a preferable user experience pattern.</p>
<p>Now that I had an idea of how to get a reference to the image, I needed a way to actually load the user-provided image into the canvas.</p>
<p>The drag and drop operation gives you a file name, but no system-relative URL.  “But wait, the file name is provided as a File object from the W3C File API.”  If the File API is at play, then I could potentially read the file in directly, and then put the results into an image element.  From there I could draw the image element into the canvas, and dissect the pixel values.</p>
<p><strong>Putting It All Together</strong></p>
<p>Did it work?  Yes, it did!  Sure, it is a long ways around, but I think you will agree that the results are pretty impressive.  To test it out for yourself, you will want to get a small-ish image to use.  Keep in mind that a 100&#215;100 pixel image is 10,000 elements to put into the DOM.  I have put some optimization in place to use the same element so long as the following pixel is the same color.  The test case I used is this image of Bart Simpson.  Right-click and save it to your desktop.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2012/02/bart.simpson.png"><img class="alignnone size-full wp-image-227" title="Bart Simpson" src="http://blog.kevinhoyt.com/wp-content/uploads/2012/02/bart.simpson.png" alt="" width="168" height="300" /></a></p>
<p>With our buddy Bart saved to your desktop, head on over to the <a title="Turn Pixels Into CSS" href="http://www.kevinhoyt.com/playground/css/pixels/pixels.html">scene with Moe</a> waiting for a phone call from his nemesis.  Take the image from your desktop and drag and drop it to where the instructions tell you (roughly the center of the screen).  Once you have dropped the Bart image, moments later he will appear across from Moe.  That version of Bart is entirely CSS &#8211; 30,000 DIV elements to be more exact.</p>
<p><a title="Turn Pixels Into CSS" href="http://www.kevinhoyt.com/playground/css/pixels/pixels.html"><img class="alignnone size-full wp-image-228" title="Bart Simpson and Moe the Bartender" src="http://blog.kevinhoyt.com/wp-content/uploads/2012/02/bart-moe-scene.png" alt="" width="450" height="283" /></a></p>
<p>Don’t believe me?  Try it with your Twitter avatar, or make a small image from your latest family outing.  PNG (including transparency) and JPG will both work fine.  The magic is accomplished by iterating through the pixel values and creating a DIV element for each that is one pixel wide by one pixel tall, and positioning the element relative to the row/column that pixel is found in the image.  The background color of the element is set to match the pixel color.</p>
<p><em>Note: Safari does not implement FileReader yet, so this example will not work there.  I have tested on Chrome and Firefox without any problems.</em></p>
<p><strong>Conclusion</strong></p>
<p>What surprised me most was that it actually works as fast as it does.  When I have shown it in the past, most people just think the image itself has popped into the DOM.  Nope, that’s tens of thousands of iterations later, bub.  I have also found that the logic needed to dissect the image executes almost instantly.  The slow part is the actual rendering of the new DOM elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2012/02/drawing-with-css/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cigars 2011</title>
		<link>http://blog.kevinhoyt.com/2011/12/cigars-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cigars-2011</link>
		<comments>http://blog.kevinhoyt.com/2011/12/cigars-2011/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 19:47:02 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Cigars]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=216</guid>
		<description><![CDATA[It is around this time of year when all the cigar blogs light up with annual reviews.  The lists range from the top ten, to rankings of all the stogies smoked in the year past.  I don’t have anything that exhaustive, but I do have some new and interesting smokes I encountered this year.  Here [...]]]></description>
			<content:encoded><![CDATA[<p>It is around this time of year when all the cigar blogs light up with annual reviews.  The lists range from the top ten, to rankings of all the stogies smoked in the year past.  I don’t have anything that exhaustive, but I do have some new and interesting smokes I encountered this year.  Here are five of the cigars that come to mind, with a little description of why I chose them, or what I thought was unique about them.  Should you encounter them in the wild, they are all worth your time and money.</p>
<p><strong>Drew Estates Dirty Rat</strong></p>
<p><strong></strong><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/dirty-rat.png"><img class="alignnone size-full wp-image-220" title="Drew Estates Dirty Rat" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/dirty-rat.png" alt="" width="300" height="81" /></a></p>
<p>Among my all time favorite cigars is the Drew Estates Liga Privada No. 9.  It is a line that they continue to expand &#8211; the T-52 is also very good, if a bit more spicy.  With the Connecticut sun-grown wrapper from the T-52, the Dirty Rat takes that spiciness one step further.  At 5 inches by 44 ring gauge, the Dirty Rat is a smallish stick, but burns slowly lasting a solid hour.  I had no burn or construction problems.  Like all the of the cigars on this list, the Dirty Rat is a full-bodied stick that is not for the beginner.</p>
<p><strong>La Gloria Cubana Artesanos de Tabaqueros</strong></p>
<p><strong></strong><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/la-gloria-cubana.png"><img class="alignnone size-full wp-image-219" title="La Gloria Cubana Artesanos de Tabaqueros" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/la-gloria-cubana.png" alt="" width="300" height="96" /></a></p>
<p>This is an unusual cigar, whose first third is a Connecticut shade-grown wrapper, and whose remainder is Sumatra wrapper.  It’s that split that really hooked me.  After lighting, most full-bodied cigars exhibit some harshness on the palette.  This stick tones that down with that Connecticut shade-grown up front.  From there, the flavor matures throughout the whole cigar, and the Sumatra really shows itself.  These guys come in a variety of size, but I like the 6 inch by 54 ring gauge.</p>
<p><strong>Zino Z-Series (654T)</strong></p>
<p><strong></strong><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/zino-platinum.png"><img class="alignnone size-full wp-image-218" title="Zino Z-Series Platinum (654T)" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/zino-platinum.png" alt="" width="300" height="106" /></a></p>
<p>Davidoff cigars always have flawless construction.  I enjoy a Special T when I’m in the mood for something more on the mild side, that has a lot of flavor.  When I was introduced to the Zino Z-Series, in a beautiful maduro Dominican wrapper, I couldn’t pass it up.  At 6 inches by 54 ring gauge, the rest of the build is a mix of Peruvian binder and Nicaraguan filler.  This is a full-bodied cigar that produces ample creamy smoke.</p>
<p><strong>Macanudo Vintage Maduro 1997</strong></p>
<p><strong></strong>Macanudo is a brand that I don’t generally smoke in the United States.  I find them sub-par in construction and flavor to their Cuban counterparts.  At 6 inches by 54 ring, this one however comes in a fancy metal band that shines against the maduro Connecticut wrapper.  And it’s a good thing that it comes in a metal band, because you will want to smoke it to the point of burning your finger.  While I have still had problems with construction from time to time, the full-bodied characteristics and creamy smoke produced by the cigar simply shouldn’t be missed.</p>
<p><strong>Montecristo Sublimes Edicion Limitada 2008 (Cuban)</strong></p>
<p><strong></strong><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/montecristo-sublime.png"><img class="alignnone size-full wp-image-217" title="Montecristo Sublimes Edicion Limitada 2008" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/montecristo-sublime.png" alt="" width="300" height="126" /></a></p>
<p>Should you make your way out of the United States, have access to Cuban cigars, and can find this limited edition cigar from Montecristo, it is worth the price-tag (between $17 USD and $24 USD).  A formidable stick at 6.5 inch by 54 ring gauge, it will take you some time to get through &#8211; and will leave even the most experience smoker with a considerable buzz.  I found this at Boisdale of Belgravia where there is a “comfortable outdoor smoking area” (<a title="Where to Smoke" href="http://www.cigars.co.uk/where-to-smoke">COSA</a>) on the top floor (<a title="COSA Directory" href="http://www.cigars.co.uk/store_pdf.php">download</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/12/cigars-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build a Web Socket Server</title>
		<link>http://blog.kevinhoyt.com/2011/12/build-a-web-socket-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=build-a-web-socket-server</link>
		<comments>http://blog.kevinhoyt.com/2011/12/build-a-web-socket-server/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 19:53:46 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=205</guid>
		<description><![CDATA[It is a little-known feature of Adobe AIR that you can build and publish applications using a web standards-based workflow.  That’s right, take an “index.html” add some “mycode.js” and turn it into an application to be deployed as a desktop application.  This feature has actually been there since the beginning, and comes with all fashion [...]]]></description>
			<content:encoded><![CDATA[<p>It is a little-known feature of Adobe AIR that you can build and publish applications using a web standards-based workflow.  That’s right, take an “index.html” add some “mycode.js” and turn it into an application to be deployed as a desktop application.  This feature has actually been there since the beginning, and comes with all fashion of fun and interesting API.  One of those APIs is the ability to create a raw socket server.  With this in mind, I couldn’t pass up on the opportunity to implement a Web Socket server with JavaScript.</p>
<p><strong>About Web Sockets</strong></p>
<p>Web Sockets have actually been under development as a specification for a few years.  The initial draft of the “Hixie” specification dates back to 2009, and made it through 76 iterations before recently giving way to the “Hybi” specification.  That specification for Web Sockets dates back to early 2010, and is now RFC-6455 &#8211; or essentially the path forward for implementing Web Socket functionality on the server.</p>
<p>In the early days there was a fair amount of contention around how exactly to make the connection to the server securely.  Both the Hixie and Hybi approaches use HTTP to make the opening request.  The Hixie approach focused on using various hashes in the headers to confirm a secure connection.  This created a lot of complexities in the client/server handshake.  The Hybi approach simplifies the handshake considerably, and puts security emphasis on the actual messages themselves.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/IxXO27CdSjU" frameborder="0" allowfullscreen></iframe></p>
<p><strong>Creating a Socket Server</strong></p>
<p>As you might expect, to create a socket server with AIR, you use the class ServerSocket.  You can instantiate the class, set up your listeners for incoming connections, and bind to a specific IP address and port.  When you are ready to start handling connections, you call ServerSocket.listen().</p>
<p><script src="https://gist.github.com/1503885.js?file=server-setup"></script></p>
<p>The main event listener to be aware of at this point is the connection from a client.  This takes the form of ServerSocketConnectEvent.CONNECT.  The event object that comes along with that has a “socket” property that is a reference to the client.  Since you may want to send messages from the server to the client (the whole point of Web Sockets really), you probably want to keep track of those connections.  I push the reference into an Array called “connections”.</p>
<p>Getting a connection is one thing, but then you will want to handle incoming data.  In the case of Web Sockets, this incoming data might be messages from the client, or at the very beginning, the handshake that says the server accepts Web Socket connections in the first place.  Incoming data happens on an event called ProgressEvent.SOCKET_DATA.  The event that goes along with it carries the associated data being sent from the client.</p>
<p><strong>Handshake</strong></p>
<p>The Web Socket handshake starts off with an HTTP GET request.  This is different from how the subsequent data messages are handled, so it provides a good point to determine what it is that the client actually wants from the server.  I decided to handle this point of differentiation by reading the first byte and determining if it was the letter “H” or “76” as an integer.  If it is the letter “H” then the client is trying to establish the connection, and we can further the handshake process along.</p>
<p>While Hybi simplifies the headers needed to make the handshake, the headers themselves are still important.  At this point you can read in all the incoming data, and parse out the headers.  The specific header you are most interested in accessing is the “Sec-WebSocket-Key” header.  This header contains a randomly generated string.  Per the specification, you are required to append a specific GUID to that string, then perform a Base-64 SHA-1 hash on the resulting string.</p>
<p><script src="https://gist.github.com/1503908.js?file=websocket-connection-handler"></script></p>
<p>Once you have this hashed value, you are required to return it as part of the HTTP response.  The first header in the HTTP response indicates that you want to switch protocols from standard HTTP.  The second header tells the client that you are switching to the Web Socket protocol.  The third header states that this is an upgrade action.  And finally, the “Sec-WebSocket-Accept” header sends the resulting hash from the previous operation.</p>
<p>Once you’ve sent the HTTP response, assuming you have hashed the incoming value correctly, a connection is established and the handshake process ends.  From here on out, incoming data takes the form of messages.  And of course you can send outgoing messages from the server as well.  We will dig into those details next.</p>
<p><strong>Incoming Messages</strong></p>
<p>Since we’ve established that only the handshake starts with “H” and that we’d not have incoming messages if the handshake had failed, we can assume new incoming data is messages.  Data messages can be a variety of data types, to permit clients that aren’t browser-based.  For example, there is an option to send binary messages.  Early work on binary support in JavaScript is happening, but for now I’m going to focus on text messages.</p>
<p>Messages are passed using a concept called “framing” which can commonly be found in other protocols.  In this case, the first four bits (yes, bits) tell the server if this is a single message, or the continuation of a longer message.  For this example, I’ll be sending single messages at a shot from the client to the server, so these bits will always be “1000” and I can move on to getting more information about the message itself.</p>
<p><script src="https://gist.github.com/1503931.js?file=websocket-message-handler"></script></p>
<p>The next bits of the incoming message data represent the data type for this message.  Since I’m looking for text messages, I’m looking for the bits “0001”.  You might be wondering how you get at bits if binary support isn’t part of JavaScript just yet.  While there’s more to this story that I’ll cover in a moment, the quick way to get at the bits is through string manipulation.  You can read the incoming data, treat it as a string with the conversion radix of 2 (binary) and then look at the second chunk of four characters.</p>
<p>Oddly enough the data type bits can also denote if the client wants to close the connection.  If that is the case, the bits of this second chunk of data will be “1000”.  In that case, we will use Array.splice() to pull that particular client from our array of monitored clients.  From there we will close that connection as well, before letting it be garbage collected down the road.</p>
<p><strong>Data Masking</strong></p>
<p>Continuing down the path of this being a text message, we will next want to know if the data was masked.  In the case of messages coming from the client, in the case of Web Sockets, that bit will always be “1” (true).  All messages from the client to the server get masked.  We will come back to this in a moment.</p>
<p>The next seven bits indicate the size of the data that is being sent along from the client.  Note that a message may be longer than what seven bits can handle (125 characters), and the specification accounts for this by using the value of “126” to indicate that these seven bits, and the next 16 bits are the payload size.  If you need longer still, you will get a value of “127” which means these seven bits and the next 64 bits.  For this example, all my messages will be less than 125 characters, so we take those seven bits to determine the size of the payload.</p>
<p><script src="https://gist.github.com/1503950.js?file=websocket-masking"></script></p>
<p>You might have noticed at this point that there’s some JavaScript syntax that you don’t normally see around handing bytes.  It turns out that AIR provides binary manipulation APIs for you to use in JavaScript.  This API may or may not reflect the ongoing JavaScript work around binary support, so take it with a grain of salt.</p>
<p>The next four bytes are the actual mask for the payload data itself.  And then the next bytes are the actual payload data itself, where the number of bytes to read comes from the previous operation.  If you didn’t already feel a little confused, this is where things can get a bit sticky.  Masking bytes are a way of shifting the payload data bytes around such that the message itself retains some security integrity.</p>
<p>The next operation then is to unmask the payload data.  To do this you essentially walk through the bytes of the payload data and shift their values using the bytes of the masking key.  For each byte of the payload data, you will increment the masking byte that you use.  When you’ve reached the fourth masking key byte, you start back at the first masking key byte, and so on until the payload data has been unmasked.  Now you have the actual message value and can figure out what the client wants from the server.</p>
<p><strong>Outbound Messages</strong></p>
<p>Sending messages also relies on data framing, but luckily messages from the server to the client do not have to be masked, which makes the process of sending a message much easier to handle.  From our previous walkthrough, we know that the first four bits of the framing are “1000” for a single message.  We also know that we will be sending a text message, so the next four bits are “0001”.  A byte consisting of “1000 0001” is the equivalent of “129”, so I send that byte right across.</p>
<p>Again, without the requirement of masking messages coming from the server, the next bits will be “0000”.  That is to say that there is no masking (zero on the first bit), and therefore no masking key is needed so zero from the remaining seven bits.  From there we can write a byte indicating how long our response message will be.  And then finally, the actual payload data bytes going back to the client.</p>
<p><script src="https://gist.github.com/1503962.js?file=websocket-message-send"></script></p>
<p>Of course being able to construct a message is one thing, but knowing where to send that data is another.  That is why we kept track of the clients as they were connecting.  For this example, I am sending random numbers back to the client at a high rate (every 50 milliseconds).  Every time that interval hits, I iterate through the connected clients, and send along the randomly generated number.</p>
<p><strong>Extras</strong></p>
<p>Because I want to ensure that I only send messages along to the clients that are currently interested in getting them, I also keep an array of the various states of the connected clients.  Clients can stay connected and choose not to receive messages for the time being.  This also sets up the foundation to potentially send entirely different message to different clients.</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/GpQ7jwHbUdw?feature=player_embedded" frameborder="0" allowfullscreen></iframe></p>
<p>Fellow Adobe Developer Evangelist, <a href="http://www.tricedesigns.com/2011/12/20/toying-with-realtime-data-web-sockets/" title="Real-Time Data with Web Sockets">Andrew Trice</a>, covers this situation very nicely in his write-up on the topic.  If this is a scenario you are interested in for your application, I highly suggest that you take a look at his example code.  Andrew also takes the next step on abstracting all the connection code and client management.  Definitely a great read for those interested in the topic.  Andrew has also posted his version on GitHub if you want to take a shot at the code yourself.</p>
<p><strong>Conclusion</strong></p>
<p>There you have it, a Web Socket server implemented with JavaScript on Adobe AIR.  While it is a fun exercise to truly understand the Web Socket specification, and while it could serve as the basis for your own server, there are many other great open source options out there.  I’ve posted this code on <a href="https://github.com/parkerkrhoyt/AIRWebSocket" title="AIR Web Socket on GitHub">GitHub</a> and will likely iterate over time, but I encourage you to check out the other options as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/12/build-a-web-socket-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Animating Web Socket Data</title>
		<link>http://blog.kevinhoyt.com/2011/12/animating-web-socket-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=animating-web-socket-data</link>
		<comments>http://blog.kevinhoyt.com/2011/12/animating-web-socket-data/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 21:58:02 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Creative]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=193</guid>
		<description><![CDATA[Over the years I have learned many things about why companies build applications.  There is the standard e-commerce site for example, which allows a company to sell its goods to a broad audience they may have never originally been able to reach.  Behind the firewall of an e-commerce site then is typically a dashboard application, [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years I have learned many things about why companies build applications.  There is the standard e-commerce site for example, which allows a company to sell its goods to a broad audience they may have never originally been able to reach.  Behind the firewall of an e-commerce site then is typically a dashboard application, which allows managers and marketers to watch purchasing trends and learn how to execute better in the future.</p>
<p>Historically, however, this has been a job of refreshing the data occasionally to see the latest.  This lag can introduce missed opportunities for the business &#8211; especially when the data being monitored relates to a single event (e.g. special sales).  With Web Sockets, this data can now become real-time information, and allow for more immediate decision making.</p>
<p>The subsequent question then becomes how to best visualize that data to provide the necessary information.  This is a whole area of research, but one thing I have found that always puts a smile on executives&#8217; faces is animation.  Animating data is a fairly basic programming task once you know how to do it, but if you are new to this world of real-time data, you might dismiss it as an extra, when it is really a low-hanging fruit to a dazzling win.</p>
<p><strong>Web Socket Connection</strong></p>
<p><strong></strong>The first step to visualizing real-time data is understanding how to access the real-time data in the first place.  Luckily, web standards are here to save the day with Web Sockets.  This specification has been in a working state for years, but has recently moved on to the “request for comments” (RFC) stage.  This means it is unlikely to change significantly moving forward, and that you can start leveraging it in your projects.</p>
<p>And to be sure, the only parts that have changed at all in the past year have been around the server implementation and handshake details, that you the web developer don’t need to think about.  The client API you implement in JavaScript from the browser has been baked for some time.</p>
<p>From JavaScript, you will find a new class to use named WebSocket.  This is a first-class data type along the lines of String, Number, Math, etc.  When you instantiate the class via the “new” keyword, you must pass the IP and port to which the socket will connect.  Per the specification, the URI prefix of “ws” should be used (as opposed to “http”).  At the end of the day however, Web Sockets are an upgrade to the HTTP protocol that happens during the handshake.</p>
<p><script src="https://gist.github.com/1503484.js?file=instantiate-websocket"></script></p>
<p>Note that as soon as you instantiate the class, the process of connecting begin.  If you are interested in knowing when you are officially connected, the WebSocket class fires an “onopen” event, which you can map to a function.</p>
<p>There is also the corresponding “onclose” event for when the connection is closed.  Keep in mind here that unlike HTTP, for which the connection is terminated once all the data has been delivered, that Web Sockets are an open connection.  This connection can be closed on the client by calling the WebSocket.close() method, but it can also be closed by the server for any number of reasons (e.g. security concerns).</p>
<p><strong>Web Socket Messages</strong></p>
<p><strong></strong>Web Sockets have the ability to handle a variety of types of data in anticipation that connections may not always come from the browser.  For example, the specification allows for binary messages.  JavaScript is rapidly evolving however, and there is some hope for binary support in the language in the not too distant future.  For now you will be limited to text messages.</p>
<p>Regardless of the data type, now or in the future, sending a message is as easy as calling WebSocket.send() and passing along the data you want to go across the wire to the server.  As an example, this could be valuable for telling the server that you want to add additional data to be monitored, or that your application is in a state to really only be interested in a subset of a larger data feed.</p>
<p>I’ve been working with a fellow Adobe Developer Evangelist, Andrew Trice, on this topic and he has a <a href="http://www.tricedesigns.com/2011/12/20/toying-with-realtime-data-web-sockets/" title="Real-Time Data with Web Sockets">great example</a> of how this might work, when it might be important, and how to implement the details.</p>
<p><iframe width="640" height="360" src="http://www.youtube.com/embed/GpQ7jwHbUdw?feature=player_embedded" frameborder="0" allowfullscreen></iframe></p>
<p>Getting messages is a matter of handling the incoming event “onmessage”, which gets passed an event object with many interesting properties.  While those properties still seem to vary slightly per implementation, the “data” property on that object is what we will be interested in accessing for the purposes of this example.</p>
<p><strong>Some Charting Options</strong></p>
<p><strong></strong>The area of canvas-based charting has seen explosive growth in the past year alone.  There are a number of great options that can cater to your specific needs.  One word of caution here is to find the charting abilities that best suit your needs, and that this may not be the biggest, baddest charting framework on the block.  Especially in the context of delivery to tablets, sometimes the closer you can get to the basic the better off you will be &#8211; especially in terms of performance.</p>
<p>A few years ago, when I start looking into charting options for my projects, I found that PlotKit worked wonderfully.  It has a great look and feel right out of the box, thus providing a great user experience with very little effort.  PlotKit however hasn’t been updated for a long time.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/plotkit.png"><img class="alignnone size-medium wp-image-195" title="Example PlotKit Rendering" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/plotkit-300x225.png" alt="Blue bar chart using PlotKit" width="300" height="225" /></a></p>
<p>Another charting library I have used in the past, and that I will use for this example, is RGraph.  The RGraph API reminds me a lot of NET syntax, so it may be more approachable to programmers, but I’ve also found it harder to get a polished look and feel out of the available customization properties.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/rgraph.png"><img class="alignnone size-medium wp-image-196" title="Example RGraph Rendering" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/rgraph-300x224.png" alt="Red bar chart rendered with RGraph" width="300" height="224" /></a></p>
<p>And if you are jQuery-inclined, you might look at jqPlot.  This library strikes a nice balance between features and customization, and in the classic jQuery approach, it gets you started with minimal effort and flexes its customization features by exposing tons of features after the fact.  Again, however, when you consider performance on mobile devices, any library that abstracts another should be tested thoroughly.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/jqplot.png"><img class="alignnone size-medium wp-image-197" title="Example jqPlot Rendering" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/jqplot-300x161.png" alt="Teal bar chart rendered with jqPlot" width="300" height="161" /></a></p>
<p><strong>Animating Charts</strong></p>
<p><strong></strong>In order to animate charts, you’re going to want to first figure out how much data you can reasonably display on the screen.  This could be adjusted by the user via the user interface down the road, but you will want to find a happy medium as a starting point.  For the purposes of this example, I will assume that we want to show 100 data points at any given time.</p>
<p>Keep in mind that when animating data, each element also represents how much history the user can view.  Sometimes more data isn’t necessarily better data.  The human mind needs to be able to digest what it is seeing.  That may be more or less than 100 data points for your use-case.</p>
<p>From a programming perspective, this means setting up an Array of 100 elements in a scope that can be accessed by other parts of your code.  When a new message arrives, get the data point(s) you are interested in visualizing, and then Array.splice( 0, 1 ) the first element off the array, and Array.push( event.data ) onto the end.  Then you want to redraw the data.</p>
<p><script src="https://gist.github.com/1503490.js?file=websocket-message-handler"></script></p>
<p>This is an interesting aspect of working with Canvas.  Once something has been rendered to the canvas, it becomes part of the overall bitmap data on the screen.  There are no discrete display objects to work with independently.  Even if your chosen library abstracts data points in a manner such that you can work with them directly and have the chart updated, chances are that it is redrawing the vast majority of the canvas space anyways.</p>
<p>Whether you are working with discrete points, or using the array method I show in the above code snippet, the important part is in moving the data down the chain.  You can’t just add onto the end.  You want to keep the same number of data points and change the values they reflect directly.  Over time, this will create the illusion of the data sliding in from the right to the left &#8211; also known as animation.  To move the chart the other way, put the new data in at the first element (zero) and splice off the end of the array.</p>
<p><strong>Conclusion</strong></p>
<p><strong></strong>This really just scratches the surface of the types of data visualizations that are possible with this technique.  Bar charts, lines, high-low points, and even pie charts render some visually impressive results with relative ease.  And again, keep in mind that the experience of the user matters.  This few extra lines of code, makes a big impact on the user, and in my experience, most marketers will love you for the effort over forcing them to refresh the data, or wait for updates of HTTP polling.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/12/animating-web-socket-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Child&#8217;s Play</title>
		<link>http://blog.kevinhoyt.com/2011/12/childs-play/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=childs-play</link>
		<comments>http://blog.kevinhoyt.com/2011/12/childs-play/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 11:45:38 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Creative]]></category>
		<category><![CDATA[Presentations]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=162</guid>
		<description><![CDATA[Back at the beginning of November, I had the opportunity to present on “Exploring Canvas” at HTML5 Live in New York, NY.  During the presentation I covered a variety of canvas topics ranging from the basics, such as how to get started, to more open-ended experimentation such as red/blue 3D rendering.  It was a fun [...]]]></description>
			<content:encoded><![CDATA[<p>Back at the beginning of November, I had the opportunity to present on “Exploring Canvas” at HTML5 Live in New York, NY.  During the presentation I covered a variety of canvas topics ranging from the basics, such as how to get started, to more open-ended experimentation such as red/blue 3D rendering.  It was a fun topic, with a fun audience, but the slides were especially fun to build since I had my seven year old daughter help me design them.  I have since gotten a lot of questions about how I built the slides, so I thought I would spend a post talking about the process.</p>
<p>I should note up front that I have often included my daughter in my presentations &#8211; especially around multi-screen and physical computing. The original idea popped into my head when I needed an additional set of hands to interact with content, while also filming at the same time.  I work in a remote office with no other Adobe employees around, so it is not like I can just grab somebody from the next cube over.  My wife is notoriously camera shy, so that left one option, my daughter.</p>
<p>These days at conferences, I will often get questions around my content, as expected, but inevitably, somebody will ask about when I have new content coming out that includes my daughter.  She has become a bit of a celebrity in that respect, which is great because she loves helping her dad with work.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/getting-help.jpg"><img class="alignnone size-full wp-image-164" title="Getting Help" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/getting-help.jpg" alt="Paige drawing the canvas heading slide" width="300" height="502" /></a></p>
<p><strong>The Slides</strong></p>
<p><strong></strong>I actually build the entire presentation before involving my daughter at all.  I work the content over and over until I have a cohesive presentation that won’t be changing much.  I’ll generally add to the sections all the way up until the presentation itself, but the section headers themselves will reach a point where they stop changing.  This is important, because the process of having my daughter draw the slides takes a considerable amount of time.  Changing major sections would be costly.</p>
<p><strong>The Artwork</strong></p>
<p><strong></strong>Once I have the presentation mostly refined, or at least refined enough to where the section headers won’t be changing, I pull out a sheet of 8.5” x 11” paper for each major heading.  Think of a sheet of paper as the screen for a specific header slide.  It’s not an exact representation of the aspect ratio, but it is close enough.  As they say in the video business “we will fix it in post”.  That is to say that we can massage the sizing once the artwork is finished.</p>
<p>First, layout the sheet of paper horizontally (long side across the top).  Then, using a ruler, measure out two lines on the paper roughly where you would normally put a slide title.  If you have a subtitle, you might adjust the lines accordingly.  Draw the lines very lightly &#8211; they are simply serving the purpose of helping you keep things level.  Then on those lines, in big letters, write the slide heading.  Again, be light here.  You are not interested in the lines any more than to provide a guide for your eager helper.</p>
<p>At this point, I turn it over to my daughter.  I tell her to trace the letters, and to do it somewhat sloppy (which she loves since to her staying in the lines is such a drag).  The sloppiness lends to better readability.  The thicker the lettering, the more legible the words will be on the screen in a formal presentation setting.  Once she has finished the letters, we think up a theme for the slide.  For example, since I was going to be in New York, NY for the presentation on “Exploring Canvas” I thought a New York skyline would be a good fit.  For another slide, since it was close to Halloween, my daughter wanted to draw witches and pumpkins.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/drawing-slide.png"><img class="alignnone size-full wp-image-163" title="Drawing Slide" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/drawing-slide.png" alt="Scanned version of paper slide" width="470" height="366" /></a></p>
<p>Try to have your helper draw a variety of objects.  Don’t limit yourself to what you think will fit best on the slides.  Let them really go at it.  The more options you have the better.  I found that on any given slide, I would use maybe three or four out of the ten different things my daughter would draw.  Also, when they are drawing, try to have them stay clear of the letters of the slide heading.  This will make it easier to fit the content to the slide down the road.  I also found it helpful to have a kind of factory line.  My daughter would finish one slide, and while she was starting on the next slide, I would start digitizing the work.</p>
<p><strong>Some Assembly Required</strong></p>
<p><strong></strong>Once a given slide is complete, I scan it into the computer using a fairly high DPI setting (300 dpi or better).  This gives you more pixels to play with when it comes to sizing the content.  It also lets you clean things up easier at a high resolution, and then scale it down to fit with less artifacts from the cleaning process itself.  For example, if you are using crayon, there will inevitably be flakes of wax you don’t want.  Photoshop’s “Content Aware Fill” makes quick work of those.</p>
<p>I found that most of the time, despite being told to steer clear of the letters, that my daughter would inevitably get carried away and end up drawing into them.  Here a little work with the Photoshop “Clone” tool goes a long way.  I will set the original point on a blank piece of the paper, and make really soft edges on the clone area.  Then I can clone the paper over errant scribbles.  If you have scanned in the artwork at a high enough resolution, then when you scale it down to fit your slides, these fixes will be imperceptible.</p>
<p>Once the artwork has been cleaned up, I use the “Polygon Lasso Tool” to trace around the parts and pieces of the slide.  I keep it fairly random to emulate the look and feel of a child cutting out the words with clunky safety scissors.  I then paste the cut out objects into my slides.  From there, if I have scanned at high enough resolution, I can continue to scale, skew and rotate the artwork individually, without loss of quality of the artwork itself.  Before long the final product emerges.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/drawing-finished.png"><img class="alignnone size-full wp-image-165" title="Finished Drawing Slide" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/drawing-finished.png" alt="" width="450" height="338" /></a></p>
<p><strong>Finishing Touches</strong></p>
<p><strong></strong>For my purposes, I found that the artwork itself, when placed on a blank white slide, lost a lot of the character that I wanted.  There was something missing.  After thinking about it for a while, I realized that it was the texture of the paper itself that was missing.  The computer rendering was too perfect.  To solve this problem, I crumpled up a blank slide, er, a piece of paper, and scanned it.  From there a little color correction brought out the right one that I was trying to achieve.  Then I simply plopped that in as the background to each heading slide (again stretching and scaling to fit the aspect ratio).</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/slide-background.png"><img class="alignnone size-full wp-image-166" title="Crumpled Paper" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/12/slide-background.png" alt="" width="450" height="351" /></a></p>
<p>When I did this, I found that the artwork became lost in the texture of the paper.  Now I had the inverse problem.  To bring the artwork back out of the textured paper, I applied a slight drop shadow to each object.  Now I had the final product.  Of course, once you have had your helper work so hard, it is important to show them the results of the work, so fire up the presentation and show them their handiwork inside the computer.  I found that my daughter would occasionally have recommendations as to pieces of her work that were missing that she wanted to include.  If at all possible, I tried to accommodate &#8211; she is, after all, the real star of the show.</p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/10574171" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="425" height="355"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/12/childs-play/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iBond</title>
		<link>http://blog.kevinhoyt.com/2011/11/ibond/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ibond</link>
		<comments>http://blog.kevinhoyt.com/2011/11/ibond/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 21:14:45 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=154</guid>
		<description><![CDATA[As the end of our London-themed mobile application tour rolls around, we turn to the world famous Mr. Bond, James Bond.  One of the features not provided for by mobile browsers yet is the ability to take a picture using the device camera.  This of course makes it hard for James to use a web [...]]]></description>
			<content:encoded><![CDATA[<p>As the end of our London-themed mobile application tour rolls around, we turn to the world famous Mr. Bond, James Bond.  One of the features not provided for by mobile browsers yet is the ability to take a picture using the device camera.  This of course makes it hard for James to use a web standards-based application to take spy photos when he’s off saving the world.  Luckily, as we reach into Q’s bag of tricks we can tap into the device APIs offered by Mr. Gap, PhoneGap.</p>
<div id="attachment_155" class="wp-caption alignnone" style="width: 330px"><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/ibond-screen.png"><img class="size-full wp-image-155" title="iBond" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/ibond-screen.png" alt="" width="320" height="480" /></a><p class="wp-caption-text">Bond or Bono?</p></div>
<p>From the point of conceiving all four demonstration ideas, through development, and to the point of delivery, which included a trip from the United States to London, England, was four days.  Four applications in four days was an ambitious goal to be sure, but PhoneGap and web standards made it happen.</p>
<p>PhoneGap and web standards didn’t however, give me the boost in creative energy I need to finish off the second half of this application.  I never really could land on a look I liked for the buttons.  I tried caffeine, beer, cigars, and even walking around picturesque London for a few hours, but my creative juices were tapped.</p>
<p>I really wanted to fill the buttons with the texture of the handle from James Bond’s preferred weapon, the Walther PPK.  Unfortunately, I couldn’t find large enough pictures to accomplish that easily, and my Photoshop skills were letting me down in a big way after coming over the Pacific Ocean. Point being that while I like how most of the application looks, I can’t stand the buttons.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/1972_Walther_PP.jpg"><img class="alignnone size-full wp-image-156" title="Walther PPK" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/1972_Walther_PP.jpg" alt="Walther PPK" width="320" height="235" /></a></p>
<p><strong>Device Camera Capture</strong></p>
<p><strong></strong>The application presents two button for James to use.  The first button presents 007 with the opportunity to take a picture using the device camera.  When tapped, a call to “navigator.camera.getPicture()” will present the device UI for taking a picture.  The call takes a success function, a failure function, and options as arguments.</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#camera&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchstart&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/camera.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; navigator.<span style="color: #660066;">camera</span>.<span style="color: #660066;">getPicture</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#photo&#8217;</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;data:image/jpeg;base64,&#8217;</span> <span style="color: #339933;">+</span> data <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;visibility&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;visible&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#camera&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/camera.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> error <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;Error&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; destinationType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">DestinationType</span>.<span style="color: #660066;">DATA_URL</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; sourceType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">PictureSourceType</span>.<span style="color: #660066;">CAMERA</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; allowEdit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; targetWidth<span style="color: #339933;">:</span> <span style="color: #CC0000;">260</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; targetHeight<span style="color: #339933;">:</span> <span style="color: #CC0000;">435</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp;<br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>There are a number of options that you can provide, which can make using this part of the PhoneGap API a little tricky.  In my case, I wanted to get the image data itself back after the picture was taken.  Depending on the device, and the resolution of the camera, this might be more data than can easily be passed back from the device into the PhoneGap application.  I didn’t have a problem, but it is something to be aware of during development.</p>
<p>The alternative option then is to get a reference to a file on disk where the image is stored.  From there it is up to you to manage if that file gets a life longer than that of the application, where it lives, etc.  Once you’ve taken care of the details, you can change the “src” attribute of an IMG tag to show the image from disk, set the image as background to a DOM element using CSS, or even simply process the image bytes further for whatever additional data it is that you might be mining (e.g. Exif).</p>
<p>From there, I specified that the source was to be “Camera.PictureSourceType.CAMERA”, which is the notation for the device camera.  The other option would be “Camera.PictureSourceType.PHOTOLIBRARY”, which we will cover in a moment.  Along the way, you can tell the device to allow the user to edit the picture they’ve taken, should the device support image editing.</p>
<p>One of the nice things that PhoneGap does for you is image sizing.  This would otherwise be horribly pixelated if the full image was smashed down into a smaller version by force, or conversely take forever to process making a thumbnail directly with JavaScript.  PhoneGap allows you to specify the dimensions you’d like the returned file to fit in, and will even respect the aspect ratio (e.g. it won’t stretch or distort the image to fit the specified sizing).</p>
<p>When the picture has been taken, the success function you passed along will be called, and will contain the raw image data, Base-64 encoded.  This is actually pretty ideal because from there you can pop it right into a canvas element for further manipulation, or feed it into an IMG tag as the source.</p>
<p><strong>Device Photo Album</strong></p>
<p><strong></strong>The other button on the user interface allows Mr. Bond the opportunity to select a picture he has already taken.  The code is almost identical with the exception of the aforementioned change in source type, and the addition of a media type.  The media type option allows you to make sure that, in the heat of a fight with Oddjob or Jaws, James doesn’t accidentally select a video from his photo album.</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#roll&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchstart&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/roll.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; navigator.<span style="color: #660066;">camera</span>.<span style="color: #660066;">getPicture</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> data <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#photo&#8217;</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;data:image/jpeg;base64,&#8217;</span> <span style="color: #339933;">+</span> data <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;visibility&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;visible&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#roll&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/roll.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> error <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;Error&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; destinationType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">DestinationType</span>.<span style="color: #660066;">DATA_URL</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; sourceType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">PictureSourceType</span>.<span style="color: #660066;">PHOTOLIBRARY</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; allowEdit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; targetWidth<span style="color: #339933;">:</span> <span style="color: #CC0000;">260</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; targetHeight<span style="color: #339933;">:</span> <span style="color: #CC0000;">435</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; mediaType<span style="color: #339933;">:</span> Camera.<span style="color: #660066;">MediaType</span>.<span style="color: #660066;">PICTURE</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp;<br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p><strong>Conclusion</strong></p>
<p><strong></strong>Being able to take a picture of something from within an mobile application, is all but considered a given these days.  I went to play a new tower defense game on my iPad the other day, and even it wouldn’t let me install without a front-facing camera.  While web standards move forward to make that a possibility in the future, PhoneGap is here to help you today.  Even if James is otherwise preoccupied chatting with Miss Moneypenny, or getting his groove on with the ever-so-lovely Bond Girls.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/11/ibond/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tardis Finder</title>
		<link>http://blog.kevinhoyt.com/2011/11/tardis-finder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tardis-finder</link>
		<comments>http://blog.kevinhoyt.com/2011/11/tardis-finder/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 16:54:01 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=141</guid>
		<description><![CDATA[Poor Doctor Who.  Always running around time and space, saving the universe &#8230; In a phone booth.  Well, okay, it’s not actually a phone booth, it is a “time and relative dimension in space” machine, or &#8220;TARDIS&#8221; for short.  But what I want to know is how, in all these different places, does The Doctor [...]]]></description>
			<content:encoded><![CDATA[<p>Poor Doctor Who.  Always running around time and space, saving the universe &#8230; In a phone booth.  Well, okay, it’s not actually a phone booth, it is a “time and relative dimension in space” machine, or &#8220;TARDIS&#8221; for short.  But what I want to know is how, in all these different places, does The Doctor remember where he parked the Tardis?  I can’t remember where I park my car at the grocery store.  So in continuing the London-themed series of PhoneGap applications, and knowing that “there’s an app for that” I built Tardis Finder.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/tardis-finder.png"><img class="alignnone size-full wp-image-147" title="Tardis Finder" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/tardis-finder.png" alt="Screenshot of the Tardis Finder running" width="480" height="854" /></a></p>
<p>Tardis Finder is really a simple example of using the device compass from PhoneGap.  The code is actually pretty short and sweet.  It is also very similar to using the accelerometer.  You make a call to “navigator.compass.watchHeading()” and get a numeric identifier in return.  You can use that identifier at some later point to stop watching the compass, so keep it in a variable that will be around to reference.</p>
<div class='sniplrcode'><span style="color: #003366; font-weight: bold;">var</span> watchId <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span></p>
<p>watchId <span style="color: #339933;">=</span> navigator.<span style="color: #660066;">compass</span>.<span style="color: #660066;">watchHeading</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> heading <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#compass&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;-webkit-transform&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;rotate( &#8216;</span> <span style="color: #339933;">+</span> heading.<span style="color: #660066;">magneticHeading</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&#8216;deg )&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> error <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;Error&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; frequency<span style="color: #339933;">:</span> <span style="color: #CC0000;">100</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>And of course you pass a success and error function to the “watchHeading()” call, along with an option of how often to poll the compass.  The default frequency for polling the compass is every 100 milliseconds.  When the success callback is executed, you will get an object with a variety of properties around magnetic heading, true north, and more.  Support for the options varies widely depending on operating system, so generally speaking you will want to simply use magnetic heading.</p>
<p><strong>CSS3 Success and Failure</strong></p>
<p><strong></strong>In this example, I use the heading value, which will be between 0 and 360 to rotate the compass image that many degrees.  This is done using the CSS3 transform “rotate()”, which despite being nearly 600&#215;600 performs admirably well on my relatively dated Droid X.</p>
<p>You might notice that the compass has a slight drop shadow to it, and you might then assume that I use the CSS3 “box-shadow” attribute to apply that shadow.  And you’d be wrong.  It turns out that “box-shadow” works only on the containing box.  This would be fine if I wanted a drop shadow on a picture, but for the compass, which is round, it doesn’t come close to rendering the desired results.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/layered-v-css.png"><img class="alignnone size-full wp-image-143" title="Layered vs CSS3" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/layered-v-css.png" alt="Comparison of layering images or using CSS3 box shadow" width="470" height="180" /></a></p>
<p>To get around this, I separate the compass from its shadow &#8211; there’s one image for each, and I layer them on top of one another.  Positioned accurately, it looks like the compass has a nice, rounded, drop shadow.  I rotate the compass image, but not the shadow.  Thanks to transparent PNGs, this gives the desired result.</p>
<p><strong>User Interface Considerations</strong></p>
<p><strong></strong>You might notice that the compass doesn’t have a needle.  How do you know then what direction you are going?  Well, for one, if you are as smart as The Doctor, then you just know, but if you’re not, let me clue you in &#8211; the top of your phone, in the center, where the Tardis doors close, is the heading you are currently on.  Pretty intuitive right?  Maybe not, but maybe more than you think.</p>
<p>Once I had made the call to rotate the compass, I realized that if I had a needle, that it would essentially always be pointing towards the top of the application.  And to be fair, if I had the graphical skills to pull off a good looking needle, then I would have put it in there.  But the point remains that when it comes to compass heading you have two choices.</p>
<p>The first choice is to rotate the compass itself.  In which case, realistically, you should provide some fixed indicator (and if you come up with anything compelling, please send it over).  The second choice is to rotate the needle.  In this case, where the compass spills off of the screen, that wouldn’t work because you’d only know your heading about 180 degrees of the time.  So if you’re going this second route, size the user interface to include the entire compass on the screen.</p>
<p>You should also consider simply telling the user the heading value in a textual fashion.</p>
<p>I’m inclined to enjoy the second approach because to me, it more closely resembles how we actually use a compass.  You generally hold the compass fixed in front of you, with the top point directly perpendicular from your body.  The compass then is free floating and turns to always be pointing to the north.  Technically, you turn and the compass stays still, and that’s what happens in Tardis Finder.</p>
<p><strong>Operating Systems and Sensors</strong></p>
<p><strong></strong>The device I use to test my iOS applications is generally an iPod Touch.  The iPod Touch has no compass, so for this application, I targeted Android.  This brings up two interesting points.  The first is simply to check for the compass availability.  I haven’t covered the “error” blocks of most of these examples, but that’s where you’d catch that there is no compass sensor, and then take the appropriate alternative action.</p>
<p>The other interesting point is the viewport.  Despite the iPod Touch having a “retina” display of 640&#215;960, as I’ve noted in other posts, working with graphics that large can still result in sub-par performance.  For this reason, I generally design for a 320&#215;480 resolution, and let the operating system scale up the graphics.  And on iOS, this is done quite well with minimal, or altogether absent scaling artifacts.</p>
<p>With iOS, when targeting the smartphone form factor, I don’t even use a viewport.</p>
<p>Android on the other hand is nowhere near as forgiving, and it will try to scale up everything &#8211; even graphics sized for the exact resolution of a specific device.  This means that the “meta viewport” definition is really important.  Further, you can’t get away with just any viewport values either if you expect your graphics to fit the display precisely.  After a whole lot of trial and error, here is the viewport definition I used in Tardis Finder.</p>
<div class='sniplrcode'>&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, target-densityDpi=device-dpi&quot;/&gt;</div>
<p>With this definition in place, I am free to expect that one pixel in my design will equal one pixel on the device.  In the case of Tardis Finder, my 480 pixels across the top fills the display of my Droid X exactly.  And luckily many Android devices have 480 pixels across the top &#8230; But not all of them.</p>
<p>And then there is the horizontal dimension to consider as well.  Early Android devices had 480&#215;800 resolution displays.  The Droid X however has 480&#215;854.  And a more modern device like the Motorola Atrix has a 540&#215;960 resolution display.  This is clearly where CSS Media Queries would come into play.  I haven’t covered them here in the interest of sticking to PhoneGap features, but the bottom line is simply to test, test, test.</p>
<p><strong>Conclusion</strong></p>
<p><strong></strong>It never ceases to amaze me how something relatively simple can involve so much thought.  Here I’ve shown how to use the device compass via PhoneGap in a handful of lines of code.  But from there comes CSS considerations, UI consideration, device support considerations, resolution considerations and more.  Indeed a large percentage of the time of overall development for devices will ultimately be in testing.  Luckily, I’ve already done that footwork for the good Doctor, and now he can get back to saving the universe.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/11/tardis-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Blimey</title>
		<link>http://blog.kevinhoyt.com/2011/11/blimey/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=blimey</link>
		<comments>http://blog.kevinhoyt.com/2011/11/blimey/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 17:30:09 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=126</guid>
		<description><![CDATA[In this spin on the differences between British English and the English used by Americans, I’ll take you through recording an audio file with PhoneGap.  We will get a brush with the PhoneGap File API along the way there.  Having recorded your voice, we will then translate the audio file.  Well, okay, we won’t translate [...]]]></description>
			<content:encoded><![CDATA[<p>In this spin on the differences between British English and the English used by Americans, I’ll take you through recording an audio file with PhoneGap.  We will get a brush with the PhoneGap File API along the way there.  Having recorded your voice, we will then translate the audio file.  Well, okay, we won’t translate per se, as much as play back a pre-canned audio recording of a female computer voice tell us nice things about our presentation &#8211; and then some.  To get there we will use the HTML5 “audio” tag.  And just for good measure, we will take a quick look at using the PhoneGap Notification API.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/blimey.png"><img class="alignnone size-full wp-image-107" title="Blimey" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/blimey.png" alt="Screenshot of an audio recorder" width="320" height="480" /></a></p>
<p><strong><span style="color: #ff0000;">WARNING: There is some potentially offensive material in this tutorial.  If you find yourself sensitive to foul language, you may want to head on to somewhere else.  Continue reading at your own risk.</span></strong></p>
<p><strong>Request File System</strong></p>
<p><strong></strong>What?  A tutorial on recording audio starts with the PhoneGap File API?  You bet!  It turns out that PhoneGap won’t record a file unless there is something already on the file system to record the audio into.  The file on the system doesn’t need to have any content to it, and must have a “wav” extension.</p>
<div class='sniplrcode'>window.<span style="color: #660066;">requestFileSystem</span><span style="color: #009900;">&#40;</span><br />
&nbsp; LocalFileSystem.<span style="color: #660066;">PERSISTENT</span><span style="color: #339933;">,</span> <br />
&nbsp; <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <br />
&nbsp; <span style="color: #003366; font-weight: bold;">function</span> doAccess<span style="color: #009900;">&#40;</span> fs <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Got file access&#8217; );</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; fs.<span style="color: #660066;">root</span>.<span style="color: #660066;">getFile</span><span style="color: #009900;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; SOURCE<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; create<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; exclusive<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> fe <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; reference <span style="color: #339933;">=</span> fe.<span style="color: #660066;">fullPath</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fe.<span style="color: #660066;">createWriter</span><span style="color: #009900;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> writer <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Ready to write&#8217; );</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span style="color: #660066;">onwriteend</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;File written&#8217; );</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; writer.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216; &#8216;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> err <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;No access to file entry&#8217; );</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <br />
&nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> err <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;File system not responding&#8217; ); &nbsp;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>First up we will get a reference to the root of the file system.  This is done through calling the “requestFileSystem()” method, found on the “window” object.  We can tell the system that we want temporary or persistent storage.  Temporary content is removed when the application is closed.  We can also optionally tell the system just how much space we will need.  After that comes handlers for success and failure events.</p>
<p>Now that we have a reference to the file system, let’s get a file reference.  We do this by calling the “getFile()” method found on the root property of the file system object that is returned from the request call.  On this method call we tell the system the name of the file we are interested in getting.  Since we’ll be creating a file, name it whatever you like &#8211; just keep that name handy.  The options we will pass tell the system to create the file, and not to fail if the file does not exist.  Then, more callbacks for success and failure.</p>
<p>When we have successfully created the file, the callback gets a reference to the file entry itself.  Let’s store the full path of the file so we can easily access it later.</p>
<p>At this point we still haven’t told the file system what we intend on doing.  We have a reference to a file, and that’s about all it knows.  Next up then is to create a “file writer” by calling “createWriter()” on the file entry we got back from getting a file reference, from getting access to the file system.  Just like the rest of these calls, you pass success and failure callbacks to the “createWriter()” method call.</p>
<p>In the success callback of getting a file writer, you will get a reference to the writer itself &#8211; finally, we’ve made it.  Here let’s simply call “write( ‘ ‘ )” on that object.  Done.  And oh, by the way, you need to write at least something to the file in order for it to hang around.  In this case I’ve used a single space character.  A null space will not work.</p>
<p>If this seems like a lot to go through to write a file, I agree.  And I didn’t even mention the asynchronous calls that can result from the writing process itself.  The good news is that this isn’t PhoneGap obtuseness &#8211; it is by design.  Whose design?  As it turns out, like most of the PhoneGap APIs, this functionality maps to the W3C specification for file access.  The bad news then is that this is W3C obtuseness.</p>
<p>On the desktop, this asynchronous API is accompanied by a synchronous version, which is far more concise.  It turns out however, that PhoneGap proxies its calls to the device operating system.  Because you don’t want your user interface to hang while you’re waiting for the operating system to respond, these all pretty much have to be asynchronous, so that’s what PhoneGap gives us to use.</p>
<p><strong>Recording Audio</strong></p>
<p><strong></strong>Now that we have a file to record our audio to, the rest of this gets pretty easy.  The trickiest part here is first to make sure you grabbed that reference to the file we just created &#8230; Like I told you to do.  You did, didn’t you?  Cool.  Then the only other hard part, more time consuming than hard really, is in managing all the buttons you’re going to need.</p>
<p>You want to record, so you will need to provide a button for that.  However, once you’re recording, you probably want to let the user stop the recording as well.  That’s either another button, or a toggle version of the first button.  Once you’ve recorded the file, you’re probably going to want to let the user play it back to make sure you captured what they think you captured.  And once playing, you will want to stop the playback, and maybe even pause it.  That’s a few more buttons/states.  So like I said, it gets tedious.  The code to record and playback, however, is actually really easy.</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#record&#8217;</span> <span style="color: #009900;">&#41;</span><br />
.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchstart&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> media <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/record.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; <br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/stop.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><br />
.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchend&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/stop.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> media <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; media <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Media<span style="color: #009900;">&#40;</span> reference<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Got media&#8217; );</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> err <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Problems accessing media&#8217; );</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; media.<span style="color: #660066;">startRecord</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; media.<span style="color: #660066;">stopRecord</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; media.<span style="color: #660066;">release</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; media <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/record.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>PhoneGap provides a “Media” class for recording and playback using the native system resources.  As far as recording is concerned, I assume that if that object instance is null, then you want to record.  When the user hits the button to stop the recording, I do that for them, and then set the media instance back to null.</p>
<p>To get a Media object instance, use its constructor and pass that file reference from earlier.  As usual, you can also provide callbacks for success and failure.  The actual recording is done by calling “startRecording()” on your media object instance.  Conversely “stopRecord()” finishes the recording process.  In order to free up the resources consumed by the recording process, call the “release()” function on the Media object instance.</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#play&#8217;</span> <span style="color: #009900;">&#41;</span><br />
.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchstart&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> media <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/play.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/stop.down.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><br />
.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchend&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> media <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/stop.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; media <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Media<span style="color: #009900;">&#40;</span> reference<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; media.<span style="color: #660066;">release</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; media <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#play&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/play.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Problems accessing audio&#8217; );</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; media.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;assets/play.up.png&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; media.<span style="color: #000066;">stop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; media.<span style="color: #660066;">release</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; media <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>The way I’ve designed this block of code lets the user record repeatedly until they are satisfied with the fidelity of the audio to be translated.  To hear what they’ve recorded, I have provided a play button.  When that button is clicked, we head on back to that magic Media class.  This time however, we will want to use the success callback to know when the audio has finished playing.  From there we can free up the resources, and set the Media object instance back to null.</p>
<p>If the user wants to stop the playback before the end of the audio stream, that will be another button press.  I use a toggle here, so the audio is either ready to play back (stopped), or playing back.  If the audio is already playing back, then I assume the user wants to stop the playback if they tap the button again.  A call to “Media.stop()” does that, then we clean up after ourselves.</p>
<p><strong>Translation</strong></p>
<p><strong></strong>Okay, just so we’re on the level here, I’m not some crazy Ph D computer scientist.  I don’t actually know how to translate audio files.  I’m sure there’s some brain at Google that has that covered, but as for me, I’ll just play back some nice prerecorded audio files.  And each time you ask for a translation, the response seems to get more and more nice.  Eventually it gets downright gregarious, before finally just going off the edge.  You are warned (again).</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#translate&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchstart&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> phrases <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8217;1-great-presentation.mp3&#8242;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8217;2-really-liked.mp3&#8242;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8217;3-really-amazing.mp3&#8242;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8217;4-dirty-thoughts.mp3&#8242;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8217;5-have-baby.mp3&#8242;</span><br />
&nbsp; <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#response&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;&lt;source&gt;&#8217;</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; .<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;src&#8217;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&#8216;phrases/&#8217;</span> <span style="color: #339933;">+</span> phrases<span style="color: #009900;">&#91;</span>phrase<span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; .<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#response&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; loaded <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;response&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">load</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> phrase <span style="color: #339933;">==</span> <span style="color: #CC0000;">4</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; phrase <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> <br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; phrase <span style="color: #339933;">=</span> phrase <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></p>
<p>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#response&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;progress&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> audio <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;response&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> duration <span style="color: #339933;">=</span> audio.<span style="color: #660066;">duration</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> end <span style="color: #339933;">=</span> audio.<span style="color: #660066;">buffered</span>.<span style="color: #660066;">end</span><span style="color: #009900;">&#40;</span> <span style="color: #CC0000;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #006600; font-style: italic;">// Progress gets fired twice</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// Only want to play once</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> loaded <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">100</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; loaded <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> end <span style="color: #339933;">/</span> duration <span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">100</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// console.log( loaded ); &nbsp;</span><br />
&nbsp; <br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> loaded <span style="color: #339933;">==</span> <span style="color: #CC0000;">100</span> <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;response&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">play</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p>I wanted to compare and contrast the PhoneGap Media object with the HTML “audio” tag, so that’s what we’ll use for playback of these “translations”.</p>
<p>The first part of that is to have an audio tag in your HTML.  The HTML audio tag is an interesting one because it actually takes several “source” tags inside of it.  The idea is to tell the browser where it can find the file with various audio encodings.  The browser looks at the source specified in the first tag, and if it can’t play it, tries the next, and the next until eventually falling back to whatever else is left inside the audio tag.</p>
<p>When the button to translate the audio recording is pressed, I empty out any previously placed “source” tags.  Then I create a new “source” tag with the “src” attribute pointing to the MP3 file I want to play this time around.  Note that not all browsers support MP3, and I’m not accounting for that.  This example works on iOS, but not Android.  I could add that support by having additional encodings, and inserting the additional “source” tags.</p>
<p>In a lot of the documentation around the audio tag, you will see to call the “load()” method, and then the “play()” method, one right after the other.  I found this approach to deliver very mixed results on my iPod Touch.  Perhaps the desktop is quick enough to load the audio file and then immediately turn around and play it, but the iPod is not.  To get around this, I listen to the “progress” event from the “audio” tag.  When the file is completely loaded, I go ahead and play the audio via the “play()” method.</p>
<p>The problem I had here is that the “progress” event fires while the content is loading, but then again once it is completely loaded.  That means you get “Hey, I’m 100% loaded.” called twice.  To manage this I keep a variable around for the loading progress outside the scope of the “progress” event itself.  Kind of clunky, really.</p>
<p>I was surprised to find that there’s no “isPlaying” attribute on the “audio” tag.  There is however a “stalled” event for when content has stopped loading before all the file has been loaded.  Apparently some browsers will also not let you play the audio programmatically unless you’ve turned on the “controls” attribute.  Note to self, “audio” seems to still be very much a work in progress.</p>
<p><strong>Notification</strong></p>
<p><strong></strong>I’m not entirely sure why I even put this in here, and you might be wondering the same thing yourself.  “Why are notifications even in PhoneGap?  JavaScript has the ‘alert()’ method, right?”  Well, yes and no.  When you use the JavaScript “alert()” method inside a PhoneGap application, the title on the dialog will be “index.html”.  That’s not really ideal for an application.  And what about presenting more than just an “Okay” and “Cancel” button?  Or vibrating the phone?  Or just beeping at the user?</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/alert-comparison.png"><img class="alignnone size-full wp-image-133" title="Alert Comparison" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/11/alert-comparison.png" alt="JavaScript alert next to a PhoneGap notification" width="470" height="345" /></a></p>
<p>All of those features are really easy to use with PhoneGap.  Like most PhoneGap functionality, you will find a “notification” property on the “navigator” object.  From there you can alert, confirm, beep and vibrate to your heart&#8217;s content.  In this application I use a “confirm()” call when the “Bob’s Your Uncle” button is pressed to show some options.  Now my native dialog looks like it’s coming from a native application.</p>
<div class='sniplrcode'>$<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#uncle&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;touchend&#8217;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> e <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; navigator.<span style="color: #660066;">notification</span>.<span style="color: #000066;">confirm</span><span style="color: #009900;">&#40;</span> <br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8216;Are you sure you are done?&#8217;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span> button <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// alert( &#8216;Success: &#8216; + button );</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8216;Question For You&#8217;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">&#8216;Yes,No,Bugger Off&#8217;</span><br />
&nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div>
<p><strong>Conclusion</strong></p>
<p><strong></strong>Outside of all the asynchronous file work we have to do up front, working with the device audio via PhoneGap is really very easy.  It even provides the callbacks that you want the HTML audio tag to have, that it doesn’t.  And of course, the native audio functionality lets us record audio as well as play it back.  And if you’re wondering what “Bob’s your uncle” is translated to, it means “then it will be simple” just like getting started with PhoneGap.  What?  You haven&#8217;t started yet?  What are you waiting for?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/11/blimey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mind the Gap</title>
		<link>http://blog.kevinhoyt.com/2011/11/mind-the-gap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mind-the-gap</link>
		<comments>http://blog.kevinhoyt.com/2011/11/mind-the-gap/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 15:50:01 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=121</guid>
		<description><![CDATA[In this London-themed example, I’ll take you Underground, as we explore accessing device accelerometer data to control the basic motion in a simple game.  Along the way we will take a look at a few considerations around relative tilt, CSS3 transforms, and decoupling processes.  But watch out!  You don’t want to fall onto the rails, [...]]]></description>
			<content:encoded><![CDATA[<p>In this London-themed example, I’ll take you Underground, as we explore accessing device accelerometer data to control the basic motion in a simple game.  Along the way we will take a look at a few considerations around relative tilt, CSS3 transforms, and decoupling processes.  But watch out!  You don’t want to fall onto the rails, or get trapped between the platform and the tube.  Mind the gap?  Yeah, buddy.  Mind the PhoneGap!</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/mind-the-gap.png"><img class="alignnone size-full wp-image-106" title="Mind the Gap" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/mind-the-gap.png" alt="Screenshot of the game" width="480" height="320" /></a></p>
<p><strong>Accelerometer</strong></p>
<p><strong></strong>Accessing the accelerometer with PhoneGap is a relatively straightforward process.  The main function you will want to call is “navigator.accelerometer.watchAcceleration()”.  That sets the ball in motion to poll the device for accelerometer data at a given frequency.  The parameters you’ll want to pass to the function then include a function to call back when the interval has elapsed, a function to call back if there is an error, and a JavaScript object with a property named “frequency” that defines how often you want to get an update.</p>
<div class='sniplrcode'><span style="color: #003366; font-weight: bold;">var</span> latest <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span></p>
<p><span style="color: #003366; font-weight: bold;">function</span> doDeviceReady<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> options <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; frequency<span style="color: #339933;">:</span> FREQUENCY_ACCEL<br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>&nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; watchID <span style="color: #339933;">=</span> navigator.<span style="color: #660066;">accelerometer</span>.<span style="color: #660066;">watchAcceleration</span><span style="color: #009900;">&#40;</span> <br />
&nbsp; &nbsp; doAcceleration<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; doError<span style="color: #339933;">,</span> <br />
&nbsp; &nbsp; options <br />
&nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #009900;">&#125;</span></p>
<p><span style="color: #003366; font-weight: bold;">function</span> doAcceleration<span style="color: #009900;">&#40;</span> acceleration <span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; latest <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; x<span style="color: #339933;">:</span> acceleration.<span style="color: #660066;">x</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; y<span style="color: #339933;">:</span> acceleration.<span style="color: #660066;">y</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></p>
<p><span style="color: #003366; font-weight: bold;">function</span> doError<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;Acceleration Error&#8217;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #009900;">&#125;</span></div>
<p>You can set the frequency interval to be as low as you want, but PhoneGap caps the update rate to a minimum of 40 milliseconds.  You can also set the frequency interval to be as high as you want.  If you set the value greater than one second, PhoneGap will still poll the device every second, but only make the callback when the interval you specified has elapsed.  In this game I fire up the accelerometer at 100 milliseconds, and record the values as a separate data point from the actual game play.  More on that later.</p>
<p><strong>Relative Tilt</strong></p>
<p><strong></strong>The accelerometer on my iPod Touch presents a value of “0” on the x-axis and y-axis when laying flat with the screen up.  Depending on the screen orientation, you will get a maximum value of “1” for a tilt of 90 degrees at one end, and a value of “-1” for a tilt of 90 degrees in the opposite direction.  From there you might choose to have some multiplication factor to translate accelerometer data into pixel movement.  Apply some CSS and you’re golden, right?  Well, not so fast.</p>
<p>There’s a good chance that your user doesn’t want to play a game with tilt controls laying flat on the table.  They might be seated, and holding the device at an angle that gives them the best view of the screen.  It is also likely that the user doesn’t want to have to tilt a full 90 degrees to get to the maximum acceleration.  If you don’t account for these tilt factors, you’re likely to present a frustrating user experience.</p>
<p>The trick then is to use an existing tilt as the zero mark, effectively creating a relative tilt.  From there, you want to map a smaller tilt range to the gauge of what represents 0 &#8211; 100% in your application.  This math took me some time to figure out.  In fact, I’d say it was the toughest part of the application.  And it doesn’t help when relative tilt is relative not only to the user, but also possibly to the containing HTML element.</p>
<p>The way I approached this problem was first to assume that the user would be holding the device at an angle comfortable to them at the very moment before the game started.  To be clear, I’m talking about the game play, not the launch of the application itself.  The user presses a start button, the game presents a countdown, and then 500 milliseconds before the game starts, I grab the latest accelerometer data, and use it as zero.</p>
<p>In my game, the captured accelerometer point is mapped to the half-way point of total tilt range.  I then limit the total range by 0.25 in both directions.  Why 0.25?  Mostly just because I played with a number of options and found that value presented the best experience for my game.  And I think that goes to a point you will hear from me often &#8211; get a device, get as many as you can, and test on all of them from an early point in development.</p>
<div class='sniplrcode'><span style="color: #003366; font-weight: bold;">function</span> sample<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; vmax <span style="color: #339933;">=</span> latest.<span style="color: #660066;">x</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">0.25</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; vmin <span style="color: #339933;">=</span> latest.<span style="color: #660066;">x</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.25</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; vrange <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.50</span><span style="color: #339933;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; hmax <span style="color: #339933;">=</span> latest.<span style="color: #660066;">y</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">0.25</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; hmin <span style="color: #339933;">=</span> latest.<span style="color: #660066;">y</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">0.25</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; hrange <span style="color: #339933;">=</span> <span style="color: #CC0000;">0.50</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></p>
<p><span style="color: #003366; font-weight: bold;">function</span> move<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> hposition <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #003366; font-weight: bold;">var</span> vposition <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; vposition <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> latest.<span style="color: #660066;">x</span> <span style="color: #339933;">-</span> vmin <span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> vrange <span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> BRICKS_SPACE <span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> BRICKS_MAXIMUM<span style="color: #339933;">;</span><br />
&nbsp; hposition <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> latest.<span style="color: #660066;">y</span> <span style="color: #339933;">-</span> hmin <span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> hrange <span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> LEGS_SPACE<span style="color: #339933;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; <span style="color: #006600; font-style: italic;">// Keep in bounds</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> vposition <span style="color: #339933;">&gt;</span> BRICKS_MAXIMUM <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; vposition <span style="color: #339933;">=</span> BRICKS_MAXIMUM<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> vposition <span style="color: #339933;">&lt;</span> BRICKS_MINIMUM <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; vposition <span style="color: #339933;">=</span> BRICKS_MINIMUM<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> hposition <span style="color: #339933;">&lt;</span> LEGS_MINIMUM <span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; hposition <span style="color: #339933;">=</span> LEGS_MINIMUM<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> hposition <span style="color: #339933;">&gt;</span> LEGS_MAXIMUM <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; hposition <span style="color: #339933;">=</span> LEGS_MAXIMUM<span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#background&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;top&#8217;</span><span style="color: #339933;">,</span> vposition <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; <br />
&nbsp; $<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;#legs&#8217;</span> <span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&#8216;left&#8217;</span><span style="color: #339933;">,</span> hposition <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #009900;">&#125;</span></div>
<p>This is what I came up with to solve the relative tilt problem.  With the given relative minimum and maximum ranges, the first step is to get the accelerometer data.  In order to put that accelerometer data in the new range, I subtract the relative minimum tilt value, and divide by the total range of motion.  This gives me a percentage value of where the accelerometer sits relative to my total range.  Then I can multiply that percentage across the placement of the UI offsets.</p>
<p><strong>CSS3 Transforms</strong></p>
<p><strong></strong>I started using CSS3 transforms for much of the animation in this game.  The performance of using the transforms was notable over using animation techniques built into frameworks such as jQuery.  That being said, transforms and animations afforded by CSS3 were really quite cumbersome to tune.  A lot of “CSS, run, test, CSS, run, test” cycles for split second movements.</p>
<p>The biggest problem with CSS3 transforms and animations was a lack of callback when the action was completed.  It is common to want to fade something out, and then to trigger another action such as starting a timer, when that object is completely transparent &#8211; or better yet, to remove the transparent element once the animation has completed.</p>
<p>Without a callback I ended up having to keep a timer running, and hope that it was running in the same timing as the animations were actually being rendered.  And for the most part, the timing worked great.  Really strange though to have to keep a counter of what frame of the animation I’m on to be able to get a fine-tuned control on it, and to take actions after the effects were applied.</p>
<p><strong>Decoupling Processes</strong></p>
<p><strong></strong>I wasn’t quite sure what to call this section.  It’s a problem I’ve run into before with other experiments.  Essentially, when a timer is running at a regular interval, you have to be careful not to do more code in the callback than can reasonably be accomplished before the next interval.</p>
<p>For example, I wanted to get updates from the accelerometer every 100 milliseconds to make the game feel relatively responsive.  It’s likely you might even want to go lower.  Once you get a callback, you’ll be tempted to calculate placement of all the parts and pieces of the UI, and then make the DOM calls to update all the positions.  I’m here to tell you that you won’t be able to do all that in 100 milliseconds on a resource-limited device.</p>
<p>The solution then is to decouple the things you are doing.  Keeping with the accelerometer example, in my game I capture the values as they come in and update a variable that stores the latest value &#8211; and that’s it.  Then I have another process that controls the game play.  As it iterates, it checks the variable that has been updated.  Once the two are separate, there’s a notable increase in performance.  The UI is free to update, while PhoneGap is free to work with the device.</p>
<p>It should also be mentioned here that using PhoneGap to communicate with the device itself also takes time.  Depending on how much data you’re communicating, you may hang your user interface until the transaction is complete.</p>
<p><strong>Conclusion</strong></p>
<p><strong></strong>After all that talk of managing tilt, animation, performance, you’d think I’d have a result that I really liked.  In all honesty, I do not.  I still feel like the UI stutters too much.  I still don’t like how some of the animations play out.  And while I’m managing tilt effectively, it’s only for one orientation.  There’s a lot of work to do yet to make this a real game.  Along the way however, I’ve learned a lot about designing a mobile application with PhoneGap.  If you’re playing this game in the London Underground, just remember to look up from your phone every once in a while and “Mind the Gap”.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/11/mind-the-gap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PhoneGap Goes to London</title>
		<link>http://blog.kevinhoyt.com/2011/10/phonegap-goes-to-london/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=phonegap-goes-to-london</link>
		<comments>http://blog.kevinhoyt.com/2011/10/phonegap-goes-to-london/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 19:56:37 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=105</guid>
		<description><![CDATA[Last week I went to London, England to present at HTML5 Live.  The topic was “Building Mobile Applications with PhoneGap.”  Even though Adobe recently acquired Nitobi, largely the main drivers of PhoneGap, I had presented this topic a number of times before.  Even before PhoneGap was integrated with Dreamweaver CS5.5 I was out there giving [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I went to London, England to present at <a title="HTML5 Live London" href="http://jaoo.dk/html5-london-2011/">HTML5 Live</a>.  The topic was “<a title="Building Mobile Applications with PhoneGap" href="http://html5live.org/html5-london-2011/presentation/Building%20Mobile%20Applications%20with%20PhoneGap">Building Mobile Applications with PhoneGap</a>.”  Even though Adobe recently acquired <a title="Nitobi" href="http://nitobi.com/">Nitobi</a>, largely the main drivers of PhoneGap, I had presented this topic a number of times before.  Even before PhoneGap was integrated with <a title="Building a PhoneGap Application with Dreamweaver CS 5.5" href="http://tv.adobe.com/watch/cs-55-web-premium-feature-tour-/creating-a-native-mobile-application/">Dreamweaver CS5.5</a> I was out there giving presentations on the technology.  But while I knew what to present, I really didn’t want to show the same old demonstrations again.  I wanted something new.  But what?</p>
<p>About a week before the trip, as I was reviewing the presentation, and updating to all the latest bits, it hit me.  “If you’re going to London, why not have a variety of London-themed examples?” I set to coding, and before long found myself with four new examples of basic PhoneGap functionality in action.  It was a lot of fun to build them all, and I plan on sharing them each over the next few posts.  In the meantime however, here is the rundown of what to expect.</p>
<p><strong>Mind the Gap</strong></p>
<p>If you have never been to London, you may or may not know that they have an extensive subway system.  Britons don’t call it the “subway” however, but rather the “Underground.”  At virtually all the Underground stops there is a warning you will find painted on the platform, between you and the train.  That warning reads “Mind the Gap.”    I thought to myself “Yeah, you should mind the gap &#8211; the PhoneGap!”  And the first example was born.</p>
<p>My “Mind the Gap” application is an example of using PhoneGap to access the accelerometer on the device.  As you tilt the device, you move around on the Underground platform.  If you touch the “the gap”, your game will be over &#8211; which you will know by the use of another PhoneGap feature &#8211; the vibration of the device.  The example also uses CSS3 transitions to control movement and animation, which keeps the performance respectable.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/mind-the-gap.png"><img class="alignnone size-full wp-image-106" title="Mind the Gap" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/mind-the-gap.png" alt="Screenshot of the game" width="480" height="320" /></a></p>
<p><strong>Blimey</strong></p>
<p>Of course, if you are going to be presenting somewhere, it helps to know the language.  You might be thinking “Hey Kevin, it’s London, not China.  They speak English.”  To which I would largely disagree.  For example, in the United States if you want to squeeze by somebody standing in your way, you will say “Pardon me.”  In the United Kingdom, that translates to “I farted.”  So you would be pushing past people, telling them that you farted, not to get out of the way.  How rude!</p>
<p>I figured that a translator was needed for my presentation.  I could use PhoneGap to record the audio of somebody speaking a UK idiom, and translate it to English (yeah, I said it &#8211; English!).  Of course I wasn’t going to build a full translation system, so what you get out is limited to a set of random canned responses &#8211; an example of using PhoneGap to play audio.  No matter what you record, you’ll always get a nice, reaffirming, message in response.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/blimey.png"><img class="alignnone size-full wp-image-107" title="Blimey" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/blimey.png" alt="Screenshot of an audio recorder" width="320" height="480" /></a></p>
<p>There’s also an example of using PhoneGap to present native dialog boxes with custom buttons and labels.  Be warned though, that things get a little colorful on that side of the application.  It was an emergency feature added just in case the audience wasn’t responding to my jokes.</p>
<p><strong>Tardis Finder</strong></p>
<p>If you look around, you’ll find a number of applications that help you solve that age old problem of remembering where you parked.  Accessing the GPS in the device is usually the method used to solve this problem.  But GPS is very hard to show while presenting indoors, so I wanted an alternative.  Additionally, I didn’t want to show how you could accomplish the same old thing that dozens of other applications already do just fine.  I needed a new audience, and who better than that British icon than Doctor Who?</p>
<p>Think about it &#8211; there’s no parking application for Doctor Who.  There he is, traveling all about space and time, saving the universe from the evil Daleks, with nothing to reliably get him back to his trusty blue phone booth, er, Time And Relative Dimension In Space machine.  What if he gets lost?  Well thanks to PhoneGap, and its ability to access the compass, Doctor Who can now download the Tardis Finder application.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/tardis-finder1.png"><img class="alignnone size-full wp-image-110" title="Tardis Finder" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/tardis-finder1.png" alt="Compass pointing to a blue phone booth" width="320" height="569" /></a></p>
<p>Since there’s only been ten (10) Doctors, I’m not expecting huge sales, but at least I’m doing my part to keep the universe safe.</p>
<p><strong>iBond</strong></p>
<p>So long as we’re talking about British icons, one would be remiss in their duties if they didn’t mention Ian Fleming’s 007: James Bond himself.  You know how all the Bond movies start, don’t you?  There’s Bond and his signature Walther PPK being tracked by a circle &#8211; as if somebody is spying on the best spy.  Sometimes there’s different chases that Bond takes part in, and of course, there’s always a woman.  I thought to myself “Why does Bond get to be the only one to have all the fun?” and the next application sprang to life.</p>
<p>iBond leverages PhoneGap to allow you to capture an image from the device camera, or to select an existing image from the device photo gallery.  From there it takes the picture, leverages CSS3 transforms to scale down the image, and then places the picture in the center of the classic circle used during the opening of the movies.  You are now James Bond.  Tap on the 007 logo to use PhoneGap’s access to the local file system, and some canvas magic, to save the entire circle, swirl and selected picture to disk as one composite image.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/ibond.png"><img class="alignnone size-full wp-image-113" title="iBond" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/10/ibond.png" alt="Screenshot waiting for you to take a picture" width="320" height="480" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/10/phonegap-goes-to-london/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Going Sans Server</title>
		<link>http://blog.kevinhoyt.com/2011/09/going-sans-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=going-sans-server</link>
		<comments>http://blog.kevinhoyt.com/2011/09/going-sans-server/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 22:22:30 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=93</guid>
		<description><![CDATA[Well, that&#8217;s not entirely accurate, but bear with me.  Here is the pitch.  You are a client-side developer with mad user experience skills.  Whether you came up with the idea for the application, or were drafted into the project, you have sunk countless hours into making sure every interaction is as smooth as butter.  You [...]]]></description>
			<content:encoded><![CDATA[<p>Well, that&#8217;s not entirely accurate, but bear with me.  Here is the pitch.  You are a client-side developer with mad user experience skills.  Whether you came up with the idea for the application, or were drafted into the project, you have sunk countless hours into making sure every interaction is as smooth as butter.  You have successfully bent your choice of SDK to your will, and the demonstration, with the dummy data, looks like it will be the next big seller.  Before you hit the markets though, you will need a server to store all that glorious user data &#8211; and that&#8217;s when you hear the brakes.  Squealing.  Churning your gut at the monster task that lies ahead.  Time to market in this innovative space means everything.  What will you do?  How about &#8230; Nothing?</p>
<p>Luckily for you there are a variety of new services popping up on the horizon.  The details go a little something like this.  You know about the cloud.  You know you can spin up Amazon EC2 instances faster than you can toast a piece of bread.  Why is it then that create, read, update and delete, the same CRUD developers have been doing since the dawn of data processing, can&#8217;t be just as easy?  That&#8217;s exactly what these new services offer.  You&#8217;ve got your HTTP for the wire, REST for parity with CRUD, and JSON to represent the objects you want to store. They manage the server, your data, the scale, etc.  You are now comfortably back at home on the client.  Make a few web standards requests and badda-bing, badda-boom, you launch your application tomorrow.</p>
<p>I&#8217;ve had the good fortune to play with some of these cool services over the past few weeks, and I&#8217;ve got to say, as somebody who has seen more server than they care to ever see, I&#8217;m impressed!  My current favorite is <a title="Parse" href="https://www.parse.com/" target="_blank">Parse</a>.  I didn&#8217;t think I would like it at first, having to define my own objects, but in the end, found the freedom quite liberating.  I&#8217;m not worried about Third Normal Form (3NF) or anything here, so there&#8217;s a lot of redundancy to be sure, but storage and processing cycles are cheap these days, no?  And it&#8217;s just that kind of freedom that gets me going.  They&#8217;ve also opted to keep the REST API very straightforward.  It&#8217;s like I have a Rails Jedi sitting next to me.  Oh, and my personal favorite &#8211; no OAuth &#8211; a client-side developers worst nightmare.</p>
<p>Ready to create your first object on somebody else&#8217;s infrastructure?  Let&#8217;s do this thing!</p>
<div class='sniplrcode'><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> create<span style="color: #000000;">&#40;</span> className<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=string%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:string.html"><span style="color: #004993;">String</span></a><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">value</span><span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=object%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:object.html"><span style="color: #004993;">Object</span></a> <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> authorization<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=string%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:string.html"><span style="color: #004993;">String</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> request<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=urlrequest%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequest.html"><span style="color: #004993;">URLRequest</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> header<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=urlrequestheader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestheader.html"><span style="color: #004993;">URLRequestHeader</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; authorization = Base64<span style="color: #000066; font-weight: bold;">.</span>encode<span style="color: #000000;">&#40;</span> APPLICATION_ID <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #990000;">&quot;:&quot;</span> <span style="color: #000066; font-weight: bold;">+</span> MASTER_KEY <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; header = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlrequestheader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestheader.html"><span style="color: #004993;">URLRequestHeader</span></a><span style="color: #000000;">&#40;</span> <span style="color: #990000;">&quot;Authorization&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #990000;">&quot;Basic &quot;</span> <span style="color: #000066; font-weight: bold;">+</span> authorization <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; request = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlrequest%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequest.html"><span style="color: #004993;">URLRequest</span></a><span style="color: #000000;">&#40;</span> <span style="color: #990000;">&quot;https://api.parse.com/1/classes/&quot;</span> <span style="color: #000066; font-weight: bold;">+</span> className <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">method</span> = <a href="http://www.google.com/search?q=urlrequestmethod%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestmethod.html"><span style="color: #004993;">URLRequestMethod</span></a><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">POST</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">contentType</span> = <span style="color: #990000;">&quot;application/json&quot;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">data</span> = JSON<span style="color: #000066; font-weight: bold;">.</span>encode<span style="color: #000000;">&#40;</span> <span style="color: #004993;">value</span> <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">requestHeaders</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span> header <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></p>
<p>&nbsp; <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">loader</span> == <span style="color: #0033ff; font-weight: bold;">null</span> <span style="color: #000000;">&#41;</span><br />
&nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #004993;">loader</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlloader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlloader.html"><span style="color: #004993;">URLLoader</span></a><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #000000;">&#125;</span></p>
<p>&nbsp; <span style="color: #004993;">loader</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span> <a href="http://www.google.com/search?q=event%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:event.html"><span style="color: #004993;">Event</span></a><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">COMPLETE</span><span style="color: #000066; font-weight: bold;">,</span> doCreateComplete <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; <span style="color: #004993;">loader</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">load</span><span style="color: #000000;">&#40;</span> request <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #000000;">&#125;</span></div>
<p>When you login to Parse, you will be prompted to set up an application.  You can have as many of these as you like, and for most purposes, you can think of it as roughly analogous to a database.  Along with that application you will get a unique identifier, and a master key.  You will use these as the user name and password in an HTTP Authentication header on your request.  Simply concatenate and Base64 encode the two.  I&#8217;m using a <a title="AS3 Base64 Class" href="https://github.com/spjwebster/as3base64" target="_blank">Base64 encoding class from Steven Webster</a> here.  From there you set up your request, and since you are creating an object, you will use the HTTP POST method.</p>
<p>Note that the URL for the Parse API is used as the destination, and then appended to that is the name of the class you want to create.  Didn&#8217;t define it prior to making the request?  No worries, that&#8217;ll get done the first time you make the request.  The data we will send to that URL is a straight-up ActionScript Object instance.  You put whatever properties you want on it, encode it with JSON, and send it along as the data of the request.  When the result comes back, it&#8217;ll be a JSON object with the data/time stamp the row was created, and the unique identifier for the data you just stored.  Again, think of this as your primary key in database terms.</p>
<p>You my friend, are done!  There&#8217;s about twenty lines of working code there, and you never even mentioned the words server or database.</p>
<div class='sniplrcode'><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> read<span style="color: #000000;">&#40;</span> className<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=string%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:string.html"><span style="color: #004993;">String</span></a><span style="color: #000066; font-weight: bold;">,</span> objectId<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=string%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:string.html"><span style="color: #004993;">String</span></a> <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> authorization<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=string%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:string.html"><span style="color: #004993;">String</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> request<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=urlrequest%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequest.html"><span style="color: #004993;">URLRequest</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> header<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=urlrequestheader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestheader.html"><span style="color: #004993;">URLRequestHeader</span></a> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; authorization = Base64<span style="color: #000066; font-weight: bold;">.</span>encode<span style="color: #000000;">&#40;</span> APPLICATION_ID <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #990000;">&quot;:&quot;</span> <span style="color: #000066; font-weight: bold;">+</span> MASTER_KEY <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; header = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlrequestheader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestheader.html"><span style="color: #004993;">URLRequestHeader</span></a><span style="color: #000000;">&#40;</span> <span style="color: #990000;">&quot;Authorization&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #990000;">&quot;Basic &quot;</span> <span style="color: #000066; font-weight: bold;">+</span> authorization <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </p>
<p>&nbsp; request = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlrequest%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequest.html"><span style="color: #004993;">URLRequest</span></a><span style="color: #000000;">&#40;</span> <span style="color: #990000;">&quot;https://api.parse.com/1/classes/&quot;</span> <span style="color: #000066; font-weight: bold;">+</span> className <span style="color: #000066; font-weight: bold;">+</span> <span style="color: #990000;">&quot;/&quot;</span> <span style="color: #000066; font-weight: bold;">+</span> objectId <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">method</span> = <a href="http://www.google.com/search?q=urlrequestmethod%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlrequestmethod.html"><span style="color: #004993;">URLRequestMethod</span></a><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">GET</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">contentType</span> = <span style="color: #990000;">&quot;application/json&quot;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; request<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">requestHeaders</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span> header <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></p>
<p>&nbsp; <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">loader</span> == <span style="color: #0033ff; font-weight: bold;">null</span> <span style="color: #000000;">&#41;</span><br />
&nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #004993;">loader</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=urlloader%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:urlloader.html"><span style="color: #004993;">URLLoader</span></a><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span style="color: #000000;">&#125;</span></p>
<p>&nbsp; <span style="color: #004993;">loader</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span> <a href="http://www.google.com/search?q=event%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:event.html"><span style="color: #004993;">Event</span></a><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">COMPLETE</span><span style="color: #000066; font-weight: bold;">,</span> doReadComplete <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; <span style="color: #004993;">loader</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">load</span><span style="color: #000000;">&#40;</span> request <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #000000;">&#125;</span></div>
<p>Don&#8217;t believe it can be that easy?  You can always go to the Parse data browser to check it out, work with the data, import some more data from a CSV file, or drop the whole thing outright.  If you are like me though, and want to see for yourself using a request of the same system, I&#8217;ve got your back.  It all follows the same pattern.  You set up the authentication header, but this time your request will be done using the GET method.  And notice that the URL is the base Parse API URL, plus the class name, plus the object identifier of the data you want.  Send that bad boy on over, and you&#8217;ll get yourself some JSON back representing the stored data.</p>
<p>And you can go on like this ad nauseam.   HTTP PUT for an update and HTTP for DELETE.  The same boiler code will do you.  There is even a fairly well thought out query syntax for when you want to start filtering on your requests.  Of course, if it seems like this boilerplate code would be all too easy to wrap up into a simple class for reuse, you are exactly right.  Up on <a title="Parse API Class on GitHub" href="https://github.com/parkerkrhoyt/Parse" target="_blank">my GitHub account</a>, I&#8217;ve posted a simple set of classes for interacting with the Parse REST API.  There&#8217;s even a sample on how to use the class.  Feel free to do so.  If you want to contribute, I can accomodate that too.  All I ask for in return is a piece of that next best selling application you&#8217;re writing.  I kid!  I kid!  Now go on with your bad self, and enjoy you some server-free data storage.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/going-sans-server/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Covey Productivity Tip</title>
		<link>http://blog.kevinhoyt.com/2011/09/covey-productivity-tip/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=covey-productivity-tip</link>
		<comments>http://blog.kevinhoyt.com/2011/09/covey-productivity-tip/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 20:36:47 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=88</guid>
		<description><![CDATA[I obsess over personal productivity.  In this Information Age, there&#8217;s entirely too much to get done &#8211; more than can ever possibly be done by one person, so prioritizing effectively is imperative to staying on top of things.  That applies not only to work, but also in your personal life, or simply other activities you [...]]]></description>
			<content:encoded><![CDATA[<p>I obsess over personal productivity.  In this Information Age, there&#8217;s entirely too much to get done &#8211; more than can ever possibly be done by one person, so prioritizing effectively is imperative to staying on top of things.  That applies not only to work, but also in your personal life, or simply other activities you enjoy.  While productivity isn&#8217;t a new area of study, I think it is safe to say that there has been a marked leap forward in recent years (e.g. Getting Things Done).  Sometimes however, we forget some of the tried and true techniques from the previous generation that can still be easily and readily applied to any workflow.</p>
<p>Franklin Covey has historically been a mainstay in the realm of personal productivity.  Their journals, books, training and other media have saved countless people from information overload.  Back in the days of paper tracking, Covey journals had an important side bar for &#8220;priorities.&#8221;  Unless you had ever read Covey&#8217;s techniques, you&#8217;d probably never use this space for anything other than notes.  Or you may have jotted a few priorities down without having given any consideration as to why you are putting them down in the first place.</p>
<p>To understand the idea of this space, you first have to step back and understand who you are as a person, and what you are about.  This first level of priority setting, outside of the presence of technology or systems, is critically important.  It takes a degree of self introspection that isn&#8217;t always comfortable.  The outcome should be the &#8220;roles&#8221; you play in your life.  As an example, you might be an employee, husband, father, etc.  Once you&#8217;ve identified who you are, and the roles you play, setting priorities becomes markedly more approachable.</p>
<p>Next up would be to start the week by examining those roles and thinking about the priorities of what needs to get accomplished in the week ahead.  And it should go without saying that you should schedule time for this activity, each and every week.  From there you&#8217;d come up with five items that you need to get done in the week ahead across those roles.  You write them down in the sidebar of the journal, and stick with them.  Again, not forgetting to schedule time for those things.</p>
<p>As the week progresses, you cross those items off your list.  The following Monday (or whenever you decide to do this activity) you&#8217;d look at what you did not get done, and carry those forward to the next week.  Then again with some contemplation, consider how you round out that list with what lies in the week ahead.  As time goes on, you can look back at all that you have accomplished, and you may even choose to reward yourself when you&#8217;ve crossed a certain milestone.  Looking forward, if you stick to the plan, you will quickly come to realize just how productive you&#8217;ve become &#8211; and how much &#8220;other stuff&#8221; falls away because it simply doesn&#8217;t matter to who you are.</p>
<p>Sounds interesting?  Here&#8217;s is my abbreviated version for those just getting started.</p>
<p>At the start of the week (Monday for me), think about what you have to do in the week ahead.  Try to think holistically.  You don&#8217;t have to focus on roles just yet.  At the start, simply get some basic things you want to get done, and try to spread the items across more than just &#8220;work.&#8221;  I&#8217;d suggest just picking five items.  Keep it short and sweet.  Then go through the week and cross those items off as you go.  Wash, rinse and repeat for the next week.  Carry over what you didn&#8217;t get done, and then round it out with new items to total five priorities for the week.  Over time, the roles that are important to you will surface, and you can start focusing more specifically on those items.</p>
<p>The other important factor of this technique is to keep those priorities relevant in your mind.  For this, I suggest a small whiteboard that you keep on your desk.  Or if you are creatively inclined, make a fun wallpaper with those priorities.  Whatever works for you to keep your action items &#8220;mentally relevant&#8221; &#8211; always on your mind.  Of course this is but one technique, and not all personal productivity wisdom applies to everybody equally, so feel free to adapt this concept to whatever works for you.  In the end, you&#8217;ll discover a more productive &#8220;you&#8221; and the people around you will recognize it as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/covey-productivity-tip/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Web Development at MAX</title>
		<link>http://blog.kevinhoyt.com/2011/09/web-development-at-max-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=web-development-at-max-2</link>
		<comments>http://blog.kevinhoyt.com/2011/09/web-development-at-max-2/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 22:57:24 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=49</guid>
		<description><![CDATA[The past couple of years, I have had the distinct pleasure of running a &#8220;camp&#8221; at MAX.  A camp is what most other conferences call a &#8220;track&#8221;.  With Adobe&#8217;s broad spectrum of offerings however, a track generally consists of terms such as &#8220;design&#8221;, &#8220;development&#8221; or &#8220;enterprise&#8221;.  Last year I ran the &#8220;mobile&#8221; camp which consisted [...]]]></description>
			<content:encoded><![CDATA[<p>The past couple of years, I have had the distinct pleasure of running a &#8220;camp&#8221; at MAX.  A camp is what most other conferences call a &#8220;track&#8221;.  With Adobe&#8217;s broad spectrum of offerings however, a track generally consists of terms such as &#8220;design&#8221;, &#8220;development&#8221; or &#8220;enterprise&#8221;.  Last year I ran the &#8220;mobile&#8221; camp which consisted of a variety mobile development options from across the Flash Platform line-up of technologies.  This year I&#8217;m running a camp on &#8220;Web Development&#8221; and I&#8217;m happy to report that I have some next-level talent and content lined up.</p>
<p>I&#8217;ve discovered that my approach to lining up presenters differs somewhat from others.  My first action is to head to Twitter and openly ask for topics and presenters.  From there I start working my professional network to reach out to suggested presenters, and see if they are interested.  I also review their past presentations from SlideShare, including comments both from there and from user group web sites.  And of course there&#8217;s an obligatory stop at their blogs.  Eventually, what settles out is a camp that is by the people, for the people.</p>
<p>These sessions have almost all sold out one time already at this point, with a month left to go until MAX starts, and most of the presenters have been able to sign on for another session.  So if you&#8217;re into web development, and are looking for awesome content, then don&#8217;t delay &#8211; head over to the MAX web site and register now.  If you&#8217;ve already made plans to attend, check your schedule and make sure you get to see these folks live and in person.  Without further ado then, the line-up for my camp this year is as follows.</p>
<p><strong>How to Rapidly Build HTML5 Web Applications with Sencha Technologies</strong></p>
<p><em>Aaron Conran, ExtJS Core Development Team Member</em></p>
<p>Join this session as we explore how to rapidly build HTML5 desktop and mobile applications using Sencha technologies. Ext JS and Sencha Touch are frameworks enabling development of pixel-perfect, cross-browser apps that look and feel like native applications. The frameworks are built on web standards (HTML5, JavaScript, and CSS), require no browser plug-ins, and can integrate with any server-side back end such as ColdFusion, PHP, or Java. Learn how to use Sencha Designer to create rich interfaces for the web in an easy-to-use visual environment.</p>
<p><strong>Mobile Applications with jQuery, Dreamweaver and PhoneGap</strong></p>
<p><em>Dave Johnson, Nitobi Cofounder</em></p>
<p><em>Steve Gill, PhoneGap Community Champion</em></p>
<p>In this session you&#8217;ll learn how to leverage native device functionality with HTML and JavaScript using PhoneGap. You&#8217;ll also see how Dreamweaver 5.5 makes it easy to integrate jQuery mobile and PhoneGap. This is a great session for anyone who wants to build cross-platform mobile applications with HTML, CSS, and JavaScript. The session will walk you through getting set up, creating a basic application, using jQuery mobile for UI, and using the PhoneGap APIs to hook into device-specific features like camera and GPS. By the end you&#8217;ll have all of the info you need to deploy and publish the application.</p>
<p><strong>Building It with jQuery Mobile</strong></p>
<p><em>Sidney Maestre, PayPal Developer Evangelist</em></p>
<p>Find out how jQuery Mobile takes the popular jQuery JavaScript library to the next level by providing a unified user interface system across all popular mobile device platforms. In this session, we’ll cover structuring content, touch events, helper methods, and working with remote data. We’ll build a mobile app using jQuery Mobile toolbars, buttons, form elements, and list components. You’ll leave with a solid foundation for future jQuery Mobile projects.</p>
<p><strong>Real-Time Programming with Arduino Using WebSockets</strong></p>
<p><em>Justin Mclean, Consultant, Developer and Trainer</em></p>
<p>Learn how you can communicate in real time with the physical world using Arduino, a low-cost, easy-to-program open source hardware and software platform. This session looks at how to interact with Arduino hardware directly from a web browser using the WebSockets protocol and the Socket.IO JavaScript library. We&#8217;ll start out by turning LEDs on and off and progress to creating graphs that react in real time to environmental sensors.</p>
<p><strong>HTML5: The 2012 of the Web</strong></p>
<p><em>Robert Nyman, Mozilla Technical Evangelist</em></p>
<p>Take an in-depth look at HTML5, a buzzword we&#8217;ve all heard, but few truly understand. We&#8217;ll explore HTML5 elements such as new form input and behavior, as well as APIs like video, canvas, Web Storage, History, and more. You&#8217;ll find out how these technologies can help you create better and richer websites for end users.</p>
<p><strong>Mastering Media Queries</strong></p>
<p><em>David Powers, Bestselling Author</em></p>
<p>Take a deep dive into using CSS3 media queries to create websites that look good and work well on desktops, tablets, and mobile phones regardless of screen size. In this session, bestselling author and trainer David Powers explores how to optimize style rules for each type of device depending on its features, such as width, height, aspect ratio, and orientation. You&#8217;ll also learn how to cope with older browsers that don&#8217;t support media queries and how to avoid wasting mobile users&#8217; valuable data allowance by forcing them to download assets intended only for larger screen sizes.</p>
<p><strong>HTML5 Semantic Web</strong></p>
<p><em>Terry Ryan, Adobe Developer Evangelist</em></p>
<p>Learn how the real HTML5 can make your job much easier! Lost in all of the marketing about HTML5 are the real features that actually define it. These include new tags, new form fields, and new attributes on both new and old tags alike. This session will introduce you to these new semantic elements, explain them, and explore when you would use them. It will also show how you can use them to reduce <em>divitis</em> in your HTML and make your work faster to write and easier to maintain.</p>
<p><strong>Building Interactive Content Using HTML5 Canvas</strong></p>
<p><em>Grant Skinner, CEO GSkinner</em></p>
<p>Join Grant Skinner, veteran interactive developer and creator of EaselJS and Pirates Love Daisies, for this session on building interactive content using the HTML5 canvas element. The talk will feature a comparison of related technologies (Flash, CSS, SVG) and include tips and gotchas, the core API, and an examination of a number of canvas libraries, with a focus on EaselJS. Applied uses include games, infographics, data visualization, and advertising.</p>
<p><strong>Building Cross-Platform Mobile Applications with HTML, CSS and JavaScript</strong></p>
<p><em>Jonathan Stark, Bestselling Author</em></p>
<p>Join mobile application consultant Jonathan Stark on an up-close and personal tour of the mobile side of HTML, CSS, and JavaScript. With the mobile web still in its infancy, platform fragmentation is worse than ever, and maintaining separate codebases can be problematic. Fortunately, advances in HTML5 and related technologies are paving the way forward. Learn how to leverage a single codebase to deliver a compelling experience on mobile platforms, both online and off.</p>
<p><strong>High-Performance JavaScript</strong></p>
<p><em>Nicholas Zakas, Bestselling Author</em></p>
<p>Join the discussion as we dive into the complexities of JavaScript. For much of its existence, JavaScript has been slow, but no one complained until developers started creating complex web applications with thousands of lines of code. Although newer JavaScript engines have improved the situation, there’s still a lot to understand about what makes JavaScript slow and what you can do to speed up your code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/web-development-at-max-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rocky Patel 2003</title>
		<link>http://blog.kevinhoyt.com/2011/09/rocky-patel-2003/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rocky-patel-2003</link>
		<comments>http://blog.kevinhoyt.com/2011/09/rocky-patel-2003/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 22:21:34 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Cigars]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=45</guid>
		<description><![CDATA[One of the first cigars that took me from being a predominantly mild to medium body smoker to a full body smoker was a Rocky Patel 1992.  Ever since then I have always had a soft spot for Rocky Patel products.  And from what I know of Rocky Patel, I like him as a person [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first cigars that took me from being a predominantly mild to medium body smoker to a full body smoker was a Rocky Patel 1992.  Ever since then I have always had a soft spot for Rocky Patel products.  And from what I know of Rocky Patel, I like him as a person as well. From Hollywood lawyer, to cigar icon, and a champion for cigar smokers rights.  I had the opportunity recently to try one of his newer lines, a Rocky Patel 2003.</p>
<p><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/rp-cameroon.png"><img class="alignnone size-full wp-image-68" title="rp-cameroon" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/rp-cameroon.png" alt="" width="400" height="153" /></a></p>
<p>From the initial examination of the cigar, the dark cameroon wrapper was certainly easy on the eyes.  A silky smooth dark wrapper leaf that seemed to suggest a typical Patel medium to full body smoke.  I&#8217;ve read that cameroon wrappers are notoriously difficult to roll well, so I was eager to see if the construction of the stick held up to other Patel smokes.  Pre-light, the scent of the cigar wasn&#8217;t anything notable either on the wrapper or on the foot.</p>
<p>Upon lighting the cigar, it started off with a little more spice than I expect, but it is a formidable size stick at 6 inches and 58 ring gauge, so it took a bit to light it.  A hot cigar usually burns a bit more spicy, so this wasn&#8217;t entirely unexpected.  After letting the cigar cool, and getting down a couple of inches, the spice subsided and flavors exhibited were that of nuts, with a slight hint of dark cherry.  The smoke itself was smooth and enjoyable.</p>
<p>Then disaster struck, and the cigar suddenly emitted a bunch of unexpected smoke, and suddenly extinguished itself.  I examined the foot for any construction flaws, but found no holes or other problems.  I suspect that this surprise came from the leaf being a bit on the younger side &#8211; it is after all only eight (8) years old.  After cleaning the foot and relighting, the remainder of the cigar exhibited no further problems.  I smoked it all the way down to the cap.</p>
<p>Overall, this was an enjoyable cigar.  It was surprisingly mild for a Rocky Patel smoke.  It would make a great late afternoon, pre-dinner stick.  Something you could enjoy without having to worry about having anything in your stomach.  Given that the cigar went out on me, I&#8217;d suggest picking up a few sticks and stashing them in your humidor for a couple of years.  I imagine that the extra age would really bring out all the characteristics of this cigar.  Notably, I&#8217;d hope that the dark cherry I tasted would mature into a more dominant flavor.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/rocky-patel-2003/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embassy Suites La Vista</title>
		<link>http://blog.kevinhoyt.com/2011/09/embassy-suites-la-vista/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=embassy-suites-la-vista</link>
		<comments>http://blog.kevinhoyt.com/2011/09/embassy-suites-la-vista/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 14:21:33 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Travel]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=27</guid>
		<description><![CDATA[Of late, I have made it a point to take a picture out the window of every hotel room I stay in &#8211; which is a considerable number of hotel rooms, over a considerable number of properties, every year.  I am not sure if it is some fashion of sick torture, reminding myself just how [...]]]></description>
			<content:encoded><![CDATA[<p>Of late, I have made it a point to take a picture out the window of every hotel room I stay in &#8211; which is a considerable number of hotel rooms, over a considerable number of properties, every year.  I am not sure if it is some fashion of sick torture, reminding myself just how much time I spend on the road, or if it is a tribute to the diversity that the world has to offer.  Either way, from time to time I figured I would start posting these pictures, starting with Embassy Suite, La Vista, Nebraska.</p>
<div id="attachment_28" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/embassy-vista-609.jpg"><img class="size-medium wp-image-28" title="Embassy Suites, La Vista, Nebraska" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/embassy-vista-609-300x225.jpg" alt="Embassy Suites, La Vista, Nebraska" width="300" height="225" /></a><p class="wp-caption-text">Embassy Suites, La Vista, Nebraska, Room #609</p></div>
<p>La Vista, Nebraska is a suburb of Omaha, Nebraska on the far West side.  It&#8217;s so far West in fact, that I&#8217;m not even sure it&#8217;s proper to call it a suburb.  If you are driving West from Omaha to Denver, Colorado, along I-80, then it is pretty much the last civilized exit you will en counter before you enter the vast farm land between Omaha and Lincoln, Nebraska.  The main draw of the area is probably the Cabela&#8217;s sporting goods store, which is just across the street from the Embassy Suites.</p>
<p>The hotel itself is a relatively new property &#8211; maybe five years old at the most.  As such the furnishings are still pretty much free of the blemishes that come with patron wear and tear.  If you have never been to an Embassy Suites, they are part of the Hilton brand.  Each room has two rooms &#8211; a living room and a bedroom (hence the &#8220;suites&#8221;).  A breakfast buffet is served every morning and includes everything from custom made omelets to biscuits and gravy.  If you&#8217;re a member of the Hilton Honors frequency program, there&#8217;s also a nightly managers reception with free beer, wine and hors de vors.</p>
<p>Embassy Suites, La Vista is connected to a Marriott Courtyard by a small conference center.  The conference center has maybe a dozen presentation rooms, and a few ballrooms.  For a few years running, the Heartland Developer Conference has been hosted in the conference center, and it is that event that brings me to La Vista, Nebraska this time around.  More information, session notes, presentations and other content from that conference coming up in a subsequent post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/embassy-suites-la-vista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Live Answers</title>
		<link>http://blog.kevinhoyt.com/2011/09/html5-live-answers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=html5-live-answers</link>
		<comments>http://blog.kevinhoyt.com/2011/09/html5-live-answers/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 01:17:41 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=21</guid>
		<description><![CDATA[Web standards are awesome!  From back in the days around the Adobe AIR launch, up to and including today, I continue to present regularly at conferences around web standards.  And there is so much to talk about these days.  Of late, I find myself immersed in canvas, local file access, CSS3 and more.  And I [...]]]></description>
			<content:encoded><![CDATA[<p>Web standards are awesome!  From back in the days around the Adobe AIR launch, up to and including today, I continue to present regularly at conferences around web standards.  And there is so much to talk about these days.  Of late, I find myself immersed in canvas, local file access, CSS3 and more.  And I have an upcoming opportunity to talk about these topics at length in sessions at the HTML5 Live conferences being held in <a title="HTML5 Live Event Web Site" href="http://jaoo.dk/html5-london-2011/">London, England</a> on October 19 and <a title="HTML5 Live Event Web Site" href="http://html5live.org/html5-nyc-2011/">New York, NY</a> on November 1, 2011.</p>
<p>The thing I like about these events is that they are being organized by the community, for the community.  They focus not on web design, but on enterprise web application developers and architects.  I get to share the stage with esteemed industry thought leaders such as Christian Heilmann from Mozilla, Bruce Lawson from Opera, James Pearce from Sencha and more.  If you haven&#8217;t already registered, you owe it to yourself attend.  And the good news is that there&#8217;s still space available.</p>
<p>The organizers recently shot me a list of questions about my sessions, to share with attendees and those looking to attend.  So without further ado, here is my session description, and my answers.</p>
<p><strong>Description</strong></p>
<p>Learn about programming charts and graphs, animations, drawing applications and other early use-cases for the HTML5 canvas element.  Come explore the canvas API including shapes, styles, transformations, compositing, images and animation.  Along the way we&#8217;ll explore examples on both the frivolous and more practical sides of the scale.</p>
<p><strong>Questions and Answers</strong></p>
<p>Q. Tell us a little about what you will be talking about at HTML5 Live.</p>
<p>A. At a high level, I will be talking all about the canvas element, and the extensive API that goes along with it.  It&#8217;s that later part that can end up getting really deep, and indeed I think this talk will initially make attendees feel a bit like Alice falling down the rabbit hole.  Once there&#8217;s a foundation of knowledge to build on however, we will take off on new, more comprehensive adventures with a wide variety of more sophisticated examples.</p>
<p>Q. What will people who attend your talk learn?</p>
<p>A. At a baseline, they will learn the fundamentals of using canvas.  I also hope that they will learn what kinds of new opportunities are opened up by this fantastic set of new capabilities.  There&#8217;s a whole new world of creative expression that can be accomplished with canvas, and I want to open attendees minds to the possibilities.</p>
<p>Q. What will they take away that they can apply right away?</p>
<p>A. Attendees will walk away with confidence that they can use, and rely on canvas for their next project. Hopefully they will also be able see web development problems in a new light, and find solutions in canvas.</p>
<p>Q. In your opinion, why should people attend HTML5 Live?</p>
<p>A. I present at, and attend, more conferences per year than I care to admit.  In talking with the HTML5 Live event organizers however, it feels like there will be a real sense of education and community throughout the day.  Those are always the best conference environments.  When attendees can take time to interact with one another, and the speakers in an open dialog, magic happens.</p>
<p>Q. Why is HTML5 exciting for web developers? Architects?</p>
<p>A. So many new APIs! What&#8217;s not to be excited about there?  New APIs mean new feature possibilities, or easier solutions to historical complex problems.  Or even better yet, ways to solve problems that were previously just not possible to solve with web standards.  And the best developers are always learning, always pushing the boundaries of themselves, and the technology which they yield.  All those APIs gives us all new opportunities to grow.</p>
<p>Q. Anything else you&#8217;d like to talk about?</p>
<p>A. I think some might find it odd to have Adobe, the Flash company, presenting at an HTML and/or web standards conference.  It is important to remember that Adobe has a long and bountiful history with web standards.  Adobe is also an active contributor to web standards proper, as well as various JavaScript frameworks.  At the end of the day, Adobe is about &#8220;Changing the world through digital experiences.&#8221;  And not on our terms but on yours.  We make tools to help you build the best experience possible &#8211; regardless of Flash, HTML, in-browser, out-of-browser, desktop, mobile, tablet, television, or any other screen.</p>
<p>Q. What are some of your favorite cigars?</p>
<p>A. Yes, I know it&#8217;s social faux pas to smoke these days, but for me, nothing beats kicking back with a nice cigar and a pour of single malt scotch (neat please).  Of late I&#8217;m finding myself particularly fond of Nicaraguan blends, so as you might imagine most of the new stuff coming from Drew Estates is a big favorite.  An Ashton Maduro is always an exquisitely constructed stick with a great taste.  I like the Illusione line across the board as well.  And Fuente has recently started shipping a great stick with a split wrapper that I&#8217;ve grown rather fond of enjoying.  On my list to explore further is the new Xikar line, HC Series.  Or, you know, when I&#8217;m in London, it&#8217;ll be anything Cuban.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/html5-live-answers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flash Rocks</title>
		<link>http://blog.kevinhoyt.com/2011/09/flash-rocks/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flash-rocks</link>
		<comments>http://blog.kevinhoyt.com/2011/09/flash-rocks/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 00:42:25 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Promotions]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=18</guid>
		<description><![CDATA[Did you know that Flash Rocks? Well it does.  There, take my word for it.  Or better yet, don&#8217;t!  Adobe Platform Marketing has recently kicked off a new &#8220;Flash Rocks&#8221; program, which is hosted primarily on Facebook.  Billed as the place for you to show off your killer applications, you can also check out what [...]]]></description>
			<content:encoded><![CDATA[<p>Did you know that Flash Rocks? Well it does.  There, take my word for it.  Or better yet, don&#8217;t!  Adobe Platform Marketing has recently kicked off a new &#8220;<a title="Flash Rocks Web Site" href="http://www.flash-rocks.com">Flash Rocks</a>&#8221; program, which is hosted primarily on Facebook.  Billed as the place for you to show off your killer applications, you can also check out what other people have done.  Have something that you&#8217;ve done that you think rocks?  Add it!  Go.  Now.  Do it!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/flash-rocks/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Designer Knows Best</title>
		<link>http://blog.kevinhoyt.com/2011/09/designer-knows-best/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=designer-knows-best</link>
		<comments>http://blog.kevinhoyt.com/2011/09/designer-knows-best/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 04:36:57 +0000</pubDate>
		<dc:creator>Kevin Hoyt</dc:creator>
				<category><![CDATA[Previews]]></category>
		<category><![CDATA[beetle]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[cards]]></category>
		<category><![CDATA[concentration]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[p2p]]></category>
		<category><![CDATA[paul]]></category>
		<category><![CDATA[slug]]></category>
		<category><![CDATA[television]]></category>
		<category><![CDATA[trani]]></category>

		<guid isPermaLink="false">http://blog.kevinhoyt.com/?p=8</guid>
		<description><![CDATA[Have you ever played that game “Punch Bug” or as I call it “Slug Bug”?  The concept is simple &#8211; when you see a Volkswagon Beetle, you call out “Slug Bug” and then hit the other players (usually in the shoulder).  I learned long ago that you do not play this game with somebody who [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever played that game “Punch Bug” or as I call it “<a title="Slug Bug" href="http://en.wikipedia.org/wiki/Slug_bug" target="_blank">Slug Bug</a>”?  The concept is simple &#8211; when you see a Volkswagon Beetle, you call out “Slug Bug” and then hit the other players (usually in the shoulder).  I learned long ago that you do not play this game with somebody who has at one time owned a Beetle.  Those individuals seem to have a second sense about them.  As I learned today, such is also the case for playing a game with the designer that built it.</p>
<p>While at 360Flex in Denver, Colorado earlier this year, I had lunch with <a title="Paul Trani" href="http://designupdate.com/" target="_blank">Paul Trani</a>.  Among the many topics discussed was a concept of producing a stable of well-designed applications for each person on the team.  I specifically asked Paul to focus on his take on the child’s game of “<a title="Memory (Card Game)" href="http://en.wikipedia.org/wiki/Memory_(card_game)" target="_blank">Memory</a>.”  You know, you pick two cards, and if they do not match, you turn them over and it is the other player’s turn?  This initiative eventually turned into a game that Paul called “Monster Match”.</p>
<p>Fast forward to this afternoon, and I spent some time “helping” Paul test out his creation.  Honestly, I think I was there more for moral support than anything else.  Paul had the game running on just about every mainstream device &#8211; from tablet to smartphone, from iOS to PlayBook &#8211; under the sun.  It leverages peer-assisted technology to be able to allow head-to-head play on the same wireless network.  We even got it playing on the <a title="Logitech Review with Google TV" href="http://www.logitech.com/en-us/smarttv/revue?wt.ac=psE|8103|revue-price-drop|hp" target="_blank">Logitech Revue</a> (Google TV) box.</p>
<div id="attachment_9" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/IMAG0265.jpg"><img class="size-medium wp-image-9" title="Monster Match" src="http://blog.kevinhoyt.com/wp-content/uploads/2011/09/IMAG0265-300x179.jpg" alt="" width="300" height="179" /></a><p class="wp-caption-text">Paul Trani shows off Monster Match</p></div>
<p>It was there where I learned this humiliating lesson of not playing a game with it’s designer.  Since Paul designed the characters and their corresponding animations, every facet of the cards were burned into his memory.  It took him no effort whatsoever to remember where he last saw a particular card.  Needless to say, I was thoroughly trounced.  While we have had some interest around the game from third parties, and are not in a position to put it into the various application markets, we do hope to have a video of this game in action in the coming week or two.  Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.kevinhoyt.com/2011/09/designer-knows-best/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

