Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
1545 lines (1396 sloc) 53.9 KB
<!--
Google IO 2012 HTML5 Slide Template
Authors: Eric Bidelman <ebidel@gmail.com>
Luke Mahé <lukem@google.com>
URL: https://code.google.com/p/io-2012-slides
-->
<!DOCTYPE html>
<html>
<head>
<title>The Web Can Do That!? - Google IO 2012</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">-->
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0">-->
<!--This one seems to work all the time, but really small on ipad-->
<!--<meta name="viewport" content="initial-scale=0.4">-->
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" media="all" href="theme/css/default.css">
<link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="theme/css/phone.css">
<!--<link rel="stylesheet" media="all" href="theme/css/custom.css">-->
<base target="_blank"> <!-- This amazingness opens all links in a new tab. -->
<script data-main="js/slides" src="js/require-1.0.8.min.js"></script>
</head>
<body style="opacity: 0" class="weavebg">
<slides class="layout-widescreen">
<slide hidden class="logoslide nobackground">
<article class="flexbox vcenter">
<span><img src="images/google_developers_logo.png"></span>
</article>
</slide>
<slide hidden class="fill nobackground" data-body-class="nobackground">
<article>
<iframe width="640" height="390" data-src="http://www.youtube.com/embed/R0T13iiAzLM?autoplay=0&origin=http://localhost" frameborder="0"></iframe>
</article>
</slide>
<slide class="title-slide segue nobackground">
<aside class="gdbar"><img src="images/chrome_logo.png"></aside>
<!-- The content of this hgroup is replaced programmatically through the slide_config.json. -->
<hgroup class="auto-fadein">
<h1 data-config-title><!-- populated from slide_config.json --></h1>
<h2 data-config-subtitle><!-- populated from slide_config.json --></h2>
<p data-config-presenter><!-- populated from slide_config.json --></p>
<p><a href="https://developers.google.com/events/io/sessions/gooio2012/204/">Watch the video!</a></p>
</hgroup>
</slide>
<slide>
<hgroup>
<h2>Who <em>is</em> this Guy?</h2>
</hgroup>
<article id="who">
<span class="build"><p class="avatar rounded"></p></span>
<p data-config-presenter-title></p>
<p data-config-presenter-company></p>
<p style="margin-top:2em;">
<a rel="author" data-config-gplus>
<img src="http://www.google.com/images/icons/ui/gprofile_button-44.png" width="44" height="44"></a> +<a rel="author" data-config-gplus><span data-config-presenter-name></span></a>
</p>
<p>
<a rel="author" style="margin-left:-8px;" data-config-twitter>
<img src="images/twitter_newbird_blue.png" width="58" height="58"></a> <a rel="author" style="margin-left:-5px;" data-config-twitter></a>
</p>
<p>
<a rel="author" data-config-www></a>
</p>
</article>
</slide>
<slide class="nobackground" data-body-class="cat">
<article class="flexbox vcenter">
<span><a href="http://active.tutsplus.com/articles/roundups/10-flash-things-you-can%E2%80%99t-do-with-html5/" style="border:none"><img src="images/html_can_not_do_that.jpg"></a></span>
<div class="source"><a href="http://www.flickr.com/photos/thefangmonster/490423135/" class="white">www.flickr.com/photos/thefangmonster/490423135/</a></div>
</article>
</slide>
<slide>
<hgroup>
<h2>Agenda</h2>
</hgroup>
<article class="flexbox vcenter auto-fadein" style="height:65%">
<h2 class="black" style="font-size:90px;">There is no agenda!</h2>
</article>
</slide>
<slide>
<hgroup>
<h2>Legend</h2>
<h3>This slide deck is alive!</h3>
</hgroup>
<article class="flexbox vleft" id="legend-slide">
<div><img src="images/icons/radar.svg"> Close to being ready. Keep it on your radar.</div>
<div><img src="images/icons/bug.png"> Relevant Chrome/WebKit bug.</div>
<div><img src="images/icons/bug_closed.png"> Bug has been fixed/resolved.</div>
<div><img src="images/icons/gears.svg"> Specification link</div>
<p id="chrome-version-warning" class="toppadding centered red3" style="display:none">( Some of the live demos in this presentation require Chrome 21+. )</p>
</article>
</slide>
<slide class="can nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">CSS For Web Apps</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
</article>
</slide>
<slide>
<hgroup>
<h2>Floats, Tables, &amp; Positioning...OH MY!</h2>
</hgroup>
<article>
<ul>
<li>Floats stack horizontally to allow simple placement.</li>
<li>Tables lack repeatability and semantic meaning.</li>
<li>Using absolute positioning is difficult. Makes adaptive display hard.</li>
<li>CSS3 specifications address layout cases with regions, exclusions, grid and <span class="underline">flexible box</span>.</li>
</ul>
</article>
</slide>
<slide>
<hgroup>
<h2>2012: The Rise of CSS for Web Apps</h2>
</hgroup>
<article>
<ul>
<li><a href="http://dev.w3.org/csswg/css3-regions/">CSS Regions Module Level 3</a></li>
<li><a href="http://dev.w3.org/csswg/css3-flexbox/">CSS Flexible Box Layout Module</a> ( da new one )</li>
<li><a href="http://dev.w3.org/csswg/css3-grid-align/">CSS Grid Layout</a></li>
<li><a href="http://dev.w3.org/csswg/css3-hierarchies/">CSS Hierarchies</a></li>
<li><a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html">CSS Filter Effects 1.0</a></li>
<li><a href="http://dl.dropbox.com/u/11894343/web-animations/web-animations.html">Web Animations 1.0</a></li>
<li><a href="http://dev.w3.org/csswg/css-variables/">CSS Variables Module Level 1</a></li>
</ul>
</article>
</slide>
<slide hidden>
<hgroup>
<span>
<a href="http://webk.it/62048" class="bug" title="Bug link"></a>
<a href="http://dev.w3.org/csswg/css3-flexbox/" class="spec" title="Spec link"></a>
</span>
<h2>CSS Flexible Box Module</h2>
<h3>Layout for web apps</h3>
</hgroup>
<article>
<ul class="build fade">
<li>Box model optimized for user interface design</li>
<li>Children can "flex" their sizes: fill unused space / shrink to avoid overflow</li>
<li>Source-ordering independence: children can be laid out in any direction</li>
<li>Enabled by <code>display: <a data-tooltip-property="flex" class="bold"></a></code> and <code>display: <a data-tooltip-property="inline-flex" class="bold"></a></code></li>
<li>Note: Replacing old flex box <code>display: <a data-tooltip-property="box"></a></code></li>
</ul>
<p class="toppadding build"><span>That's all great...</span></p>
</article>
</slide>
<slide class="segue">
<article class="flexbox vcenter auto-fadein">
<h2 class="black">So why is flexbox so awesome?</h2>
</article>
</slide>
<slide>
<hgroup>
<h2>Achieve That "Holy Grail" Layout!</h2>
</hgroup>
<article class="flexbox vcenter">
<img src="images/slides/flexbox-holygrail.svg" style="width:500px;height:400px;" alt="Standard layout" title="Standard layout">
</article>
</slide>
<slide>
<hgroup>
<h2>Alignment</h2>
<h3>Vertically centered content is easy peasy!</h3>
</hgroup>
<article class="flexbox-example" id="flexbox-ex2">
<pre class="prettyprint" data-lang="css">
.box {
display: <a data-tooltip-property="flex" class="bold"></a>;
<a data-tooltip-property="justify-content" class="bold"></a>: <select id="justify-content">
<option>flex-start</option>
<option selected>center</option>
<option>flex-end</option>
<option>space-between</option>
<option>space-around</option>
</select>;
<a data-tooltip-property="align-items" class="bold"></a>: <select id="align-items">
<option>flex-start</option>
<option selected>center</option>
<option>flex-end</option>
<option>baseline</option>
<option>stretch</option>
</select>;
}
</pre>
<section class="box">
<div>A</div>
<div>B</div>
<div>C</div>
</section>
</article>
</slide>
<slide>
<hgroup>
<h2>Ordering &amp; Orientation</h2>
<h3>Order independent from source</h3>
</hgroup>
<article class="flexbox-example smaller" id="flexbox-ex4">
<ul>
<li>Content is laid out from lowest to highest numbered ordinal group.</li>
<li>Items with the same order group are laid out per source document.</li>
</ul>
<pre class="prettyprint" data-lang="css">
.box {
<a data-tooltip-property="flex-direction" class="bold"></a>: <select id="flexDirection">
<option selected>row</option>
<option>row-reverse</option>
<option>column</option>
<option>column-reverse</option>
</select>;
}
.box > :nth-child(2) {
<a data-tooltip-property="order" class="bold"></a>: <input id="order" type="number" placeholder="0">;
}
</pre>
<section class="box">
<div>A</div>
<div>B</div>
<div>C</div>
</section>
</article>
</slide>
<slide hidden>
<hgroup>
<h2>Optimized For UI Design!</h2>
</hgroup>
<article>
<p>Example: distribute toolbar icons evenly as device width changes:</p>
<p class="centered">
<img src="images/slides/flexbox-tools.svg" alt="Typical toolbar" title="Typical toolbar">
</p>
</article>
</slide>
<slide>
<hgroup>
<h2>Same Height Columns!</h2>
</hgroup>
<article id="flexbox-bad">
<div class="rounded">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla varius tortor ut sem volutpat eu tincidunt ligula feugiat. Pellentesque sollicitudin turpis egestas lorem tincidunt ultricies in at metus. Fusce nec nibh justo.
</div>
<div class="rounded">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
<div class="rounded">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla varius tortor ut sem volutpat eu tincidunt ligula feugiat.
</div>
</article>
</slide>
<slide>
<hgroup>
<h2>Flexibility</h2>
</hgroup>
<article class="flexbox-example smaller" id="flexbox-ex3">
<ul>
<li>Flexbox items alter their width/height to fill available space.</li>
<li>Items grow/shrink proportional to their positive/negative flexibility</li>
<li>3rd argument is preferred size</li>
</ul>
<pre class="prettyprint" data-lang="css">
.box > * {
<a data-tooltip-property="flex" class="bold"></a>: 1 0 0px;
}
.box > :nth-child(2) {
<a data-tooltip-property="flex" class="bold"></a>: <input type="number" value="1" placeholder="1"> <input type="number" placeholder="0"> <input type="text" placeholder="0">px;
}
</pre>
<section class="box">
<div>A</div>
<div>B</div>
<div>C</div>
</section>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demo: Holy Grail Layout</h2>
</hgroup>
<article>
<!--<a href="http://jsbin.com/emedub/37/edit" class="demo">Demo</a>-->
<a href="http://html5-demos.appspot.com/static/css/flexbox/index.html" class="previewframe"><iframe data-src="http://html5-demos.appspot.com/static/css/flexbox/index.html"></iframe></a>
</article>
</slide>
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>CSS Flexbox ( da new one )</h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png" class="supported">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png" class="supported">
</div>
</article>
</slide>
<slide class="can nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Dynamic CSS</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
</article>
</slide>
<slide hidden>
<aside class="note">
<section>
<p>Support: <code>-webkit-calc()</code>, <code>-moz-calc()</code>, IE9.</p>
</section>
</aside>
<hgroup>
<span>
<a href="http://webk.it/16662" class="bug"></a>
<a href="http://www.w3.org/TR/css3-values/#calc" class="spec" title="Spec link" alt="Spec link"></a>
</span>
<h2>New CSS Functions</h2>
</hgroup>
<article class="smaller">
<p>calc()</p>
<pre class="prettyprint" data-lang="css">
width: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(200px - 100);
width: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(2 * 50%);
width: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(200px / 2);
color: hsl(<a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(120), <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(75%), 0.5);
background-position: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(50% + 5px) center;
</pre>
<p>min()</p>
<pre class="prettyprint" data-lang="css">
width: <a data-tooltip-property="min" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(150px, 100px, 200px);
width: <a data-tooltip-property="min" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(90px + 50px, 100px);
width: <a data-tooltip-property="min" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(100px, 100%); /* where 100% is 200px; */
</pre>
<p>max()</p>
<pre class="prettyprint" data-lang="css">
width: <a data-tooltip-property="max" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(150px, 100px, 200px);
width: <a data-tooltip-property="max" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(200px - 50px, 100px);
width: <a data-tooltip-property="max" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(100px, 100%); /* where 100% is 200px; */
</pre>
</article>
</slide>
<slide>
<aside class="note">
<section>
<p>Support: <code>-webkit-calc()</code>, <code>-moz-calc()</code>, IE9.</p>
</section>
</aside>
<hgroup>
<span>
<a href="http://webk.it/16662" class="bug"></a>
<a href="http://www.w3.org/TR/css3-values/#calc" class="spec" title="Spec link" alt="Spec link"></a>
</span>
<h2>calc()</h2>
</hgroup>
<article id="flexbox-circle" class="columns-2">
<pre class="prettyprint" data-lang="css">
.circle {
width: 300px;
height: 300px;
}
div {
display: <a data-tooltip-property="flex" class="bold"></a>;
width: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(100% - 4em);
height: <a data-tooltip-property="calc" data-tooltip-support='["webkit", "moz", "unprefixed"]' class="bold"></a>(100% - 4em);
border-radius: 50%;
<a data-tooltip-property="align-items" data-tooltip-support='["webkit"]' class="bold"></a>: center;
<a data-tooltip-property="justify-content" data-tooltip-support='["webkit"]' class="bold"></a>: center;
}
div:hover {
border-radius: 0;
}
</pre>
<div class="circle">
<div>
<div><div></div></div>
</div>
</div>
</article>
</slide>
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>CSS calc()</h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png" class="supported">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png" class="supported">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png" class="supported">
</div>
</article>
</slide>
<slide hidden>
<hgroup>
<span>
<a href="http://webk.it/52162" class="bug"></a>
<a href="http://dev.w3.org/csswg/css3-images/#cross-fade-function" class="spec" title="Spec link" alt="Spec link"></a>
</span>
<h2>CSS Functions ( cont. )</h2>
</hgroup>
<article>
<p>cross-fade()</p>
<pre class="prettyprint" data-lang="css">
background-image: <a data-tooltip-property="cross-fade" class="bold"></a>(url(first.png), url(second.png), 50%);
@-webkit-keyframes fading {
0% { background-image: <a data-tooltip-property="cross-fade" class="bold"></a>(url(first.png), url(second.png), 0%); }
100% { background-image: <a data-tooltip-property="cross-fade" class="bold"></a>(url(first.png), url(second.png), 100%); }
}
</pre>
<p class="centered"><a href="http://peter.sh/files/examples/cross-fading.html" class="demo">Demo</a></p>
</article>
</slide>
<slide hidden>
<aside class="note">
<section>
<ul>
<li>Prefixed in WebKit nightly/Chrome Canary: <code>-webkit-filter</code>.</li>
</ul>
</section>
</aside>
<hgroup>
<span>
<a href="http://webk.it/68469" class="bug" title="Bug link"></a>
<a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html" class="spec" title="Spec link"></a>
</span>
<h2>CSS Filter Effects</h2>
</hgroup>
<article>
<p>Apply filter effects to any DOM element:</p>
<pre class="prettyprint" data-lang="css">
video, img {
<a data-tooltip-property="filter" class="bold"></a>: grayscale(0.5) blur(10px);
}
</pre>
<ul>
<li>Chrome needs <code>--enable-accelerated</code> flag for hardware accelerated content.</li>
<li>Good <a href="http://drublic.de/blog/effects-for-the-web/">blog post</a>.</li>
</ul>
<p class="centered"><a href="http://html5-demos.appspot.com/static/css/filters/index.html" class="demo">Demo</a> <a href="http://lab.simurai.com/stars/" class="demo">Demo2</a></p>
</article>
</slide>
<slide class="can nobackground" data-body-class="binding">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Data binding</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
<div class="source"><a href="http://www.flickr.com/photos/24946690@N03/4345556870/" class="white">www.flickr.com/photos/24946690@N03/4345556870/</a></div>
</article>
</slide>
<slide>
<hgroup>
<h2>Old Hat for JS Frameworks</h2>
</hgroup>
<article class="build">
<div>
<p>Angular ( <a href="http://angularjs.org">angularjs.org</a> ) example:</p>
<pre class="prettyprint" data-lang="html">
&lt;div <b>ng-app</b> ng-init="val=25">
Volume: &lt;input type="range" min="0" max="100" <b>ng-model="val"</b>>
<b>{{val}}</b>/100
&lt;/div>
</pre>
</div>
<div ng-app ng-cloak ng-init="val=25" class="centered toppadding">
Volume: <input type="range" min="0" max="100" ng-model="val"> {{val}}/100
</div>
</article >
</slide>
<slide>
<hgroup>
<h2>One-way Data Binding: <code>data-*</code> Attributes</h2>
<h3>"Poor man's data binding"</h3>
</hgroup>
<article>
<ul>
<li>Model: data attribute</li>
<li>Use <code>attr()</code> to get the value(s)</li>
<li>View: render generated content to <code>:before</code>/<code>:after</code> pseudo elements</li>
<li>Hook listeners that watch for changes.</li>
</ul>
</article>
</slide>
<slide id="data-binding-example">
<hgroup>
<h2>"Poor Man's Data Binding"</h2>
</hgroup>
<article>
<pre class="prettyprint" data-lang="html/js">
&lt;style>
input::after {
<b>content: attr(data-value) '/' attr(max);</b>
position: relative;
left: 135px; top: -20px;
}
&lt;/style>
&lt;input type="range" min="0" max="100" value="25"&gt;
&lt;script>
var input = document.querySelector('input');
input.dataset.value = input.value; // Set an initial value.
<b>input.addEventListener('change', function(e) {
this.dataset.value = this.value;
});</b>
&lt;/script>
</pre>
<div class="centered">
Volume: <input type="range" min="0" max="100" value="25">
</div>
</article>
</slide>
<slide>
<hgroup>
<span>
<a href="http://webk.it/27247" class="bug" title="Bug link"></a>
<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-datalist-element" class="spec" title="Spec link"></a>
</span>
<h2>One-way Data Binding: &lt;datalist&gt;</h2>
</hgroup>
<article>
<pre class="prettyprint" data-lang="html">
Browsers: &lt;input <b>list="browsers"></b>
&lt;<b>datalist</b> id="browsers">
&lt;option value="Chrome">
&lt;option value="Firefox">
&lt;option value="Internet Explorer">
&lt;option value="Opera">
&lt;option value="Safari">
<b>&lt;/datalist></b>
</pre>
<ul>
<li>Specifies a list of pre-defined options for an &lt;input&gt; element.</li>
<li><code>list</code> attribute "binds" data list to an &lt;input&gt;</li>
<li>Useful for "autocomplete" on &lt;input&gt; elements.</li>
</ul>
<p class="centered blue">Browsers: <input list="browsers">
<datalist id="browsers">
<option value="Chrome">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Opera">
<option value="Safari">
</datalist>
</p>
</article>
</slide>
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>Data binding with <code>data-*</code> attrs / <code>&lt;datalist&gt;</code></h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%;">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png" class="supported">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png" class="supported">
<img src="images/browser_logos/opera_logo.png" class="supported">
<img src="images/browser_logos/ie10_logo.png" class="supported">
</div>
</article>
</slide>
<slide class="can nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Access a Filesystem</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
</article>
</slide>
<slide>
<hgroup style="display:inline-block;">
<h2 class="build">I Got So Excited...<span>I Wrote a Book :)</span></h2>
</hgroup>
<article class="flexbox vcenter">
<a href="http://www.amazon.com/Using-HTML5-Filesystem-Eric-Bidelman/dp/1449309453" style="border:none;"><img src="images/my_book_cover.jpg" alt="Using the HTML5 Filesystem API" title="Using the HTML5 Filesystem API" style="height:500px;"></a>
</article>
</slide>
<slide>
<hgroup>
<span>
<a href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html" class="spec" title="Spec link"></a>
</span>
<h2>HTML5 Filesystem API</h2>
<h3>Persist data to files/folders</h3>
</hgroup>
<article>
<p>Opening a filesystem:</p>
<pre class="prettyprint" data-lang="js">
window.<a data-tooltip-property="requestFileSystem" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(
TEMPORARY, // persistent vs. temporary storage
1024 * 1024, // size (bytes) of needed space
initFs, // success callback
opt_errorHandler // opt. error callback, denial of access
);
</pre>
<ul class="build">
<li>Security: sandboxed per origin</li>
<li>Power: native apps can do files/folders,...web apps should too!</li>
<li>Benefit: dynamically cache and manage assets.</li>
</ul>
</article>
</slide>
<slide>
<hgroup>
<h2>Example: Caching Remote Files</h2>
</hgroup>
<article class="">
<pre class="prettyprint" data-lang="js">
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
<b>xhr.responseType = 'arraybuffer';</b>
xhr.onload = function(e) {
};
xhr.send();
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Example: Caching Remote Files</h2>
</hgroup>
<article class="">
<pre class="prettyprint" data-lang="js">
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
<b>window.<a data-tooltip-property="requestFileSystem" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(TEMPORARY, 1024 * 1024, function(fs) {</b>
<b>}, onError);</b>
};
xhr.send();
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Example: Caching Remote Files</h2>
</hgroup>
<article class="">
<pre class="prettyprint" data-lang="js">
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
window.<a data-tooltip-property="requestFileSystem" data-tooltip-support='["webkit"]' data-tooltip-js></a>(TEMPORARY, 1024 * 1024, function(fs) {
<b>fs.root.getFile('image.png', {create: true}, function(fileEntry) {</b>
<b>}, onError);</b>
}, onError);
};
xhr.send();
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Example: Caching Remote Files</h2>
</hgroup>
<article class="">
<pre class="prettyprint" data-lang="js">
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
window.<a data-tooltip-property="requestFileSystem" data-tooltip-support='["webkit"]' data-tooltip-js></a>(TEMPORARY, 1024 * 1024, function(fs) {
fs.root.getFile('image.png', {create: true}, function(fileEntry) {
<b>fileEntry.createWriter(function(writer) {</b>
writer.onwriteend = function(e) { ... };
writer.onerror = function(e) { ... };
<b>writer.write(new Blob([xhr.response], {type: 'image/png'}));</b>
<b>}, onError);</b>
}, onError);
}, onError);
};
xhr.send();
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Using Local Assets</h2>
</hgroup>
<article>
<ul>
<li>Stored files/folders get their own ( <code>filesystem:</code> ) URL:</li>
</ul>
<pre class="centered" style="font-size:25px;">
<b>filesystem:</b><b alt="Origin of the app" class="blue" data-tooltip="Origin of the app"><span class="property" style="color:inherit;">http://example.com</span></b>/<b alt="Type of storage used" class="red" data-tooltip="Type of storage used"><span class="property" style="color:inherit;">temporary</span></b>/<b alt="Path to the file/folder" class="green" data-tooltip="Path to the file/folder"><span class="property" style="color:inherit;">image.png</span></b>
</pre>
<ul><li>Use for a src/href value:</li></ul>
<pre class="prettyprint" data-lang="js">
var img = document.createElement('img');
img.src = <b>fileEntry.toURL();</b>
document.body.appendChild(img);
</pre>
<ul><li>Get back to a <code>FileEntry</code> from its <code>filesystem:</code> URL:</li></ul>
<pre class="prettyprint" data-lang="js">
window.<a data-tooltip-property="resolveLocalFileSystemURL" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(img.src, function(fileEntry) { ... });
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Moar Callbackzzzzzz!</h2>
</hgroup>
<article class="">
<pre class="prettyprint" data-lang="js">
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
window.<a data-tooltip-property="requestFileSystem" data-tooltip-support='["webkit"]' data-tooltip-js></a>(TEMPORARY, 1024 * 1024, function(fs) {
fs.root.getFile('image.png', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.onwriteend = function(e) { ... };
writer.onerror = function(e) { ... };
writer.write(new Blob([xhr.response], {type: 'image/png'}));
}, onError);
}, onError);
}, onError);
};
xhr.send();
</pre>
</article>
</slide>
<slide class="segue">
<article class="flexbox vcenter auto-fadein">
<q style="font-size: 60px;">Callback spaghetti is hard,... let's go shopping!</q>
<div class="build toppadding"><div class="author">Eric Bidelman</div></span>
</article>
</slide>
<slide>
<hgroup>
<h2>filer.js ( <a href="https://github.com/ebidel/filer.js">github.com/ebidel/filer.js</a> )</h2>
</hgroup>
<article>
<p>Wrapper lib that implements common UNIX cmds (ls, cp, mv)</p>
<pre class="prettyprint" data-lang="js">
<b>var filer = new Filer();</b>
filer.<b>init</b>({persistent: false, size: 1024 * 1024}, function(fs) {...}, onError);
filer.<b>ls</b>('path/to/some/dir/', function(entries) { ... }, onError);
<b>filer.cp('file.txt', '/path/to/folder', 'newname.txt', function(entry) {
// entry.fullPath == '/path/to/folder/newname.txt'
}, onError);</b>
var b = new Blob(['body { color: red; }'], {type: 'text/css'});
filer.<b>write</b>('styles.css', {data: b, type: b.type}, function(entry, writer) {
...
}, onError);
</pre>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demo: Filesystem Playground</h2>
</hgroup>
<article style="margin-top:0;">
<a href="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html" class="previewframe"><iframe data-src="http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html" style="-webkit-transform: scale(0.75) translateX(-130px);width: 120%;height:600px;"></iframe></a>
</article>
</slide>
<!--
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>Filesystem API</h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png">
</div>
</article>
</slide>
-->
<slide class="segue">
<article class="flexbox vcenter auto-fadein">
<h2 class="black" style="font-size:45px;">But kind Sir, this marvel is only in Chrome!</h2>
<p class="centered build toppadding"><a href="http://html5-demos.appspot.com/static/filesystem/idb.filesystem.js/demos/playground/index.html" class="demo">Oh yeah?</a></p>
</article>
</slide>
<!--
<slide>
<hgroup>
<h2>idb.filesystem.js</h2>
</hgroup>
<article>
<p class="centered"><a href="https://github.com/ebidel/idb.filesystem.js">github.com/ebidel/idb.filesystem.js</a></p>
<ul class="build">
<li>HTML5 Filesystem API shim library using IndexedDB</li>
<li>Means browsers that support IDB also support the Filesystem API!</li>
</ul>
<p class="centered build"><a href="http://html5-demos.appspot.com/static/filesystem/idb.filesystem.js/demos/playground/index.html" class="demo">Launch me in FF</a></p>
</article>
</slide>
-->
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>HTML5 Filesystem API - thanks to <a href="https://github.com/ebidel/idb.filesystem.js">idb.filesystem.js</a> shim!</h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png" class="supported">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png" class="supported">
</div>
</article>
</slide>
<slide class="can cant nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">sudo make me a sandwich</h2>
<span class="build"><h1 class="stamp" style="left:30%">BUSTED</h1></span>
</hgroup>
</article>
</slide>
<slide class="can nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Serverless Downloads</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
</article>
</slide>
<slide>
<hgroup>
<span>
<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#downloading-resources" class="spec" title="Spec link"></a>
</span>
<h2>Client-side Downloads</h2>
</hgroup>
<article class="build">
<p><label class="old"></label>Force downloads with a server:</p>
<pre class="prettyprint" data-lang="http">
Content-Disposition: attachment; filename="MyLogo.png";
</pre>
<ul class="toppadding">
<li>Need a way for users to download data created in the app.</li>
</ul>
<p><label class="new"></label>Use <code>download</code> to download resources rather than navigate to them:</p>
<pre class="prettyprint" data-lang="html">
&lt;a href="http://google.com/logo.png" <b>download="Logo.png"</b>>download me&lt;/a>
</pre>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demo: Novel Generator</h2>
</hgroup>
<article>
<a href="http://html5-demos.appspot.com/static/a.download.html" class="previewframe"><iframe data-src="http://html5-demos.appspot.com/static/a.download.html"></iframe></a>
</article>
</slide>
<slide>
<hgroup>
<h2>Example: Downloading a Generated File</h2>
</hgroup>
<article>
<pre class="prettyprint" data-lang="js">
function downloadLink(name, content, mimetype) {
var a = document.createElement('a');
<b>a.href = window.<a data-tooltip-property="URL.createObjectURL" data-tooltip-lowercase data-tooltip-support='["unprefixed", "webkit"]' data-tooltip-js></a>(new Blob([content], {type: mimetype}));</b>
<b>a.download = name;</b>
a.textContent = 'Download ready';
document.body.appendChild(a);
}
downloadLink('MyNovel.txt', document.querySelector('textarea').textContent, 'text/plain');
</pre>
</article>
</slide>
<slide class="can nobackground" data-body-class="rocket">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Efficiently Transfer Data</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
<div class="source"><a href="http://www.flickr.com/photos/hamillianactor/362021036/" class="white">www.flickr.com/photos/hamillianactor/362021036/</a></div>
</article>
</slide>
<slide class="segue">
<article class="flexbox vcenter auto-fadein">
<h2 class="black">Evolution of <code>postMessage()</code></h2>
</article>
</slide>
<slide>
<hgroup>
<span>
<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#web-messaging" class="spec" title="window.postMessage() spec link"></a>
<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#dedicatedworkerglobalscope" class="spec" title="worker.postMessage() spec link"></a>
</span>
<h2>Evolution of <code>postMessage()</code></h2>
</hgroup>
<article>
<div class="build">
<div>
<p>1. Basic strings</p>
<pre class="prettyprint" data-lang="js">
worker.postMessage(<b>'Hello World'</b>);
window.postMessage(<b>JSON.stringify({msg: 'Hello World'})</b>, '*');
</pre>
</div>
<div>
<p>2. JSON</p>
<pre class="prettyprint" data-lang="js">
worker.postMessage(<b>{msg: 'Look ma, no strings!'}</b>);
</pre>
</div>
</div>
</article>
</slide>
<slide>
<aside class="note">
<section>
<ul>
<li>Structured cloning support: Chrome 13, FF 5</li>
</ul>
</section>
</aside>
<hgroup>
<h2>Evolution of <code>postMessage()</code></h2>
</hgroup>
<article>
<p>3. Complex types (<code>File</code>, <code>Blob</code>, <code>ArrayBuffer</code>) via structured cloning</p>
<pre class="prettyprint" data-lang="js">
var data = [1, 2, 3, 4];
// Blob() in Chrome 20, FF 13
worker.postMessage(<b>new Blob(data.toString(), {type: 'text/plain'})</b>);
var uint8Array = new Uint8Array(data);
worker.postMessage(<b>uint8Array</b>);
worker.postMessage(<b>uint8Array.buffer</b>);
</pre>
<ul class="build">
<li>Problem: all of these methods are copies. Not efficient!</li>
<li>We can do better...</li>
</ul>
</article>
</slide>
<slide>
<aside class="note">
<section>
<ul>
<li>Support: Chrome 17, FF, Safari 6</li>
</ul>
<img src="images/transferables.jpg">
</section>
</aside>
<hgroup>
<h2>Transferable Objects</h2>
<h3>a.k.a. workers that "don't suck"</h3>
</hgroup>
<article>
<p>Same old friend, different semantics (note the vendor prefix):</p>
<pre class="prettyprint" data-lang="js">
worker.<a data-tooltip-property="postMessage" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(arrayBuffer, [arrayBuffer]);
window.<a data-tooltip-property="postMessage" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(arrayBuffer, targetOrigin, [arrayBuffer]);
</pre>
<ul class="build">
<li>Zero-copy
<ul>
<li>Ownership of data (<code>ArrayBuffer</code>) is transferred to new context (e.g. worker/window). Source buffer becomes unavailable.</li>
<li><span class="underline">~50x faster</span> than structured cloning (Chrome 13/FF).</li>
</ul>
</li>
<li>2nd argument is list of what to transfer.</li>
</ul>
</article>
</slide>
<slide hidden>
<hgroup>
<h2>Examples</h2>
</hgroup>
<article>
<pre class="prettyprint" data-lang="js">
var uint8Array = new Uint8Array(1024 * 1024 * 32); // 32MB
// Fill'r up!
for (var i = 0, len = uint8Array.length; i &lt; len; ++i) {
uint8Array[i] = i;
}
worker.<a data-tooltip-property="postMessage" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(uint8Array, [uint8Array.buffer]);
</pre>
<p>Pass multiple buffers at once and/or additional data:</p>
<pre class="prettyprint" data-lang="js">
worker.<a data-tooltip-property="postMessage" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>({
view1: uInt8Array,
buffer2: anotherBuffer,
username: 'johndoe'
}, [uInt8Array.buffer, anotherBuffer]);
</pre>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demo: Transferable Objects</h2>
</hgroup>
<article>
<a href="http://html5-demos.appspot.com/static/workers/transferables/index.html" class="previewframe"><iframe data-src="http://html5-demos.appspot.com/static/workers/transferables/index.html"></iframe></a>
</article>
</slide>
<slide>
<hgroup>
<h2>Feature Detection</h2>
</hgroup>
<article>
<ul>
<li>Feature detecting is a PITA b/c of false positives.</li>
<li>If transferred, buffer's <code>.byteLength</code> goes to zero.</li>
</ul>
<pre class="prettyprint" data-lang="js">
var ab = new ArrayBuffer(1);
worker.<a data-tooltip-property="postMessage" data-tooltip-support='["webkit"]' data-tooltip-js class="bold"></a>(ab, [ab]);
if (ab.byteLength) {
alert('Transferables are not supported in your browser!');
} else {
// Transferables are supported.
}
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3>Transferable Objects</h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png" class="supported">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png" class="supported">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png">
</div>
</article>
</slide>
<slide class="can nobackground" data-body-class="tools">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Access Native Hardware</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
<div class="source"><a href="http://www.flickr.com/photos/katerha/5746905652/" class="white">www.flickr.com/photos/katerha/5746905652/</a></div>
</article>
</slide>
<slide>
<hgroup>
<h2>"Device APIs"</h2>
</hgroup>
<article class="build">
<p>Device APIs WG: <a href="http://www.w3.org/2009/dap/">www.w3.org/2009/dap/</a></p>
<ul class="build">
<li>Geolocation API</li>
<li>Device Orientation API ( accelerometer )</li>
<li>WebGL ( GPU )</li>
<li>HTML5 Filesystem API ( sandboxed filesystem )</li>
<li><code>navigator.onLine</code> / <code>navigator.connection</code> ( network connectivity )</li>
<li>Battery API</li>
<li>Gamepad API</li>
<li>WebRTC ( voice &amp; video input ) / Web Audio API ( core audio )</li>
</ul>
</article>
</slide>
<slide>
<hgroup>
<h2>First Step to Speech Enabled Apps!</h2>
</hgroup>
<article class="flexbox vcenter">
<input id="speech-input-textbox" type="text" x-webkit-speech style="width:400px;height:50px;font-size:135%;">
<pre class="prettyprint centered toppadding" data-lang="html">
&lt;input type="text" <b>x-webkit-speech</b>&gt;
</pre>
</article>
</slide>
<slide>
<aside class="note">
<section>
<ul>
<li>Prefixed as <code>navigator.webkitGetUserMedia()</code> in WebKit</li>
<li><code>window.URL</code> is prefixed as <code>window.webkitURL</code> in WebKit</li>
<li>Needs <code>--enable-media-stream</code> flag in Chrome.</li>
</ul>
</section>
</aside>
<hgroup>
<h2>Camera &amp; Microphone Access</h2>
</hgroup>
<article>
<p>Plugin-free access to camera/microphone.</p>
<pre class="prettyprint" data-lang="js">
<b>navigator.<a data-tooltip-property="getUserMedia" data-tooltip-support='["unprefixed", "webkit", "moz"]' data-tooltip-js></a></b>({audio: true, video: true}, function(stream) {
var video = document.querySelector('video');
video.src = <b>window.<a data-tooltip-property="URL.createObjectURL" data-tooltip-lowercase data-tooltip-support='["unprefixed", "webkit"]' data-tooltip-js></a>(stream)</b>;
}, function(e) {
console.log(e);
});
</pre>
<pre class="prettyprint centered" data-lang="html">
&lt;video autoplay controls&gt;&lt;/video&gt;
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Demos</h2>
</hgroup>
<article>
<ul>
<li><a href="http://html5-demos.appspot.com/static/getusermedia/photobooth.html">Photo booth</a></li>
<li><a href="http://neave.com/webcam/html5/">Live Effects</a></li>
<li><a href="http://www.html5rocks.com/en/tutorials/webgl/jsartoolkit_webrtc/">Augmented Reality</a></li>
<li><a href="http://learningthreejs.com/data/live-video-in-webgl/">WebGL Live TV</a></li>
<li><a href="http://people.opera.com/danield/webapps/instant-camera/">Instant Camera</a></li>
<li><a href="http://people.opera.com/danield/html5/explode/">Explode Video</a></li>
</ul>
</article>
</slide>
<slide>
<hgroup>
<span>
<img src="images/icons/radar.svg" class="radar" title="Coming soon...keep it on your radar!">
<a href="http://crbug.com/113676" class="bug" title="Bug link"></a>
</span>
<h2>Recording Content</h2>
</hgroup>
<article>
<pre class="prettyprint" data-lang="html">
&lt;input type="button" value="⚫" onclick="record(this)">
&lt;input type="button" value="◼" onclick="stop(this)">
</pre>
<pre class="prettyprint" data-lang="js">
var localMediaStream, recorder;
var record = function(button) {
recorder = <b>localMediaStream.record()</b>;
};
var stop = function(button) {
localMediaStream.stop();
<b>recorder.getRecordedData</b>(function(blob) {
// Upload blob using XHR2.
});
};
</pre>
</article>
</slide>
<slide>
<hgroup>
<h2>Browser Support</h2>
<h3><code>getUserMedia()</code></h3>
</hgroup>
<article class="flexbox vcenter" style="height:65%">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png" class="supported">
<img src="images/browser_logos/opera_logo.png" class="supported">
<img src="images/browser_logos/ie10_logo.png">
</div>
</article>
</slide>
<slide class="can nobackground">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Make &lt;audio&gt; Sexy Again</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demo: HTML5 &lt;audio&gt; Visualizer</h2>
</hgroup>
<article>
<a href="http://html5-demos.appspot.com/static/webaudio/createMediaSourceElement.html" class="previewframe"><iframe data-src="http://html5-demos.appspot.com/static/webaudio/createMediaSourceElement.html"></iframe></a>
</article>
</slide>
<slide>
<aside class="note">
<section class="centered">
<p><img src="images/audio-routing.png" style="height:200px"></p>
</section>
</aside>
<hgroup>
<span>
<a href="http://crbug.com/79949" target="_blank" class="bug" title="Bug link"></a>
<a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioElementIntegration-section" target="_blank" class="spec" title="Spec link"></a>
</span>
<h2>Web Audio API + <code>&lt;audio&gt;</code>/<code>&lt;video&gt;</code></h2>
</hgroup>
<article>
<p>Use an <code>HTMLMediaElement</code> as the source to the API:</p>
<pre class="prettyprint" data-lang="js">
var ctx = new window.<b><a data-tooltip-property="AudioContext" data-tooltip-lowercase data-tooltip-support='["webkit"]' data-tooltip-js></a></b>();
var audioElement = new Audio();
audioElement.src = 'sounds/dope_beats.mp3';
audioElement.controls = true;
audioElement.autoplay = true;
<b>var source = ctx.createMediaElementSource(audioElement);</b>
var analyser = ctx.createAnalyser();
source.connect(analyser);
analyser.connect(ctx.destination);
</pre>
<p><b>Note</b>: There's no <code>source.noteOn(0)</code>. Play/pause is controlled by the <code>&lt;audio&gt;</code> element.</p>
</article>
</slide>
<!--
<slide hidden>
<hgroup>
<h2>Demos</h2>
</hgroup>
<article>
<ul>
<li><a href="http://www.technitone.com/">Technitone</a></li>
<li><a href="http://labs.dinahmoe.com/plink/">Plink</a></li>
<li><a href="http://static.echonest.com/BohemianRhapsichord/index.html">Bohemian Rhapsichord</a></li>
<li><a href="http://airtightinteractive.com/demos/js/reactive/">3D Audio Visualizer</a></li>
<li><a href="http://www.htmlfivewow.com/demos/hal/index.html">GAL 9000</a></li>
<li><a href="http://www.htmlfivewow.com/demos/audio-visualizer/index.html">HTML5Wow Visualizer</a></li>
<li><a href="http://alteredqualia.com/three/examples/webgl_city.html">WebGL City</a></li>
<li><a href="http://www.iquilezles.org/apps/soundtoy/index.html">Sound Toy</a></li>
</ul>
</article>
</slide>
<slide hidden>
<aside class="note">
<section class="centered">
<p><img src="images/audio-routing-analysis.png" style="width:530px"></p>
</section>
</aside>
<hgroup>
<h2>Realtime Audio Processing</h2>
</hgroup>
<article class="smaller">
<pre class="prettyprint" data-lang="js">
var ctx = new window.<b><a data-tooltip-property="AudioContext" data-tooltip-lowercase data-tooltip-support='["webkit"]' data-tooltip-js></a></b>();
var analyser = <b>ctx.createAnalyser</b>();
function initAudio(arrayBuffer) {
ctx.decodeAudioData(arrayBuffer, function(buffer) {
var src = ctx.createBufferSource();
src.buffer = buffer;
<b>src.connect(analyser);</b> // src -> analyser -> destination
<b>analyser.connect(ctx.destination);</b>
render(src);
}, function(e) {
console.log('Error decoding audio file', e);
});
}
function render(src) {
(function callback(timeStamp) {
<b>var byteData = new Uint8Array(analyser.frequencyBinCount);</b>
<b>analyser.getByteFrequencyData(byteData);</b>
// draw byteData to &lt;canvas&gt; visualization...
window.requestAnimationFrame(callback, src);
})();
}
</pre>
</article>
</slide>
<slide hidden>
<hgroup>
<h2>Browser Support</h2>
</hgroup>
<article class="flexbox vcenter">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png">
</div>
</article>
</slide>
-->
<slide class="can nobackground" data-body-class="stream">
<article class="flexbox vcenter">
<hgroup>
<h2 class="white auto-fadein">Stream Multimedia</h2>
<span class="build"><h1 class="stamp">Confirmed</h1></span>
</hgroup>
<div class="source"><a href="http://www.flickr.com/photos/nikonvscanon/2081397439/" class="white">www.flickr.com/photos/nikonvscanon/2081397439/</a></div>
</article>
</slide>
<slide>
<hgroup>
<span>
<a href="http://dev.w3.org/html5/websockets/#dom-websocket-binarytype" class="spec" title="Spec link"></a>
</span>
<h2>Binary WebSockets</h2>
<h3>New look, same great taste</h3>
</hgroup>
<article>
<ul>
<li>WebSockets suffered the same limitations as Workers.</li>
<li>Now send <code>File</code>, <code>Blob</code>, or <code>ArrayBuffer</code> types.</li>
</ul>
<div class="build">
<pre class="prettyprint" data-lang="js">
var socket = new WebSocket('ws://example.com/sock', ['dumby-protocol']);
<b>socket.binaryType = 'blob';</b> // or 'arraybuffer'
socket.onopen = function(e) {
window.setInterval(function() {
if (<b>socket.bufferedAmount</b> == 0) {
<b>socket.send(new Blob([blob1, blob2]));</b>
}
}, 50); // rate limit us.
};
socket.onmessage = function(e) {
document.querySelector('img').src = <b><a data-tooltip-property="URL.createObjectURL" data-tooltip-lowercase data-tooltip-support='["unprefixed", "webkit"]' data-tooltip-js></a>(e.data);</b>
};
</pre>
</div>
</article>
</slide>
<slide class="fill nobackground" data-body-class="blueprint">
<hgroup>
<h2 class="white">Demos: Media Streaming</h2>
</hgroup>
<article class="flexbox vcenter">
<p class="centered"><a href="http://localhost:8000" class="demo">Audio Streamer</a> <a href="demos/screenshare/screenshare.crx" class="demo">Install Screenshare</a></p>
</article>
</slide>
<slide hidden>
<hgroup>
<h2>Browser Support</h2>
</hgroup>
<article class="flexbox vcenter">
<div class="browser-support">
<img src="images/browser_logos/safari_logo.png">
<img src="images/chrome_logo.png" class="supported">
<img src="images/browser_logos/ff_logo.png">
<img src="images/browser_logos/opera_logo.png">
<img src="images/browser_logos/ie10_logo.png">
</div>
</article>
</slide>
<slide class="segue">
<article class="flexbox vcenter auto-fadein">
<h2 class="black">Finito.</h2>
</article>
</slide>
<slide id="wrapup">
<hgroup>
<h2>The Web Can Do Amazing Things...</h2>
</hgroup>
<article>
<ul></ul> <!-- dynamically filled -->
</article>
</slide>
<slide class="nobackground">
<article class="flexbox vcenter" id="chrome-heart">
<div class="chrome-logo spin"></div>
<h1 title="BFFs"><div class="jitter"></div> <img src="images/HTML5_Badge_128.png" style="margin-bottom:-24px;height:85px;"></h1>
<p class="toppadding"><a href="https://plus.google.com/b/102860501900098846931/102860501900098846931">+Google Chrome Developers</a></p>
</article>
</slide>
<slide class="thank-you-slide segue nobackground">
<aside class="gdbar right"><img src="images/chrome_logo.png"></aside>
<article class="flexbox vleft auto-fadein">
<h2>&lt; Thank You! &gt;</h2>
<p>Source: <a href="https://github.com/ebidel/html5can" class="white" style="border:none">github.com/ebidel/html5can</a></p>
</article>
<p class="auto-fadein" data-config-contact>
<!-- populated from slide_config.json -->
</p>
</slide>
<slide class="logoslide dark nobackground">
<article class="flexbox vcenter">
<span><img src="images/google_developers_logo_white.png"></span>
</article>
</slide>
<slide class="backdrop"></slide>
</slides>
<!--
<script src="js/app.js"></script>
-->
<script src="js/angular-1.0.0.min.js" async></script>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-32630298-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<!--[if IE]>
<script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script>CFInstall.check({mode: 'overlay'});</script>
<![endif]-->
</body>
</html>