<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Ryan Stewart - Mountaineer Coding</title>
	
	<link>http://blog.digitalbackcountry.com</link>
	<description>Just an average guy trying to drink above average beer.</description>
	<lastBuildDate>Sat, 26 May 2012 00:55:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/digitalbackcountry" /><feedburner:info uri="digitalbackcountry" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item>
		<title>Using requestAnimationFrame to Optimize Dragging Events</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/WeF-Lbf_OoU/</link>
		<comments>http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/#comments</comments>
		<pubDate>Fri, 25 May 2012 22:57:39 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[requestAnimationFrame]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3061</guid>
		<description><![CDATA[requestAnimationFrame is an API that was originally created by Mozilla but has found its way into Chrome and I think it has huge, huge implications for user interface. A lot of the examples I&#8217;ve seen have talked about how you &#8230; <a href="http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><code><a href="https://developer.mozilla.org/en/DOM/window.requestAnimationFrame">requestAnimationFrame</a></code> is an API that was originally created by Mozilla but has found its way into Chrome and I think it has huge, huge implications for user interface. A lot of the examples I&#8217;ve seen have talked about how you can <a href="http://paulirish.com/2011/requestanimationframe-for-smart-animating/">use it to optimize animation</a>, which makes sense. The basic premise of requestAnimationFrame is that instead of trying to move things out of sync with the browser, you get a hook directly into the browser refresh/redraw and on that refresh you can tell the browser to do something specific with requestAnimationFrame. So it&#8217;s sort of like a queuing system whereby you tell the browser what you want to happen, and when it goes through its next round of repaints, it executes what&#8217;s in that queue. This makes perfect sense for animation since the animation can&#8217;t move any faster than the repaint cycles of the browser. But it also turns out it makes great sense to use it for dragging events as well.</p>
<h2>The Problem:</h2>
<p>For me, the problem manifested when I was working on making the <a href="https://github.com/adobe/brackets/">Brackets</a> sidebar resizable. Like with a lot of resize events I was doing the resize on a <code>mousemove</code> event, so I&#8217;d track the <code>mousemove</code> and then resize the sidebar accordingly as the mouse moved. In theory it seemed like a decent way to do things until I opened it up in the Chrome Developer tools:</p>
<div id="attachment_3063" class="wp-caption aligncenter" style="width: 660px"><a href="http://blog.digitalbackcountry.com/wp-content/uploads/painting_events.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/painting_events.png" alt="" title="painting_events" width="650" height="496" class="size-full wp-image-3063" /></a><p class="wp-caption-text">Holy repaint batman!</p></div>
<p>That screenshot may be a bit confusing, but basically, every mouse move there are a TON of &#8220;Recalculate Style/Paint&#8221; events happening. That means every single mousemove the browser is trying to repaint and so each <code>mousemove</code> event takes about 50 milliseconds to process. That may not sound like much, but think about how often <code>mousemove</code> fires. What&#8217;s worse is that because of how the browser redraws, even though it&#8217;s <em>trying</em> to redraw everything on mouse move, it can&#8217;t actually do that because the <code>mousemove</code> events are happening faster than the browser can redraw. Here&#8217;s the code that&#8217;s doing all that repainting:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #006600; font-style: italic;">/**
     * @private
     * Sets sidebar width and resizes editor. Does not change internal sidebar open/closed state.
     * @param {number} width Optional width in pixels. If null or undefined, the default width is used.
     * @param {!boolean} updateMenu Updates &quot;View&quot; menu label to indicate current sidebar state.
     * @param {!boolean} displayTriangle Display selection marker triangle in the active view.
     */</span>
    <span style="color: #003366; font-weight: bold;">function</span> _setWidth<span style="color: #009900;">&#40;</span>width<span style="color: #339933;">,</span> updateMenu<span style="color: #339933;">,</span> displayTriangle<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// if we specify a width with the handler call, use that. Otherwise use</span>
        <span style="color: #006600; font-style: italic;">// the greater of the current width or 200 (200 is the minimum width we'd snap back to)</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">var</span> prefs                   <span style="color: #339933;">=</span> PreferencesManager.<span style="color: #660066;">getPreferenceStorage</span><span style="color: #009900;">&#40;</span>PREFERENCES_CLIENT_ID<span style="color: #339933;">,</span> defaultPrefs<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            sidebarWidth            <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>prefs.<span style="color: #660066;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarWidth&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        width <span style="color: #339933;">=</span> width <span style="color: #339933;">||</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>$sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> sidebarWidth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> displayTriangle <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;boolean&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> display <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>displayTriangle<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot;block&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;none&quot;</span><span style="color: #339933;">;</span>
            $sidebar.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.triangle-visible&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;display&quot;</span><span style="color: #339933;">,</span> display<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isSidebarClosed<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            $sidebarResizer.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;left&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            $sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span>width<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            $sidebarResizer.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;left&quot;</span><span style="color: #339933;">,</span> width <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #006600; font-style: italic;">// the following three lines help resize things when the sidebar shows</span>
            $sidebar.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.sidebar-selection&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span>width<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            $projectFilesContainer.<span style="color: #660066;">triggerHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;scroll&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            $openFilesContainer.<span style="color: #660066;">triggerHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;scroll&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>width <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                prefs.<span style="color: #660066;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarWidth&quot;</span><span style="color: #339933;">,</span> width<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>updateMenu<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> text <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>isSidebarClosed<span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">&quot;Show Sidebar&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Hide Sidebar&quot;</span><span style="color: #339933;">;</span>
            $sidebarMenuText.<span style="color: #660066;">first</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>text<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        EditorManager.<span style="color: #660066;">resizeEditor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">/**
     * @private
     * Install sidebar resize handling.
     */</span>
    <span style="color: #003366; font-weight: bold;">function</span> _initSidebarResizer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> $mainView               <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.main-view&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            $body                   <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            prefs                   <span style="color: #339933;">=</span> PreferencesManager.<span style="color: #660066;">getPreferenceStorage</span><span style="color: #009900;">&#40;</span>PREFERENCES_CLIENT_ID<span style="color: #339933;">,</span> defaultPrefs<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            sidebarWidth            <span style="color: #339933;">=</span> prefs.<span style="color: #660066;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarWidth&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            startingSidebarPosition <span style="color: #339933;">=</span> sidebarWidth<span style="color: #339933;">;</span>
&nbsp;
        $sidebarResizer.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;left&quot;</span><span style="color: #339933;">,</span> sidebarWidth <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prefs.<span style="color: #660066;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarClosed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            toggleSidebar<span style="color: #009900;">&#40;</span>sidebarWidth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            _setWidth<span style="color: #009900;">&#40;</span>sidebarWidth<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        $sidebarResizer.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dblclick&quot;</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>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #006600; font-style: italic;">// mousedown is fired first. Sidebar is already toggeled open to 1px.</span>
                _setWidth<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                toggleSidebar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $sidebarResizer.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousedown.sidebar&quot;</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>
            <span style="color: #003366; font-weight: bold;">var</span> startX <span style="color: #339933;">=</span> e.<span style="color: #660066;">clientX</span><span style="color: #339933;">;</span>
            $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #006600; font-style: italic;">// check to see if we're currently in hidden mode</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isSidebarClosed<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                toggleSidebar<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            $mainView.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</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>
                <span style="color: #003366; font-weight: bold;">var</span> doResize <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                    newWidth <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">clientX</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// if we've gone below 10 pixels on a mouse move, and the</span>
                <span style="color: #006600; font-style: italic;">// sidebar is shrinking, hide the sidebar automatically an</span>
                <span style="color: #006600; font-style: italic;">// unbind the mouse event.</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>startX <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    toggleSidebar<span style="color: #009900;">&#40;</span>startingSidebarPosition<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    doResize <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                <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>startX <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #006600; font-style: italic;">// reset startX if we're going from a snapped closed position to open</span>
                    startX <span style="color: #339933;">=</span> startingSidebarPosition<span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>doResize<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #006600; font-style: italic;">// if we've moving past 10 pixels, make the triangle visible again</span>
                    <span style="color: #006600; font-style: italic;">// and register that the sidebar is no longer snapped closed.</span>
                    <span style="color: #003366; font-weight: bold;">var</span> forceTriangle <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        forceTriangle <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
&nbsp;
                    _setWidth<span style="color: #009900;">&#40;</span>newWidth<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> forceTriangle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">===</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;body&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            $mainView.<span style="color: #660066;">one</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mouseup.sidebar&quot;</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>
                $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                startingSidebarPosition <span style="color: #339933;">=</span> $sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The main issue is that there is a lot of jQuery selecting (and then setting) that&#8217;s going on. Look at the <code>mousemove</code> event handler and see how much is going on there. That&#8217;s kind of bad. It not only does some math, it also calls <code>_setWidth()</code>, which goes through and modifies significant parts of the DOM. It turns out that it&#8217;s pretty expensive to pull from and modify the DOM, and when it&#8217;s happening a lot every time the mouse moves, you&#8217;re going to get a significant bottleneck. If only there was a way to only do all of that getting and setting when the browser could handle it. That&#8217;s the beauty of <code>requestAnimationFrame</code></p>
<h2>Optimizing with requestAnimationFrame</h2>
<p><code>requestAnimationFrame</code> is a pretty straightforward API to use, but it took me a little bit to figure it out. Basically you call <code>window.webkitRequestAnimationFrame()</code> (that&#8217;s the webkit-specific prefix) and pass in a function that will be called every time the browser gets to the point where it can redraw the page. What&#8217;s a little tricky is that you have to tell the browser to keep listening for it because normally it just gets called once. So what I found easiest was to just call <code>window.webkitRequestAnimationFrame()</code> at the end of the function you&#8217;re passing into <code>requestAnimationFrame</code>. Here&#8217;s my rewritten example of the <code>_initSidebarResizer()</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">function</span> _initSidebarResizer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> $mainView               <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.main-view&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            $body                   <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">body</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            prefs                   <span style="color: #339933;">=</span> PreferencesManager.<span style="color: #660066;">getPreferenceStorage</span><span style="color: #009900;">&#40;</span>PREFERENCES_CLIENT_ID<span style="color: #339933;">,</span> defaultPrefs<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            sidebarWidth            <span style="color: #339933;">=</span> prefs.<span style="color: #660066;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarWidth&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            startingSidebarPosition <span style="color: #339933;">=</span> sidebarWidth<span style="color: #339933;">,</span>
            animationRequest        <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span>
            isMouseDown             <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
        $sidebarResizer.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;left&quot;</span><span style="color: #339933;">,</span> sidebarWidth <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prefs.<span style="color: #660066;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;sidebarClosed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            toggleSidebar<span style="color: #009900;">&#40;</span>sidebarWidth<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            _setWidth<span style="color: #009900;">&#40;</span>sidebarWidth<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        $sidebarResizer.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;dblclick&quot;</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>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>$sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #006600; font-style: italic;">// mousedown is fired first. Sidebar is already toggeled open to 1px.</span>
                _setWidth<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                toggleSidebar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        $sidebarResizer.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousedown.sidebar&quot;</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>
            <span style="color: #003366; font-weight: bold;">var</span> startX <span style="color: #339933;">=</span> e.<span style="color: #660066;">clientX</span><span style="color: #339933;">,</span>
                newWidth <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>startX<span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                doResize <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
            isMouseDown <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #006600; font-style: italic;">// take away the shadows (for performance reasons during sidebarmovement)</span>
            $sidebar.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.scroller-shadow&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;display&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;none&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #006600; font-style: italic;">// check to see if we're currently in hidden mode</span>
            <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isSidebarClosed<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                toggleSidebar<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            animationRequest <span style="color: #339933;">=</span> window.<span style="color: #660066;">webkitRequestAnimationFrame</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> doRedraw<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #006600; font-style: italic;">// only run this if the mouse is down so we don't constantly loop even</span>
                <span style="color: #006600; font-style: italic;">// after we're done resizing.</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isMouseDown<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #006600; font-style: italic;">// if we've gone below 10 pixels on a mouse move, and the</span>
                    <span style="color: #006600; font-style: italic;">// sidebar is shrinking, hide the sidebar automatically an</span>
                    <span style="color: #006600; font-style: italic;">// unbind the mouse event.</span>
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>startX <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        toggleSidebar<span style="color: #009900;">&#40;</span>startingSidebarPosition<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        doResize <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
                    <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>startX <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #006600; font-style: italic;">// reset startX if we're going from a snapped closed position to open</span>
                        startX <span style="color: #339933;">=</span> startingSidebarPosition<span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
&nbsp;
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>doResize<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #006600; font-style: italic;">// if we've moving past 10 pixels, make the triangle visible again</span>
                        <span style="color: #006600; font-style: italic;">// and register that the sidebar is no longer snapped closed.</span>
                        <span style="color: #003366; font-weight: bold;">var</span> forceTriangle <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                            forceTriangle <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                        <span style="color: #006600; font-style: italic;">// for right now, displayTriangle is always going to be false for _setWidth</span>
                        <span style="color: #006600; font-style: italic;">// because we want to hide it when we move, and _setWidth only gets called</span>
                        <span style="color: #006600; font-style: italic;">// on mousemove now.</span>
                        _setWidth<span style="color: #009900;">&#40;</span>newWidth<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
&nbsp;
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>newWidth <span style="color: #339933;">===</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;body&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                    animationRequest <span style="color: #339933;">=</span> window.<span style="color: #660066;">webkitRequestAnimationFrame</span><span style="color: #009900;">&#40;</span>doRedraw<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            $mainView.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</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>
                newWidth <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span>e.<span style="color: #660066;">clientX</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            $mainView.<span style="color: #660066;">one</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mouseup.sidebar&quot;</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>
                isMouseDown <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #006600; font-style: italic;">// replace shadows and triangle</span>
                $sidebar.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.triangle-visible&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;display&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;block&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $sidebar.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.scroller-shadow&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;display&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;block&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                EditorManager.<span style="color: #660066;">resizeEditor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $projectFilesContainer.<span style="color: #660066;">triggerHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;scroll&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $openFilesContainer.<span style="color: #660066;">triggerHandler</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;scroll&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $mainView.<span style="color: #660066;">off</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mousemove.sidebar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                $body.<span style="color: #660066;">toggleClass</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;resizing&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                startingSidebarPosition <span style="color: #339933;">=</span> $sidebar.<span style="color: #660066;">width</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            e.<span style="color: #660066;">preventDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>There are a few changes there but the biggest is that the <code>mousemove</code> event only sets the <code>newWidth</code> property based on the mouse event. Nothing else. That keeps <code>mousemove</code>, which happens a lot, nice and small. Everything else has been moved up to <code>mousedown</code> but wrapped in a function named <code>doResize()</code>, which is passed into <code>window.webkitRequestAnimationFrame()</code>. So instead of doing everything on <code>mousemove</code> I&#8217;m telling the browser that I only want to do the heavy lifting when the browser is going to do a repaint anyway. And because the <code>newWidth</code> is being updated by <code>mousemove</code> I&#8217;ve got the correct width updated and the browser will repaint the sidebar in the correct position.</p>
<p>One thing that confused me was how to stop <code>requestAnimationFrame</code>. There is a <code>cancelRequestAnimationFrame</code> but no one seems to use it because <code>requestAnimationFrame()</code> will run only one extra time when it&#8217;s called unless you tell it otherwise. Unfortunately, that&#8217;s exactly what this code does because we recursively call <code>requestAnimationFrame()</code> as soon as the function finishes so that if the page is still being dragged, we can get new values. But if we don&#8217;t find a way to stop it, the browser will constantly try to repaint even if there&#8217;s not a drag event going on. That&#8217;s why I use the <code>isMouseDown</code> boolean. If the mouse isn&#8217;t down, it&#8217;s a way to tell <code>requestAnimationFrame()</code> that I don&#8217;t want it to fire any more so it&#8217;s going to run once more, then stop.</p>
<p>The result is pretty significant:</p>
<div id="attachment_3062" class="wp-caption aligncenter" style="width: 660px"><a href="http://blog.digitalbackcountry.com/wp-content/uploads/optimized_paint.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/optimized_paint.png" alt="" title="optimized_paint" width="650" height="530" class="size-full wp-image-3062" /></a><p class="wp-caption-text">Ahhh, much better</p></div>
<p>The <code>mousemove</code> event now takes 0ms, and since it happens often, that&#8217;s a fantastic improvement right off the bat. And now all of the layout/paint events are happening based on an Animation Frame Event instead of on <code>mousemove</code>. You can also see spots where <code>mousemove</code> fires a couple of times before the Animation Frame Event fires and in the old code that would have caused an unnecessary layout/repaint series because even though the browser was doing all of the leg-work on it, it wouldn&#8217;t even be able to render it until the next animation frame came up. This way we&#8217;re only having the browser do the work when it can.</p>
<p>This is more of a real-world scenario of <em>why</em> <code>requestAnimationFrame</code> can be helpful. Now that I&#8217;m digging into it more I&#8217;m looking at doing a couple of posts on the basics and starting from a smaller example with <code>requestAnimationFrame</code> but this example made me a believer in how cool it is so I wanted to share.</p>
<p><em>Huge thanks to <a href="https://twitter.com/#!/paul_irish">Paul Irish</a> for info on using requestAnimationFrame and chatting about it. Talking it through helped a ton to wrap my head around it.</em></p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/" data-text="Using requestAnimationFrame to Optimize Dragging Events" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/WeF-Lbf_OoU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/05/using-requestanimationframe-to-optimize-dragging-events/</feedburner:origLink></item>
		<item>
		<title>MAX Moving to Spring 2013</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/TBMF0x4FZSw/</link>
		<comments>http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/#comments</comments>
		<pubDate>Tue, 15 May 2012 03:20:53 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[MAX]]></category>
		<category><![CDATA[max2012]]></category>
		<category><![CDATA[max2013]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3059</guid>
		<description><![CDATA[As Kevin posted this morning, MAX is going to be moving to Spring and the next MAX will take place on May 4-8th instead of in October. It&#8217;s a big change, but one that I&#8217;m excited about. Doing it in &#8230; <a href="http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://max.adobe.com/blog/spring_max.html">Kevin posted this morning</a>, MAX is going to be moving to Spring and the next MAX will take place on May 4-8th instead of in October.</p>
<p>It&#8217;s a big change, but one that I&#8217;m excited about. Doing it in the spring will align more closely with releases and planning, which is ultimately going to make for a better event. We&#8217;ve also completely revamped how we think about content at MAX and as Kevin said, the content is going to focus around 4 major areas:</p>
<ul>
<li>Design and creativity</li>
<li>Web sites, including the latest on HTML5, JavaScript and CSS</li>
<li>Digital publishing, video, and gaming, including the latest on Flash</li>
<li>Applications, particularly for mobile platforms</li>
</ul>
<p>We&#8217;re working on getting some awesome speakers and I&#8217;m excited to be helping put on what is going to be a world class event for designers and developers creating digital content. Over the next few months I&#8217;ll also be talking more about how you can get involved, so stay tuned. And see you in May.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/" data-text="MAX Moving to Spring 2013" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/TBMF0x4FZSw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/05/max-moving-to-spring-2013/</feedburner:origLink></item>
		<item>
		<title>A Response to Benjamin Sandofsky’s Shell Apps</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/oTxXcer9cSk/</link>
		<comments>http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/#comments</comments>
		<pubDate>Tue, 08 May 2012 20:10:29 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[native apps]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[shell apps]]></category>
		<category><![CDATA[web apps]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3055</guid>
		<description><![CDATA[Dion Almaer retweeted an article by Benjamin Sandofsky that covers &#8220;shell apps&#8221;, or HTML/Hybrid apps in contrast to native apps. His thesis seems to be, from his post: If you plan to write an app for iOS or Android, you &#8230; <a href="http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Dion Almaer <a href="https://twitter.com/#!/sunghu/status/199894919706451971">retweeted</a> an <a href="http://sandofsky.com/blog/shell-apps.html">article by Benjamin Sandofsky that covers &#8220;shell apps&#8221;</a>, or HTML/Hybrid apps in contrast to native apps. His thesis seems to be, from his post:</p>
<blockquote><p>
If you plan to write an app for iOS or Android, you will save time and create a better product if you stick to Objective-C and Java, respectively.
</p></blockquote>
<p>Which I agree with in principle, but I also found some of his arguments deeply flawed. He spends a lot of time talking about the cross-platform problem of trying to build a web-experience that looks native on iOS and native on Android. Specifically he calls out differences on iOS and Android:</p>
<blockquote><p>
The harder problems are inconsistencies in platform conventions. The iPhone uses Helvetica as its system font, while Android uses Roboto. iOS transitions between views by sliding new views in from the right, while Android uses a zoom effect.<br />
You could recreate each platform in HTML5, but that requires a lot of work. You could design everything around an iOS look, and settle for things looking weird on Android. You could create a platform agnostic design language, making things equally weird for everyone. In a web view, it’s an uphill battle for consistency, whereas going native provides consistency for free.
</p></blockquote>
<p>Put aside the fact that if you&#8217;re doing native development you&#8217;re writing two different versions <em>anyway</em> (I&#8217;m not sure why that would be a knock against an HTML-centric solution), why do you have to design around an iOS or Android specific look?</p>
<h2>The Native Component Question</h2>
<p>I know it&#8217;s harder, and potentially more expensive, and requires more design sense, but why should developers of HTML-centric apps for mobile devices be locked into the specific UI look and feel of that platform? I&#8217;m not talking about UI paradigms (eg, soft back buttons on iOS, menu buttons on Android), but the specific look of apps. Instead of skinning your application to look like an iOS app and then try to make it look like an Android app, do a design that looks unique and polished that would translate well across both platforms. Then as you start to get into the specific differences (he brings up a good point about transitions) you can implement those device/platform-specific patterns. To me one of the beautiful things about the HTML/JS/CSS stack is the freedom with which we can develop. Bringing that to mobile applications, and letting some great CSS/HTML designers loose on that platform is a great thing. And it&#8217;s one of the reasons I love PhoneGap.</p>
<p>There are definitely some performance implications by going with a shell app/HTML-centric app approach. And as your application gets more complex, those will pop up more and more. So it&#8217;s something to be very aware of. Benjamin quotes some of the reasons he sees for people choosing HTML-centric apps: &#8220;we need to release faster&#8221;, &#8220;write once, run anywhere&#8221;, &#8220;HTML is easier&#8221;. I&#8217;m not sure any of those are great reasons to choose HTML-centric apps. Instead I see the primary benefits of the HTML approach as not being locked into a specific platform or deployment model. With HTML you can repurpose code for mobile web and you can target new platforms as they come (no device is not going to support HTML). But maybe most importantly, with HTML you can easily create custom app experiences. There are some great designers out there who can do amazing things with HTML and choosing something like PhoneGap lets you use those skills to create a unique web-like experience with all of the device features users expect from native apps.</p>
<p>Is it a silver bullet? Definitely not. But I think dismissing HTML-centric apps as being done because they&#8217;re cheaper/faster/easier doesn&#8217;t do them justice. For some kinds of apps, the HTML-centric approach is just <em><strong>better</strong></em>. There&#8217;s an amazing community of people that know HTML/JS/CSS, the web is the ultimate platform for reach and flexibility, and shell-apps bring those two elements to the native app world. That&#8217;s something to celebrate.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/" data-text="A Response to Benjamin Sandofsky\'s Shell Apps" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/oTxXcer9cSk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/05/a-response-to-benjamin-sandofskys-shell-apps/</feedburner:origLink></item>
		<item>
		<title>Presenting PhoneGap at the AT&amp;T Hackathon – Seattle, April 14th</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/XxVDVlUCEfQ/</link>
		<comments>http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 06:05:23 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[att hackathon]]></category>
		<category><![CDATA[hackathon]]></category>
		<category><![CDATA[phonegap]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3052</guid>
		<description><![CDATA[I&#8217;m going to be presenting/talking about PhoneGap at the AT&#038;T Hackathon here in Seattle on Saturday, April 14th. The hackathon actually starts on Friday night, and the last one I was at was a really fun event. If you&#8217;re in &#8230; <a href="http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to be presenting/talking about PhoneGap at the <a href="http://mobileappsea2.eventbrite.com/">AT&#038;T Hackathon here in Seattle</a> on Saturday, April 14th. The hackathon actually starts on Friday night, and the last one I was at was a really fun event. If you&#8217;re in the area I encourage you to come check it out, build an app, and win some prizes. I&#8217;ll be there in and out (not totally sure when I&#8217;m speaking) but I&#8217;m hoping to see some cool PhoneGap projects and chat with developers. Here are the details:</p>
<blockquote>
<p>F5 Networks HQ<br />
401 Elliott Avenue West<br />
Seattle, WA 98119</p>
<p>Friday, April 13, 2012 at 6:00 PM &#8211; Saturday, April 14, 2012 at 9:00 PM (PT)</p>
</blockquote>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/" data-text="Presenting PhoneGap at the AT&T Hackathon - Seattle, April 14th" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/XxVDVlUCEfQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/04/presenting-phonegap-at-the-att-hackathon-seattle-april-14th/</feedburner:origLink></item>
		<item>
		<title>The PhoneGap Starter Project</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/irP0ep1HYjY/</link>
		<comments>http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 23:54:17 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[cordova]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[phonegap build]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3042</guid>
		<description><![CDATA[As I&#8217;ve been digging more and more into PhoneGap Build I&#8217;ve also been discovering that there are some gaps in the workflow and that it&#8217;s not always easy to go from a feature I want to use to a cross-platform &#8230; <a href="http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;ve been digging more and more into <a href="http://build.phonegap.com">PhoneGap Build</a> I&#8217;ve also been discovering that there are some gaps in the workflow and that it&#8217;s not always easy to go from a feature I want to use to a cross-platform implementation for it. Most of the time I&#8217;ll use the PhoneGap documentation as a starter point and then try to wrangle it into a local project and then make that local project work with PhoneGap Build. One of my favorite features of PhoneGap Build is that it can pull directly from a git/svn repository and build binaries from that repo. So last night I did a little bit of work to pull a couple of features/code from the documentation into GitHub projects that can be quickly loaded into PhoneGap Build and turned into binaries. Fueled by some <a href="http://www.nwpeaksbrewery.com/">NW Peaks beer</a> last night I built some initial ideas for the <a href="https://github.com/phonegap-starter">PhoneGap Starter Project</a>. As you can see it&#8217;s pretty sparse but there are a few goals I have in mind.</p>
<ul>
<li>Showing how to structure projects for use in PhoneGap build. I struggled with this a bit&#8211;with things like making the config.xml file work, setting the files up correctly (in a www folder, and referencing cordova.js in the script tag but not including it), etc. Each one of these projects works with PhoneGap Build out of the box.</li>
<li>Linking documentation to a real project. The documentation for PhoneGap is pretty good and I wanted an easy, out-of-the-box way for people to see the features in action. So I took the code from the documentation and turned them into projects. Load them into PhoneGap Build and you can see them in action on your device in a matter of seconds.</li>
<li>Helping fix documentation! I&#8217;m looking for ways to contribute to the <a href="http://incubator.apache.org/cordova/">Cordova project</a> and some of the documentation code is a bit out of date. What better way than to go through that code, make sure it works, fix bugs, and then submit them back?</li>
<li>Showing how kick ass PhoneGap Build is. I really, really like PhoneGap Build and once you get a good workflow down I think it&#8217;s a great help in creating binaries quickly. This shows it in action.</li>
</ul>
<p>To use the project in PhoneGap Build, just create a new app from SVN and put in the URL of the repo.</p>
<div id="attachment_3043" class="wp-caption aligncenter" style="width: 470px"><a href="http://blog.digitalbackcountry.com/wp-content/uploads/phoengap_build_add_app1.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/phoengap_build_add_app1.png" alt="Adding an App to PhoneGap Build " title="Adding an App to PhoneGap Build " width="460" height="460" class="size-full wp-image-3043" /></a><p class="wp-caption-text">Creating a new app based on Git/SVN project</p></div>
<p>I&#8217;m going to be filling out some of other documented features over the week as well as doing an example for the ChildBrowser plugin. I&#8217;m curious to hear if this seems useful for people or solves any kind of pain point. Since it helps me find the gaps/issues in the documentation, it serves a higher purpose for me, but if it seems useful then I&#8217;ll work on keeping it up to date.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/" data-text="The PhoneGap Starter Project" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/irP0ep1HYjY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/04/the-phonegap-starter-project/</feedburner:origLink></item>
		<item>
		<title>Web Versus Native – Asking the Wrong Questions</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/jFQAXdFWuUA/</link>
		<comments>http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 17:57:35 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[mobile apps]]></category>
		<category><![CDATA[open web]]></category>
		<category><![CDATA[web applications]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3037</guid>
		<description><![CDATA[There&#8217;s been a lot of talk lately about web apps versus native. It&#8217;s not that the question has ever gone away, but just over the past couple of weeks it seems like it&#8217;s been called out a bit more in &#8230; <a href="http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a lot of talk lately about web apps versus native. It&#8217;s not that the question has ever gone away, but just over the past couple of weeks it seems like it&#8217;s been called out a bit more in blog posts. There <a href="http://pewinternet.org/Reports/2012/Future-of-Apps-and-Web/Overview.aspx">was a Pew Internet report</a> that covered some of the pros/cons of going web or native. Darryl Taft, one of my favorite press guys, <a href="http://www.eweek.com/c/a/Application-Development/Mobile-App-Development-Web-or-Native-That-Is-the-Question-880358/">did a writeup earlier this month</a> on the landscape of web versus native and some of the companies involved in blending those two worlds. And then today I <a href="http://venturebeat.com/2012/04/02/yahoo-node-open-source-mojito/">saw news about Mojito, a hybrid client-server solution from Yahoo</a>, which is part of a wider initiative called Cocktails with the aim of &#8220;<a href="http://venturebeat.com/2011/11/09/mobile-web/">making web applications feel native</a>&#8220;. And that got me thinking about the problems that people are trying to solve when it comes to web apps on mobile devices.</p>
<p>Web apps are in a tough spot when it comes to native, but they&#8217;re getting better. As I see it, one of the main problems with web apps is that they aren&#8217;t currently <em>better</em>. They&#8217;re cheaper, they&#8217;re faster (to write), and they allow you to target more platforms, but they&#8217;re not better. What&#8217;s even worse is that you could argue there are only 2 platforms for mobile that matter right now, Android and iOS. But it was the exact same situation back in 2003/2004 when the web really started coming into its own as an app platform and taking away from traditional native apps on the desktop. The one problem is that back then the web apps <em>were</em> better. They didn&#8217;t look as fancy and they didn&#8217;t run quite as fast, but there were few things that people needed to do that the web couldn&#8217;t do. I remember talking about AIR and mentioning things like drag and drop, file system access, and file type associations. Those were nice, but people didn&#8217;t really need them. What made web apps better for end users was the fact that they ran everywhere, were lightweight, always up-to-date and moved with the user so when they switched between the library, school, work, and home, their stuff went with them.</p>
<p>But fast forward to today. We never leave our mobile devices. They&#8217;re always with us. Sometimes we change contexts from our mobile device to a desktop/laptop/tablet (think email) but ultimately one of the things that made web apps so great, that they moved with the user, has been completely negated by smartphones. And increasingly, what web apps can&#8217;t do is much more important than what web apps couldn&#8217;t do 5 years ago. All of the sensors; GPS, Accelerometer, Camera, not to mention the data on the phone, things like contacts, that can be used to make things on the device so much more personal and completely change the experience. Some of the basic ones are available to web apps, and the specs are in place to get more, but there&#8217;s still a significant disconnect between what can be done with native apps on the device and what can be done on the mobile web.</p>
<p>To me that&#8217;s the biggest worry for the web on mobile devices right now. Sure, performance isn&#8217;t ideal, but as the browsers get better and devices get more powerful, that one will fix itself. The technology is there in the form of Canvas, SVG, great JS frameworks, faster JS performance. So the core interactive features work on these devices (with some performance caveats). But the benefits of the web are in many ways nullified by smartphones today. The web needs to come up with something that makes it better once again. And the deck is really, really stacked against it. Think of the distribution model of apps and in-app purchases. I think you could argue that those aren&#8217;t great for customers as much as they are great for content creators. Mobile apps are easier to monetize, easier to track, and easier to manage than the web right now. And on one hand, that&#8217;s fantastic. Finally designers and developers can directly make money off of their creations. But it&#8217;s coming at the expense of the web.</p>
<p>In order for web apps to thrive again the web community needs to start thinking about how mobile web apps can be better and more useful to customers than native apps. I have no doubt that it&#8217;s going to happen. How many times have you said to yourself &#8220;I don&#8217;t want your app, I just want to see the content&#8221; while browsing around the web on a mobile browser? So the sentiment from users is there, but for now the web just doesn&#8217;t provide enough value for users to get beyond the inflection point. So I&#8217;m hoping the conversation starts to move away from web apps not being fast enough, or &#8220;feeling native enough&#8221; to one of how web apps can be better than native from a user perspective. It&#8217;s going to be a fun conversation to watch unfold.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/" data-text="Web Versus Native - Asking the Wrong Questions" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/jFQAXdFWuUA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/04/web-versus-native-asking-the-wrong-questions/</feedburner:origLink></item>
		<item>
		<title>Experimenting with CSS Exclusions</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/Yu-Pl3207j4/</link>
		<comments>http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/#comments</comments>
		<pubDate>Fri, 30 Mar 2012 08:14:26 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[Beer]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[adobe webkit]]></category>
		<category><![CDATA[css exclusions]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3022</guid>
		<description><![CDATA[Okay, this is going to be scattered and on the cutting edge side, so buckle in. Adobe has been hard at work making the web a little bit richer when it comes to how type is displayed. A great example &#8230; <a href="http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Okay, this is going to be scattered and on the cutting edge side, so buckle in. Adobe <a href="http://corlan.org/2012/03/16/css-bleeding-edge-features/">has been hard at work</a> making the web a little bit richer when it comes to how type is displayed. A great example of that is <a href="http://labs.adobe.com/technologies/cssregions/">CSS Regions</a>, which let you create linked islands that text can flow between so you have a lot of control over how text gets laid out on the screen. That&#8217;s currently in the &#8220;Canary&#8221; builds of Chrome and if you go to about://flags and turn on &#8220;CSS Regions&#8221; you&#8217;ll be able to view the demos. The other thing we&#8217;ve been working on is a bit further out, but it&#8217;s in the same vein. It&#8217;s called <a href="http://dev.w3.org/csswg/css3-exclusions/">CSS exclusions</a>. It essentially lets you create more interesting islands of text in the form of shapes that text will flow around. At this stage it&#8217;s still very, very early. In fact, the only way to test CSS exclusions content is with a special build of WebKit that&#8217;s <a href="http://labs.adobe.com/downloads/cssregions.html">available on Adobe Labs</a>.</p>
<h2>The Backstory</h2>
<p>A lot of the demos associated with these features are associated with magazines, and especially with the iPad 3 coming out, it&#8217;s going to be critical to be able to build expressive content that scales. Since magazines are mostly text, expressive text will be a big deal. I&#8217;ve been mulling over doing a beer-related magazine and figured it would be cool to try out some of the CSS demos to create something that might look unique and fit in a beer magazine. So I thought &#8220;hey, I could create shapes of different beer glasses and run text through those!&#8221; That was the basic premise. As I dug in, I found a couple of caveats. Most I&#8217;ll get to throughout the post, but the biggest one is that there currently isn&#8217;t a version of WebKit that has both CSS Exclusions and support for flowing across CSS Regions. So my original idea ran into a small roadblock but I&#8217;ll be able to fix that down the road.</p>
<h2>Creating regions</h2>
<p>The CSS Exclusions spec supports SVG&#8217;s basic shapes. That includes circles, rectangles, and polygons. At this point it can&#8217;t do arbitrary path data but you will be able to use SVG data according to the spec. So I started with creating the various types of beer glasses in Illustrator with the polygon tool. Then I had to set up the glasses on the page and make text flow correctly. The standard method seems to be to create two CSS classes, one for the properties that every region or shape will have, and another class for the specific region, in this case, glass type. I called my main region <code>container</code> and it looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">     .container<span style="color: #00AA00;">&#123;</span>
          <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span><span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span><span style="color: #933;">500px</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span><span style="color: #933;">300px</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span><span style="color: #993333;">justify</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">margin-top</span><span style="color: #00AA00;">:</span><span style="color: #933;">0px</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span><span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
&nbsp;
          -webkit-wrap-shape-mode<span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">content</span><span style="color: #00AA00;">;</span>
          -webkit-render-wrap-shape<span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
          -webkit-hyphens<span style="color: #00AA00;">:</span><span style="color: #993333;">auto</span><span style="color: #00AA00;">;</span>
     <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>The main properties are those three on the bottom. The first one tells the browser what I&#8217;m doing, and that&#8217;s wrapping the content within a shape. I think the other option here is <code>around</code>, which would make the shape an exclusion but I don&#8217;t think that&#8217;s working in my build of WebKit (or I&#8217;m doing it wrong). The <code>render-wrap-shape</code> is good for debugging as it shows you an outline of the shape so you can see how it&#8217;s appearing. I found this incredibly helpful as I laid objects out on the page. The last one, <code>hyphens</code>, lets you tell the browser how you want it to break up text. If you go for <code>none</code> there, it will only flow full words within the content. Otherwise it fills the content as much as it can before breaking words with a hyphen. For fuller-looking shapes, go with hyphens set to auto.</p>
<p>Next I had to set up the specific glass shapes. The hardest part for me was lining things up correctly. The way I created the polygons I think made it tougher to lay out. It also doesn&#8217;t change as you resize the page because I&#8217;m not using percentages (if that&#8217;s even possible with polygon objects). It looks kind of ugly but to define a shape we just have to use <code>webkit-wrap-shape</code> and give it the values. Here are a couple I did.</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">     <span style="color: #cc00cc;">#irishpint1</span> <span style="color: #00AA00;">&#123;</span>
          <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span><span style="color: #933;">0px</span><span style="color: #00AA00;">;</span>
     <span style="color: #00AA00;">&#125;</span>
&nbsp;
    <span style="color: #6666ff;">.irishpint</span> <span style="color: #00AA00;">&#123;</span>
          -webkit-wrap-shape<span style="color: #00AA00;">:</span> polygon<span style="color: #00AA00;">&#40;</span><span style="color: #933;">157px</span><span style="color: #00AA00;">,</span><span style="color: #933;">473px</span> <span style="color: #933;">106px</span><span style="color: #00AA00;">,</span><span style="color: #933;">472px</span> <span style="color: #933;">93px</span><span style="color: #00AA00;">,</span><span style="color: #933;">453px</span> <span style="color: #933;">91px</span><span style="color: #00AA00;">,</span><span style="color: #933;">432px</span> <span style="color: #933;">87px</span><span style="color: #00AA00;">,</span><span style="color: #933;">401px</span> <span style="color: #933;">84px</span><span style="color: #00AA00;">,</span><span style="color: #933;">368px</span> <span style="color: #933;">78px</span><span style="color: #00AA00;">,</span><span style="color: #933;">332px</span> <span style="color: #933;">70px</span><span style="color: #00AA00;">,</span><span style="color: #933;">294px</span> <span style="color: #933;">61px</span><span style="color: #00AA00;">,</span><span style="color: #933;">255px</span> <span style="color: #933;">57px</span><span style="color: #00AA00;">,</span><span style="color: #933;">225px</span> <span style="color: #933;">55px</span><span style="color: #00AA00;">,</span><span style="color: #933;">191px</span> <span style="color: #933;">55px</span><span style="color: #00AA00;">,</span><span style="color: #933;">165px</span> <span style="color: #933;">57px</span><span style="color: #00AA00;">,</span><span style="color: #933;">128px</span> <span style="color: #933;">63px</span><span style="color: #00AA00;">,</span><span style="color: #933;">118px</span> <span style="color: #933;">165px</span><span style="color: #00AA00;">,</span><span style="color: #933;">118px</span> <span style="color: #933;">274px</span><span style="color: #00AA00;">,</span><span style="color: #933;">120px</span> <span style="color: #933;">279px</span><span style="color: #00AA00;">,</span><span style="color: #933;">128px</span> <span style="color: #933;">282px</span><span style="color: #00AA00;">,</span><span style="color: #933;">164px</span> <span style="color: #933;">282px</span><span style="color: #00AA00;">,</span><span style="color: #933;">190px</span> <span style="color: #933;">282px</span><span style="color: #00AA00;">,</span><span style="color: #933;">226px</span> <span style="color: #933;">274px</span><span style="color: #00AA00;">,</span><span style="color: #933;">263px</span> <span style="color: #933;">267px</span><span style="color: #00AA00;">,</span><span style="color: #933;">296px</span> <span style="color: #933;">257px</span><span style="color: #00AA00;">,</span><span style="color: #933;">337px</span> <span style="color: #933;">253px</span><span style="color: #00AA00;">,</span><span style="color: #933;">368px</span> <span style="color: #933;">250px</span><span style="color: #00AA00;">,</span><span style="color: #933;">397px</span> <span style="color: #933;">246px</span><span style="color: #00AA00;">,</span><span style="color: #933;">427px</span> <span style="color: #933;">244px</span><span style="color: #00AA00;">,</span><span style="color: #933;">453px</span> <span style="color: #933;">233px</span><span style="color: #00AA00;">,</span><span style="color: #933;">473px</span> <span style="color: #933;">173px</span><span style="color: #00AA00;">,</span><span style="color: #933;">473px</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
     <span style="color: #00AA00;">&#125;</span>
&nbsp;
&nbsp;
     <span style="color: #cc00cc;">#weissbierflute1</span> <span style="color: #00AA00;">&#123;</span>
          <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span><span style="color: #933;">250px</span><span style="color: #00AA00;">;</span>    
     <span style="color: #00AA00;">&#125;</span>
&nbsp;
     <span style="color: #6666ff;">.weissbierflute</span> <span style="color: #00AA00;">&#123;</span>
          -webkit-wrap-shape<span style="color: #00AA00;">:</span>  polygon<span style="color: #00AA00;">&#40;</span><span style="color: #933;">104px</span><span style="color: #00AA00;">,</span><span style="color: #933;">470px</span> <span style="color: #933;">82px</span><span style="color: #00AA00;">,</span><span style="color: #933;">459px</span> <span style="color: #933;">81px</span><span style="color: #00AA00;">,</span><span style="color: #933;">439px</span> <span style="color: #933;">89px</span><span style="color: #00AA00;">,</span><span style="color: #933;">400px</span> <span style="color: #933;">105px</span><span style="color: #00AA00;">,</span><span style="color: #933;">344px</span> <span style="color: #933;">102px</span><span style="color: #00AA00;">,</span><span style="color: #933;">294px</span> <span style="color: #933;">86px</span><span style="color: #00AA00;">,</span><span style="color: #933;">238px</span> <span style="color: #933;">72px</span><span style="color: #00AA00;">,</span><span style="color: #933;">183px</span> <span style="color: #933;">66px</span><span style="color: #00AA00;">,</span><span style="color: #933;">128px</span> <span style="color: #933;">62px</span><span style="color: #00AA00;">,</span><span style="color: #933;">77px</span> <span style="color: #933;">59px</span><span style="color: #00AA00;">,</span><span style="color: #933;">39px</span> <span style="color: #933;">58px</span><span style="color: #00AA00;">,</span><span style="color: #933;">17px</span> <span style="color: #933;">57px</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">0</span> <span style="color: #933;">280px</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">0</span> <span style="color: #933;">279px</span><span style="color: #00AA00;">,</span><span style="color: #933;">17px</span> <span style="color: #933;">278px</span><span style="color: #00AA00;">,</span><span style="color: #933;">41px</span> <span style="color: #933;">276px</span><span style="color: #00AA00;">,</span><span style="color: #933;">74px</span> <span style="color: #933;">271px</span><span style="color: #00AA00;">,</span><span style="color: #933;">128px</span> <span style="color: #933;">265px</span><span style="color: #00AA00;">,</span><span style="color: #933;">182px</span> <span style="color: #933;">251px</span><span style="color: #00AA00;">,</span><span style="color: #933;">238px</span> <span style="color: #933;">234px</span><span style="color: #00AA00;">,</span><span style="color: #933;">299px</span> <span style="color: #933;">232px</span><span style="color: #00AA00;">,</span><span style="color: #933;">344px</span> <span style="color: #933;">248px</span><span style="color: #00AA00;">,</span><span style="color: #933;">400px</span> <span style="color: #933;">255px</span><span style="color: #00AA00;">,</span><span style="color: #933;">434px</span> <span style="color: #933;">252px</span><span style="color: #00AA00;">,</span><span style="color: #933;">463px</span> <span style="color: #933;">215px</span><span style="color: #00AA00;">,</span><span style="color: #933;">473px</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
     <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>So they&#8217;re some semi-complex polygons. I also used the <code>div</code> tags to set up padding and lay things out. One of the things I learned is that CSS regions/shapes can only be applied through classes, you can&#8217;t define the properties based on id&#8217;s. But that may change.</p>
<p>So with all of those glass polygons, it looks like this:</p>
<div id="attachment_3023" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_001.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_001-300x240.png" alt="What the page looks like in a browser that supports CSS Exclusions" title="CSS Exclusions with Beer Glass Shapes" width="300" height="240" class="size-medium wp-image-3023" align="center" /></a><p class="wp-caption-text">What the page looks like in a browser that supports CSS Exclusions</p></div>
<p>That <a href="https://github.com/ryanstewart/CSS-Exclusions-Demo/blob/master/index_001.html">page is up on GitHub</a> but you won&#8217;t be able to view it in your browser so you&#8217;ll have to be looking at it with the special browser from Adobe labs.</p>
<h2>Making it More Interesting</h2>
<p>After this I thought it would be cool to do a bit more with the shapes. Beer has a rating scale <a href="http://www.twobeerdudes.com/beer/srm">for color called the SRM scale</a>. Types of beer have a general range of SRM scales and since some glasses roughly correspond to specific types of beers I wanted to see about creating a background for each shape that would correspond to the SRM scale. But even more than that I wanted it to change with the glass so as the glass got narrower, the background would become more transparent just like a real beer glass. Unfortunately it didn&#8217;t work quite the way I wanted, but I learned a bit about using CSS shapes along the way. Originally I just started by giving the <code>div</code> a background:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">     <span style="color: #cc00cc;">#irishpint1</span> <span style="color: #00AA00;">&#123;</span>
          <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span><span style="color: #933;">0px</span><span style="color: #00AA00;">;</span>
          <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> -webkit-gradient<span style="color: #00AA00;">&#40;</span>linear<span style="color: #00AA00;">,</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">,</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">bottom</span><span style="color: #00AA00;">,</span>
                                             color-stop<span style="color: #00AA00;">&#40;</span>.8<span style="color: #00AA00;">,</span> rgba<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">152</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">83</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">54</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">1</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">,</span>
                                             color-stop<span style="color: #00AA00;">&#40;</span>.2<span style="color: #00AA00;">,</span> rgba<span style="color: #00AA00;">&#40;</span><span style="color: #cc66cc;">152</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">83</span><span style="color: #00AA00;">,</span><span style="color: #cc66cc;">54</span><span style="color: #00AA00;">,</span>.7<span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
     <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>But the CSS shapes/exclusions don&#8217;t actually change the shape of the <code>div</code>, they&#8217;re only worried about wrapping the text within the div. So my page just looked like this:</p>
<div id="attachment_3024" class="wp-caption aligncenter" style="width: 191px"><a href="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_002.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_002-181x300.png" alt="What the div tag looked like when trying to set the background" title="Div tag Gradient" width="181" height="300" class="size-medium wp-image-3024" align="center" /></a><p class="wp-caption-text">What the div tag looked like when trying to set the background</p></div>
<p>Luckily <code>webkit-mask-image</code> came to the rescue. With that, I could create a mask based on a file, in my case an SVG file, and use that to mask a block element like a <code>div</code> tag. So I went through and created an SVG file for every glass shape and then used those as the mask and set the background accordingly with <code>rbga()</code> properties in a gradient. The final version looks like this:</p>
<p><a href="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_003.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_003-1024x488.png" alt="" title="CSS Exclusions with gradient background" width="584" height="278" class="aligncenter size-large wp-image-3025" /></a></p>
<p><a href="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_004.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_004-1024x487.png" alt="" title="CSS Exclusions Page 2" width="584" height="277" class="aligncenter size-large wp-image-3026" /></a></p>
<p>And here&#8217;s a clean(ish) version without the backgrounds. I kind of like this one better.</p>
<p><a href="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_005.png"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/glasses_005-1024x792.png" alt="" title="CSS Exclusions with no background on the div tag" width="584" height="451" class="aligncenter size-large wp-image-3029" /></a></p>
<p><strong>Update:</strong> If you have a browser that supports exclusions you can <a href="http://www.digitalbackcountry.com/demos/cssregions/index_001.html">check out the demo here</a>.</p>
<h2>Final Thoughts</h2>
<p>It&#8217;s really, really early for CSS Exclusions but there is a LOT of potential there and even the stuff that works now is a lot of fun to use. This was just an initial dive into the feature to kick the tires, and because it&#8217;s so new, there are a lot of gaps both in my knowledge and what I was able to do. One of the things I tried was using CSS3 transitions to animate the <code>-webkit-wrap-shape</code> property. That didn&#8217;t seem to work, it could be on the roadmap.</p>
<p>It&#8217;s a fun feature and it&#8217;s really fun to be able to give it a shot while it&#8217;s still in the early stages. For magazines or any kind of rich text content, exclusions are going to be a fantastic way to make stuff pop. If you want, you can <a href="https://github.com/ryanstewart/CSS-Exclusions-Demo">check out the project on Github</a>. I&#8217;ll probably be modifying it and improving it as the spec evolves.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/" data-text="Experimenting with CSS Exclusions" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/Yu-Pl3207j4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/03/experimenting-with-css-exclusions/</feedburner:origLink></item>
		<item>
		<title>Installing the ChildBrowser Plugin for iOS with PhoneGap/Cordova 1.5</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/Us43b3AopQE/</link>
		<comments>http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 00:41:25 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[childbrowser]]></category>
		<category><![CDATA[cordova]]></category>
		<category><![CDATA[phonegap]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3014</guid>
		<description><![CDATA[Note: I&#8217;ve added a ChildBrowser example to the PhoneGap Starter project. It won&#8217;t help with native issues, but if you&#8217;re using PhoneGap Build it might give you a working head start. I&#8217;ve seen a bunch of people who are new &#8230; <a href="http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Note:</strong> <em>I&#8217;ve added a <a href="https://github.com/phonegap-starter/ChildBrowserPlugin">ChildBrowser example</a> to the PhoneGap Starter project. It won&#8217;t help with native issues, but if you&#8217;re using PhoneGap Build it might give you a working head start.</em></p>
<p>I&#8217;ve seen a bunch of people who are new to PhoneGap/Cordova struggle with getting the ChildBrowser up and running. I fought with it today as well and most of my mistakes were based on old blog posts so I wanted to do a quick post that hopefully shows up in Google for people running into the same problems I had.</p>
<p>I&#8217;m starting with a blank project. The ChildBrowser plugin I&#8217;m using <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/ChildBrowser">is here</a> which as of this writing has been updated to support Cordova 1.5 with some potential backwards compatibility with 1.4.1. The simplest thing is to probably just <a href="https://github.com/phonegap/phonegap-plugins/downloads">download the source as a zip</a>.</p>
<p>I&#8217;m starting with a blank project that has my <code>www</code> folder already referenced by the project. Here are the rest of the steps.</p>
<p>1. Drag all of the .m, .h, and .bundle file(s) from the ChildBrowser folder to the Plugins folder of your project. Make sure the copy option is selected (I think it&#8217;s the default).</p>
<p><img src="http://blog.digitalbackcountry.com/wp-content/uploads/childbrowser_001.png" alt="" title="childbrowser_001" width="400" height="268" class="aligncenter size-full wp-image-3015" /></p>
<p><img src="http://blog.digitalbackcountry.com/wp-content/uploads/childbrowser_002.png" alt="" title="childbrowser_002" width="230" height="162" class="aligncenter size-full wp-image-3016" /></p>
<p>2. In your project, under the Supporting Files folder, open the Cordova.plist file. You&#8217;ll see a bunch of key/value pairs and the one you want is under Plugins. You&#8217;ll need to add 2 by clicking the add button that shows when you highlight the Plugins section.</p>
<pre>Key: ChildBrowser, Type:String, Value: ChildBrowser.js</pre>
<pre>Key: ChildBrowserCommand, Type:String, Value:ChildBrowserCommand</pre>
<p>3. You also need to make sure that your application can call the external URL you want to load. This is also handled in the Cordova.plist file under ExternalHosts. Add any of the URLs you plan to open to that. You just need the Value, so you can leave the Key as the default. And remember that you can use wildcards, so the entry below lets you go to any subdomain of Google.</p>
<pre>Key: Item 0, Type: String, Value: *.google.com</pre>
<p><img src="http://blog.digitalbackcountry.com/wp-content/uploads/childbrowser_003.png" alt="" title="childbrowser_003" width="527" height="170" class="aligncenter size-full wp-image-3017" /></p>
<p>4. Copy over <code>ChildBrowser.js</code> (or the minified version) from the project files to your www folder.</p>
<p><img src="http://blog.digitalbackcountry.com/wp-content/uploads/childbrowser_004.png" alt="" title="childbrowser_004" width="208" height="145" class="aligncenter size-full wp-image-3018" /></p>
<p>Now you need to go into your HTML and JS files and make some changes. The biggest one is to reference the <code>ChildBrowser.js</code> file.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot;charset=&quot;utf-8&quot;src=&quot;ChildBrowser.js&quot;&gt;&lt;/script&gt;</pre></div></div>

<p>And here&#8217;s the modified JavaScript I used to get it to work. I created a <code>childbrowser</code> variable, then in <code>onDeviceReady</code> added a call to the <code>install</code> method of the <code>ChildBrowser</code> object. Finally I created a function that handles the URL opening.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">    <span style="color: #003366; font-weight: bold;">var</span> childbrowser<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> onBodyLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
document.<span style="color: #660066;">addEventListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;deviceready&quot;</span><span style="color: #339933;">,</span> onDeviceReady<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> onDeviceReady<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #006600; font-style: italic;">// do your thing!</span>
childbrowser <span style="color: #339933;">=</span> ChildBrowser.<span style="color: #660066;">install</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
navigator.<span style="color: #660066;">notification</span>.<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Cordova is working&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">function</span> onLinkClick<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>   
&nbsp;
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>childbrowser <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        childbrowser.<span style="color: #660066;">onLocationChange</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>loc<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;In index.html new loc = &quot;</span> <span style="color: #339933;">+</span> loc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        childbrowser.<span style="color: #660066;">onClose</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><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;In index.html child browser closed&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        childbrowser.<span style="color: #660066;">onOpenExternal</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><span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;In index.html onOpenExternal&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
        window.<span style="color: #660066;">plugins</span>.<span style="color: #660066;">childBrowser</span>.<span style="color: #660066;">showWebPage</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;http://google.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>  
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This definitely works with Cordova 1.5 and I&#8217;m pretty sure it should work with 1.4. Notice that there&#8217;s <strong>no need to change any of the .m/.h files</strong>, so don&#8217;t worry about importing anything or changing code that you may have seen in other blog posts.</p>
<p>And I&#8217;m pretty sure this is basically how all Cordova/PhoneGap plugins work. Simply copy the OS-specific files into the plugin directory and then copy the JS files and reference them. But ChildBrowser threw me for a loop because of all the blog noise that referenced past versions. So hopefully this helps someone.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/" data-text="Installing the ChildBrowser Plugin for iOS with PhoneGap/Cordova 1.5" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/Us43b3AopQE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/03/installing-the-childbrowser-plugin-for-ios-with-phonegapcordova-1-5/</feedburner:origLink></item>
		<item>
		<title>Speaking at the LA PhoneGap Meetup on Wednesday, February 15th</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/rMInfVa1J8Q/</link>
		<comments>http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 16:49:50 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[Adobe]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[los angeles]]></category>
		<category><![CDATA[phonegap]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3008</guid>
		<description><![CDATA[I&#8217;m doing a presentation in conjunction with HTC at the LA PhoneGap meetup on Wednesday, February 15th, so if you&#8217;re in the area, come by. I&#8217;m going to be covering Debugging and Deploying with PhoneGap, which includes talking about using &#8230; <a href="http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m doing a presentation in conjunction with HTC at the <a href="http://www.meetup.com/laphonegap/events/48814092/">LA PhoneGap meetup on Wednesday, February 15th</a>, so if you&#8217;re in the area, come by. I&#8217;m going to be covering Debugging and Deploying with PhoneGap, which includes talking about using the debug tools like weinre and using PhoneGap Build to deploy it across a bunch of platforms. From the site:</p>
<blockquote>
<p><strong>AGENDA:</strong></p>
<p>1. Android Tablet Development (Lance Nanek &#038; Michael Ludden, HTC)</p>
<p>2. Debugging and Deploying with PhoneGap (Ryan Stewart, Adobe) </p>
<p>===============================</p>
<p><strong>Android Tablet Development.</strong> HTCdev has created a PhoneGap plugin for their Scribe Pen enabled tablets, one of which they will be giving away to a lucky developer. Check out <a href="http://www.htcdev.com">www.htcdev.com</a> for details.</p>
<p>Two of their lead developer evangelists will be demonstrating how HTCdev can help apps gain visibility, and how to easily program apps that let you create using Pen-based input.</p>
<p>Presenters:</p>
<p>Michael Ludden (<a href="http://twitter.com/Michael_Ludden">twitter.com/Michael_Ludden</a>) is a Developer Evangelist at HTC. Tasked with developer enablement, Michael is focusing on how best to help developers differentiate without fragmenting on HTC devices – creating great, unique user experiences that widen appeal of apps and catch that all important user’s attention. He will be showing how developers can take advantages of HTC’s app promotional programs, support, co marketing and robust toolsets to maximize an app’s influence. He has a bachelor’s degree from UCLA and has been working in development and with developers for years.</p>
<p>Lance Nanek (<a href="http://nanek.name">http://nanek.name</a>) is a Developer Evangelist at HTC. He has ten years of experience in information technology: implementing web metrics for ibm.com at IBM, writing Java web applications at State University of New York System Administration, and working on Android apps for many companies, including CardioTrainer by WorkSmart Labs with over three million downloads. He has a master’s degree in Computer Science from State University of New York University at Albany.</p>
<p><strong>Debugging and Deploying with PhoneGap.</strong> In this session, Ryan Stewart, a web developer evangelist from Adobe, will cover how to debug and deploy PhoneGap applications. He will talk about how to use Winere to get some insight into how your PhoneGap application is behaving on the device and how to set up the application so that it can easily be debugged. He will also cover some of the deployment options, including a deep dive on the ways to use PhoneGap Build to deploy quickly across multiple devices and operating systems. You&#8217;ll learn about things to be aware of, and things you can do to streamline the process.</p>
</blockquote>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/" data-text="Speaking at the LA PhoneGap Meetup on Wednesday, February 15th" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/rMInfVa1J8Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/02/speaking-at-the-la-phonegap-meetup-on-wednesday-february-15th/</feedburner:origLink></item>
		<item>
		<title>Hoping for a Web App Future</title>
		<link>http://feedproxy.google.com/~r/digitalbackcountry/~3/oBsZFZVPjMY/</link>
		<comments>http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 22:04:34 +0000</pubDate>
		<dc:creator>ryanstewart</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[installable web apps]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[phonegap]]></category>

		<guid isPermaLink="false">http://blog.digitalbackcountry.com/?p=3003</guid>
		<description><![CDATA[If I think back to 2006/2007 I was very happy with how things were shaking out. The web was on the upswing and we were moving away from native applications. All of the great things about the web&#8211;its ubiquity, its &#8230; <a href="http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If I think back to 2006/2007 I was very happy with how things were shaking out. The web was on the upswing and we were moving away from native applications. All of the great things about the web&#8211;its ubiquity, its freedom, its openness&#8211;were being harnessed to create native-like experiences that, I hoped at the time, would see us all do away with native apps. At the time, there wasn&#8217;t much (I thought) that web apps couldn&#8217;t do that we needed native apps for. How wrong I was. With the introduction of the iPhone, and subsequent smartphone releases, we&#8217;ve seen a huge shift back to native applications. Part of that is performance, right now native apps just feel better than mobile web apps, but it also came about because of just how many things native mobile apps could do. Geolocation, accelerometers, contact info&#8211;the smartphone showed how many things &#8220;apps&#8221; needed access to and for the most part those features have been exclusive to native applications. So just as the web was starting to really take off, we&#8217;ve slid back into native application territory.</p>
<p>It bummed me out, and still does. I thought AIR was an okay solution to the problem, but by the time AIR came around it was pretty clear that &#8220;the web&#8221; had come to mean HTML/JS, and I&#8217;m fine with that. So as PhoneGap started getting traction, and then Adobe took a major interest in the project, I was excited about the prospect of working on it as an Adobe evangelist, and more importantly, working with the teams behind it to see what else they had up their sleeves as the web moves forward.</p>
<p>But another side benefit is that it&#8217;s put me on what I&#8217;d consider the &#8220;right&#8221; side of the web argument. Two things got me thinking more about this. One was a <a href="http://www.bothsidesofthetable.com/2012/01/28/web-second-mobile-first/">very good post</a> by a VC named Mark Suster, who while not telling his companies to focus exclusively on the web, has told them to make it a big part of what they do. So many startups nowadays are thinking completely mobile-first while ignoring the web, I&#8217;d say at their peril. When I think of my own usage, I&#8217;m still using a lot of native apps (for reasons I can&#8217;t quite figure out) but the ones I enjoy most have a web component that is well done and part of the overall experience. Yelp comes to mind. Another is <a href="http://www.untappd.com">Untappd</a>. I can do almost anything I need to on the website version of Untappd so it&#8217;s not as though I&#8217;m getting a watered down experience. It more easily lets me move between contexts and devices while still using the service. I contrast that to something like <a href="http://foursquare.com">Foursquare</a> or <a href="http://www.path.com">Path</a>. Both are mobile-centric, and with Foursquare I can&#8217;t check in because it wants to be sure that I am where I say I am (using GPS) but it still makes the web side of it less useful for me. Path is unusable when you&#8217;re not on a mobile device as far as I can tell. When I log in all I get is &#8220;download the app&#8221;. Which I hate. Mobile is clearly important but the web can&#8217;t be ignored.</p>
<div id="attachment_3004" class="wp-caption aligncenter" style="width: 410px"><img src="http://blog.digitalbackcountry.com/wp-content/uploads/path_login-1.jpg" alt="Path Login" title="Path Login" width="400" height="308" class="size-full wp-image-3004" /><p class="wp-caption-text">If this is what I see when I log into your site, you&#039;re too mobile-first. </p></div>
<p>The second thing that got me thinking more about this was something <a href="http://brian.io">Brian Leroux</a> pointed to on the Cordova mailing list, a post by Tim Berners-Lee about <a href="http://lists.w3.org/Archives/Public/public-webapps/2012JanMar/0464.html">Installable Web Apps</a>. This is a model I would love to see take hold. As Tim notes, there are a few things that users need to have when they&#8217;re installing web apps, and some trust/permissions issues that need to be figured out. Right now, I think PhoneGap is closest to this model, but a huge, huge, part of me wishes PhoneGap didn&#8217;t need to exist. If we could somehow skip the native shim and just take for granted that every platform supported, and at its core used, installable web apps. Maybe something like the WebOS model. But we&#8217;re not there yet. So for now, I&#8217;m glad I get to work with PhoneGap and build apps with web technologies. Eventually though I think PhoneGap can be used as inspiration for installable web apps. This is kind of how the standards world moves, as more and more people adopt something, people find ways to bring that something back into the standards. I think some of PhoneGap&#8217;s APIs and methodologies would make a great start at the idea of installable web apps. And I think the guys behind PhoneGap will be at the forefront of making those things happen, which means Adobe is going to be a really cool place to be over the next few years. It feels like there is a lot of potential to change the world and while I miss spending time with Flash, I feel like the HTML/JS/CSS work I&#8217;ve been doing and that Adobe is investing in, will make a similar impact on the web down the road.</p>
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/" data-text="Hoping for a Web App Future" data-count="horizontal">Tweet</a><div class="alignright"><div class="g-plusone" data-href="http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/" size="standard" count="true"></div></div><img src="http://feeds.feedburner.com/~r/digitalbackcountry/~4/oBsZFZVPjMY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		<feedburner:origLink>http://blog.digitalbackcountry.com/2012/02/hoping-for-a-web-app-future/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 0/0 objects using disk: basic

Served from: blog.digitalbackcountry.com @ 2012-05-28 01:26:07 -->

