changeset 7:7b67d3e40479

Refactored content and DOM structure, refactored code into a syncVisualsWithAudio() function.
author Atul Varma <varmaa@toolness.com>
date Wed, 10 Feb 2010 12:07:27 -0800
parents 37a4eb5f9695
children c9bb7e3e1821
files css/ff-herdict-preso.css ff-herdict-preso.html js/ff-herdict-preso.js
diffstat 3 files changed, 145 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/css/ff-herdict-preso.css	Wed Feb 10 10:49:43 2010 -0800
+++ b/css/ff-herdict-preso.css	Wed Feb 10 12:07:27 2010 -0800
@@ -13,7 +13,7 @@
     font-size: 24pt;
 }
 
-#script {
+#subtitles {
     display: none;
 }
 
@@ -25,7 +25,7 @@
     position: static;
 }
 
-#slides .slide {
+#slides div {
     font-size: 24pt;
     display: none;
     vertical-align: middle;
@@ -35,7 +35,7 @@
     display: table-cell;
 }
 
-#slides .slide em {
+#slides div em {
     font-style: normal;
     font-weight: bold;
 }
--- a/ff-herdict-preso.html	Wed Feb 10 10:49:43 2010 -0800
+++ b/ff-herdict-preso.html	Wed Feb 10 12:07:27 2010 -0800
@@ -11,136 +11,124 @@
 <body>
 <div id="container">
   <div id="slides">
-    <div class="visible slide" data-at="0.0">
+    <div data-at="0.0">
       <a href="http://www.mozillalabs.com"><img id="logo" src="images/labs-logo.png"/></a>
       <h1>Firefox-Herdict Integration Pitch</h1>
     </div>
-    <div class="slide" data-at="4.0">
+    <div data-at="4.0">
       <img src="images/server-not-found.png"/>
     </div>
-    <div class="slide" data-at="18.0">
+    <div data-at="18.0">
       &ldquo;Is there something <em>I</em> can do to fix this?&rdquo;
     </div>
-    <div class="slide" data-at="28.0">
+    <div data-at="28.0">
       <a href="http://www.theatlantic.com/doc/200803/chinese-firewall"><img src="images/fallows-article.png"/></a>
     </div>
-    <div class="slide" data-at="49.0">
+    <div data-at="49.0">
       <a href="http://www.flickr.com/photos/pfly/130659908/"><img src="images/ethernet.jpg"/></a>
     </div>
-    <div class="slide" data-at="53.5">
+    <div data-at="53.5">
       <a href="http://www.flickr.com/photos/laughingsquid/176520418/"><img src="images/router.jpg"/></a>
     </div>
-    <div class="slide" data-at="56.0">
+    <div data-at="56.0">
       <img src="images/comcast.gif"/>
     </div>
-    <div class="slide" data-at="59.5">
+    <div data-at="59.5">
       <a href="http://www.flickr.com/photos/giantginkgo/69237905/"><img src="images/cubicles.jpg"/></a>
     </div>
-    <div class="slide" data-at="63.0">
+    <div data-at="63.0">
       <a href="http://en.wikipedia.org/wiki/People%27s_Republic_of_China"><img src="images/china-flag.png"/></a>
     </div>
-    <div class="slide" data-at="68.0">
+    <div data-at="68.0">
       bleh.
     </div>
-    <div class="slide" data-at="74.0">
+    <div data-at="74.0">
       &ldquo;Is there something <em>I</em> can do to fix this?&rdquo;
     </div>
-    <div class="slide" data-at="79.0">
+    <div data-at="79.0">
       <a href="http://www.herdict.org/web"><img src="images/herdict-logo.gif"/></a>
     </div>
-    <div class="slide" data-at="82.0">
+    <div data-at="82.0">
       <a href="http://cyber.law.harvard.edu"><img src="images/berkman-logo.png"/></a>
     </div>
-    <div class="slide" data-at="89.0">
+    <div data-at="89.0">
       <a href="http://www.herdict.org/web"><img src="images/herdict-map-2.png"/></a>
     </div>
-    <div class="slide" data-at="100.0">
+    <div data-at="100.0">
       &ldquo;Can other people on the internet see this site?&rdquo;
     </div>
-    <div class="slide" data-at="112.0">
+    <div data-at="112.0">
       &ldquo;Is there something <em>I</em> can do to fix this?&rdquo;
     </div>
-    <div class="slide" data-at="120.0">
+    <div data-at="120.0">
       <a href="http://jboriss.wordpress.com/2010/01/04/herdict-and-its-tasty-anonymized-aggregated-data/"><img src="images/mockup-firewall.png"/></a>
     </div>
-    <div class="slide" data-at="125.0">
+    <div data-at="125.0">
       <a href="http://jboriss.wordpress.com/2010/01/04/herdict-and-its-tasty-anonymized-aggregated-data/"><img src="images/mockup-china.png"/></a>
     </div>
-    <div class="slide" data-at="130.0">
+    <div data-at="130.0">
       <a href="http://jboriss.wordpress.com/2010/01/04/herdict-and-its-tasty-anonymized-aggregated-data/"><img src="images/mockup-everyone.png"/></a>
     </div>
-    <div class="slide" data-at="144.5">
+    <div data-at="144.5">
       <p><img src="images/dino-head.png"/></p>
       <p>For more information, visit the <a href="https://wiki.mozilla.org/Firefox/Projects/Herdict">project wiki page</a>.</p>
     </div>
   </div>
+  <div id="subtitles">
+    <p>Firefox's network error pages are familiar to everyone.</p>
+    <p>But they're not very useful. Most people, if they're like me, see this
+    wall of text and interpret it to mean "the internet broke and we have
+    no idea why."</p>
+    <p>The fundamental question users want answered when they see this is: is
+    there something <em>I</em> can do to fix this?</p>
+    <p>Now, the architecture of the internet makes it fairly hard to pinpoint
+    why a network is down.</p>
+    <p>As James Fallows explains in his article "The Connection Has Been
+    Reset" from The Atlantic's March 2008 issue, some national governments
+    even exploit this to prevent their people from seeing things that the
+    government doesn't want them to see.</p>
+    <p>All this means that a "server not found" error page could have been
+    raised because the user's network connection got unplugged; or it
+    could be because their local router is down; or it could be because
+    their ISP is having problems; or it could be because their corporation
+    is blocking access to the site; or it could be because their
+    government has outlawed access to that particular site; or it could be
+    because the site is actually down.</p>
+    <p>Firefox should do its best to answer that fundamental question:
+    is there something <em>I</em> can do to fix this and get where I want
+    to go?</p>
+    <p>Enter Herdict.</p>
+    <p>Herdict is a project of the Berkman Center for Internet & Society at
+    Harvard University, a brainchild of Professor Jonathan Zittrain, that
+    attempts to use crowdsourcing to generate a global picture of internet
+    connectivity.</p>
+    <p>Put simply, it uses the power of the internet itself to ask the
+    question: <em>can other people on the internet see this site? If so,
+    who?</em></p>
+    <p>Firefox can use the answers to these questions to help answer the
+    user's fundamental question: is there something *I* can do to fix
+    this?</p>
+    <p>This Labs Experiment is an attempt at picturing what
+    Firefox-Herdict-integration might look like. It's intended to be as
+    unintrusive as possible to the user experience, so it only aims to
+    improve upon the already notoriously unhelpful network error
+    pages.</p>
+    <p>Rather than being a final solution, this Labs Experiment is intended
+    to build mindshare and catalyze discussion about what a better network
+    error page might look like, following Mozilla's philosophy of creating
+    things that do stuff to make the internet better.</p>
+  </div>
   <audio id="main" controls="indeed" autobuffer="indeed">
     <source src="audio/ff-herdict-preso.ogg"
 	    type="audio/ogg">
     <source src="audio/ff-herdict-preso.mp3"
 	    type="audio/mpeg">
-  Alas, this presentation requires <a
-  href="http://getfirefox.com">Firefox</a> or another
-  standards-compliant browser that
-  supports the <code>audio</code> element and Ogg Vorbis.
+    Alas, this presentation requires <a
+    href="http://getfirefox.com">Firefox</a> or another
+    standards-compliant browser that
+    supports the <code>audio</code> element.
   </audio>
-  <p id="license">
-  <a rel="license" href="http://creativecommons.org/licenses/by/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/us/80x15.png" /></a></p>
-</div>
-<!-- This is the script for the pitch; eventually we should turn this text -->
-<!-- into live subtitles. -->
-<div id="script">
-Firefox's network error pages are familiar to everyone.
-
-But they're not very useful. Most people, if they're like me, see this
-wall of text and interpret it to mean "the internet broke and we have
-no idea why."
-
-The fundamental question users want answered when they see this is: is
-there something *I* can do to fix this?
-
-Now, the architecture of the internet makes it fairly hard to pinpoint
-why a network is down.
-
-As James Fallows explains in his article "The Connection Has Been
-Reset" from the Atlantic's March 2008 issue, some national governments
-even exploit this to prevent their people from seeing things that the
-government doesn't want them to see.
-
-All this means that a "server not found" error page could have been
-raised because the user's network connection got unplugged; or it
-could be because their local router is down; or it could be because
-their ISP is having problems; or it could be because their corporation
-is blocking access to the site; or it could be because their
-government has outlawed access to that particular site; or it could be
-because the site is actually down.
-
-Firefox should do its best to answer that fundamental question: is
-there something *I* can do to fix this and get where I want to go?
-
-Enter Herdict.
-
-Herdict is a project of the Berkman Center for Internet & Society at
-Harvard University, a brainchild of Professor Jonathan Zittrain, that
-attempts to use crowdsourcing to generate a global picture of internet
-connectivity.
-
-Put simply, it uses the power of the internet itself to ask the
-question: can other people on the internet see this site? If so, who?
-
-Firefox can use the answers to these questions to help answer the
-user's fundamental question: is there something *I* can do to fix
-this?
-
-This Labs Experiment is an attempt at picturing what
-Firefox-Herdict-integration might look like. It's intended to be as
-unintrusive as possible to the user experience, so it only aims to
-improve upon the already notoriously unhelpful network error pages.
-
-Rather than being a final solution, this Labs Experiment is intended
-to build mindshare and catalyze discussion about what a better network
-error page might look like, following Mozilla's philosophy of creating
-things that do stuff to make the internet better.
+  <p id="license"><a rel="license" href="http://creativecommons.org/licenses/by/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/us/80x15.png" /></a></p>
 </div>
 </body>
 <script src="js/jquery.js"></script>
--- a/js/ff-herdict-preso.js	Wed Feb 10 10:49:43 2010 -0800
+++ b/js/ff-herdict-preso.js	Wed Feb 10 12:07:27 2010 -0800
@@ -34,61 +34,82 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
+// This function synchronizes any visual HTML content with the current
+// position of audio content. It's a generic function that can be used
+// to provide e.g. the visuals for a narrated slide-show, or
+// subtitles for a movie.
+//
+// The options object should contain the following keys:
+//
+//   audio        - CSS selector that points to a single HTML5
+//                  <audio> element. The visuals will be synchronized
+//                  with this. Required.
+// 
+//   visuals      - CSS selector that points to a collection
+//                  of DOM elements, each of which is a visual
+//                  to be displayed at some point in the audio. Required.
+// 
+//   visibleClass - Class to add to a visual element when it is
+//                  being displayed. Defaults to "visible".
+// 
+//   syncAttr     - Attribute name on each visual element that
+//                  identifies the time into the audio, in seconds, at
+//                  which the visual element it's attached to should
+//                  be displayed. Every visual element must have
+//                  this attribute, or else an exception will be
+//                  thrown when this function is called. Defaults to
+//                  "data-at".
+function syncVisualsWithAudio(options) {
+  var syncInfo = [];
+  var audio = $(options.audio).get(0);
+  var visuals = $(options.visuals);
+  var visibleClass = options.visibleClass || "visible";
+  var syncAttr = options.syncAttr || "data-at";
+
+  visuals.each(
+    function() {
+      var rawTimestamp = $(this).attr(syncAttr);
+      var timestamp = parseFloat(rawTimestamp);
+      if (isNaN(timestamp))
+        throw new Error("bad '" + syncAttr + "' attribute: " +
+                        rawTimestamp);
+      syncInfo.push({timestamp: timestamp, visual: this});
+    });
+
+  // Return the DOM element that should be displayed as the active
+  // visual the given number of seconds into the audio.
+  function findVisualForTime(timestamp) {
+    var bestVisual;
+
+    for (var i = 0; i < syncInfo.length; i++) {
+      var info = syncInfo[i];
+      if (info.timestamp <= timestamp)
+        bestVisual = info.visual;
+    }
+
+    return bestVisual;
+  }
+
+  // Potentially change the current visual depending on
+  // how far we are into the movie.
+  function maybeChangeVisual() {
+    var visual = findVisualForTime(audio.currentTime);
+    if (visual && !$(visual).hasClass(visibleClass)) {
+      visuals.removeClass(visibleClass);
+      $(visual).addClass(visibleClass);
+    }
+  }
+
+  audio.addEventListener("timeupdate", maybeChangeVisual, false);
+  maybeChangeVisual();
+}
+
 $(window).ready(
   function() {
-    // Ordered list of slides in the presentation. Each element
-    // is a JS object containing the following keys:
-    //
-    //   timestamp - number of seconds into the presentation
-    //               at which the slide should be shown.
-    //
-    //   element   - the DOM element containing the slide's
-    //               content; has the HTML class 'slide'.
-    var slides = [];
-
-    // The main HTML5 audio element that stores our presentation's
-    // soundtrack.
-    var audio = $("audio#main").get(0);
-
-    // Build the 'slides' list by analyzing all slides in the DOM
-    // and parsing out their metadata, throwing an exception
-    // if we encounter any errors.
-    $("#slides .slide").each(
-      function() {
-        var rawTimestamp = $(this).attr("data-at");
-        var timestamp = parseFloat(rawTimestamp);
-        if (isNaN(timestamp))
-          throw new Error("bad 'data-at' attribute: " + rawTimestamp);
-        slides.push({timestamp: timestamp, element: this});
-      });
-
-    // Return the DOM element that should be displayed as the active
-    // slide the given number of seconds into the movie.
-    function findSlideElementForTime(timestamp) {
-      var bestElement;
-
-      for (var i = 0; i < slides.length; i++) {
-        var slide = slides[i];
-        if (slide.timestamp < timestamp)
-          bestElement = slide.element;
-      }
-
-      return bestElement;
-    }
-
-    // Potentially change the current slide depending on
-    // how far we are into the movie.
-    function maybeChangeSlide() {
-      var element = findSlideElementForTime(audio.currentTime);
-      if (element && !$(element).hasClass("visible")) {
-        $("#slides .visible").removeClass("visible");
-        $(element).addClass("visible");
-      }
-    }
-
     // Whenever the current time in the audio soundtrack
-    // changes, alter the current visual if necessary. This
+    // changes, alter the current slide if necessary. This
     // effectively makes the audio UI work just like a
     // movie UI.
-    audio.addEventListener("timeupdate", maybeChangeSlide, false);
+    syncVisualsWithAudio({audio: "audio#main",
+                          visuals: "#slides > div"});
   });