{"id":279,"date":"2009-11-05T07:42:09","date_gmt":"2009-11-05T15:42:09","guid":{"rendered":"http:\/\/www.zackgrossbart.com\/hackito\/?p=279"},"modified":"2011-06-13T12:59:21","modified_gmt":"2011-06-13T20:59:21","slug":"present","status":"publish","type":"post","link":"http:\/\/www.zackgrossbart.com\/hackito\/present\/","title":{"rendered":"Give Your Next Presentation In Your Browser With JQuery"},"content":{"rendered":"<p><a href=\"https:\/\/github.com\/zgrossbart\/htmlpresent\"><img decoding=\"async\" style=\"position: absolute; top: 0; right: 0; border: 0;\" src=\"https:\/\/d3nwyuy0nl342s.cloudfront.net\/img\/7afbc8b248c68eb468279e8c17986ad46549fb71\/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67\" alt=\"Fork me on GitHub\"><\/a><\/p>\n<p>\nI&#8217;d rather watch linoleum curl than sit through one more robotic technology presentations. A monotone drone over poorly organized slides turns even the most interesting topics sour.  There are many great blogs about giving better presentations.  <a href=\"http:\/\/www.presentationzen.com\/\">Presentation Zen<\/a> and the <a href=\"http:\/\/blog.duarte.com\/\">Duarte Design<\/a> blog are two worth reading.  I&#8217;ve even written a little of <a href=\"http:\/\/www.cio.com\/article\/501646\/Remote_Public_Speaking_The_Right_Way\">my own advice<\/a>.\n<\/p>\n<p>\nGood presentations are well thought out, have strong supporting materials, and tell interesting stories.  They also have a sense of pacing.  When I present I want one topic to flow into the next, but nothing ruins pacing faster than watching the presenter fool around with PowerPoint when they should be presenting.\n<\/p>\n<blockquote><p>\n&#8220;OK.  Now we&#8217;ll switch to the demo&#8230; Where&#8217;s that button&#8230; Hey Bob do you know how to make this PowerPoint window go away?&#8221;\n<\/p><\/blockquote>\n<div class=\"sourcebox\">\n    See a presentation<br \/><a href=\"\/extras\/jquery_pres\">in Action<\/a>\n<\/div>\n<p>\nSwitching between applications during a presentation throws off your pacing and I don&#8217;t like to do it.  I recently gave <a href=\"\/extras\/css_pres\/\">a presentation about CSS<\/a>, with many examples that ran in a web browser.  The solution was simple: put all of my presentation in the browser.\n<\/p>\n<p>\nI created a new presentation program using simple HTML, CSS, and JavaScript.  This slide show works in all browsers and on all platforms; sharing it is as simple as sending an URL.  Just like <a href=\"http:\/\/www.slideshare.net\/\">SlideShare.net<\/a> you can host anywhere without all that Flash.  This approach also gives you the big advantage of writing your slides in HTML.  The only drawback is you have to write your slides in HTML.\n<\/p>\n<p>\nThis article shows you how to create your own presentations with JQuery and gives you an in-depth look at how this program works.  It is a useful introduction to JQuery programming and a working program for giving presentations.  It&#8217;s also released under the <a href=\"http:\/\/www.apache.org\/licenses\/LICENSE-2.0\">Apache 2.0 License<\/a> and is totally free.\n<\/p>\n<h2>See It In Action<\/h2>\n<p>This all started because I wanted to give a presentation about CSS that had many CSS examples.  I figured I could combine the presentation and the examples in one and I got <a href=\"\/extras\/css_pres\/\">Zack&#8217;s (Not So) Basic CSS<\/a>.  I kept this presentation simple because I wanted to keep the CSS simple.<\/p>\n<p>A few weeks later I gave a presentation about <a href=\"http:\/\/jquery.com\/\">JQuery<\/a> that got a little more complex.  <a href=\"\/extras\/jquery_pres\/\">Zack&#8217;s JQuery Jumpstart<\/a> added a navigation footer and a much nicer key explaining the keyboard navigation.  <\/p>\n<p>This framework is a flexible alternative to PowerPoint.  You can change these presentations with CSS and make them look any way you want.  Let&#8217;s take a look at how it works.<\/p>\n<h2>The HTML<\/h2>\n<p>You do most of your work for these presentations in HTML.  Each slide is a <code>div<\/code> tag with a class of <code>slide<\/code>.  The easiest type of slide is a content slide like this:<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">&lt;div class=\"slide\"&gt;\r\n    &lt;p class=\"titleslide\"&gt;\r\n        My Title Slide\r\n    &lt;\/p&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>There are a few other built-in slide types including content slides:<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">&lt;div class=\"slide contentslide\"&gt;\r\n    &lt;p&gt;\r\n        I'm going to put a lot of text here.\r\n    &lt;\/p&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>and <code>iframe<\/code> slides for embedding other website into your presentation:<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">&lt;div class=\"slide\"&gt;\r\n    &lt;iframe src=\"an url\" frameborder=\"0\" scrolling=\"no\" width=\"100%\" height=\"99.7%\"&gt;&lt;\/iframe&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>Each slide is HTML and the sky&#8217;s the limit.  As long as your data is contained in a <code>div<\/code> tag and with the class <code>slide<\/code> you can put anything you want in there.  The slides will appear in your presentation in the order they are written in the HTML file.<\/p>\n<p>The HTML also contains the controls like the navigation key and the footer that automatically integrate with your presentation.  Any slide you have will display above the footer.  <\/p>\n<h2>The CSS<\/h2>\n<p>You can add whatever CSS you want to support your slides, but the presentation needs some basic CSS to make each slide work.<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">.slide {\r\n    position: absolute;\r\n    top: 0px;\r\n    left: 0px;\r\n    width: 100%;\r\n    height: 100%;\r\n    background: white;\r\n}\r\n\r\n.titleslide {\r\n    position: relative;\r\n    top: 33%;\r\n    font-size: 72px;\r\n    text-align: center;\r\n    vertical-align: middle;\r\n}\r\n\r\n.contentslide {\r\n    margin: 2em;\r\n    height: 85%;\r\n    width: 85%;\r\n    display: inline;\r\n    left: 10%;\r\n    top: 10%;\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>This CSS basically does three things: <\/p>\n<ol>\n<li>Make a single slide take up the whole screen<\/li>\n<li>Make the text in title slides center aligned and really big<\/li>\n<li>Add a little spacing to content slides<\/li>\n<\/ol>\n<h2>The JavaScript<\/h2>\n<p>The JavaScript is where the magic happens, but it&#8217;s more rabbit out of a hat than Harry Potter.<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">$(\".slide\").each(function () {\r\n  slideCount++;\r\n  $(this).css(\"display\", \"none\");\r\n  slideArray[slideCount] = $(this);\r\n});\r\n    \r\nslideArray[currentSlide].css(\"display\", \"block\");\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>First we iterate over all the slides and add them to an array.  While we iterate we also hide every slide.  Once we&#8217;ve done that we just make the first slide visible.  <\/p>\n<p>After we add this stack of slides to an array positioning the slide deck is easy.  We simply hide the current slide and show the requested slide.<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">function positionSlide(<span class=\"code_comment\">\/*int*\/<\/span> slide) {\r\n    if (slide > 0 && slide <= slideCount) {\r\n        slideArray[currentSlide].hide();\r\n        currentSlide = slide;\r\n        slideArray[currentSlide].show();\r\n    }\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>If you wanted to get fancy you could do this with a <a href=\"http:\/\/docs.jquery.com\/Effects\">JQuery Effect<\/a>.  Just replace the calls to <code>hide<\/code> and <code>show<\/code> to calls for <code>slideIn<\/code> or <code>fadeIn<\/code> and you are all set.  I kept it simple because I often <a href=\"http:\/\/www.zackgrossbart.com\/blog\/2009\/09\/we-pres-example\">present remotely<\/a> where animations look choppy.<\/p>\n<p>The rest of code takes care of enabling and disabling buttons and hiding and showing controls.  Switching from one slide to another is fast and easy.  I can use my keyboard, the arrow buttons, or jump to a specific slide.  You can see <a href=\"https:\/\/github.com\/zgrossbart\/htmlpresent\">all the source code<\/a>.<\/p>\n<h2>A Little Bonus<\/h2>\n<p>One of <a href=\"http:\/\/blog.duarte.com\/\">my favorite presenters<\/a> likes to start her presentations with an <a href=\"http:\/\/blog.duarte.com\/2009\/03\/animation-works-like-magic\/\">animation<\/a>.  The animation gives the audience something to look at while they are finding a place to sit and waiting for the presentation to start.  PowerPoint makes animations like this pretty easy and I wanted to do the same with JQuery<\/p>\n<div class=\"sourcebox\">\n    See the animation<br \/><a href=\"\/extras\/jquery_pres\/jquery_anim.html\">in Action<\/a>\n<\/div>\n<p>For my recent <a href=\"http:\/\/www.zackgrossbart.com\/extras\/jquery_pres\/\">JQuery presentation<\/a> I started things off with a simple <a href=\"http:\/\/docs.jquery.com\/Effects\/animate#paramsdurationeasingcallback\">JQuery animation<\/a>.  <\/p>\n<p>The animation uses a special type of slide called an <code>animatedslide<\/code>.  In this slide you give every word you want animated a different class:<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">&lt;div class=\"slide\"&gt;\r\n    &lt;p class=\"titleslide animateslide\"&gt;\r\n        &lt;span class=\"animcell\"&gt;Welcome&lt;\/span&gt; \r\n        &lt;span class=\"animcell\"&gt;To&lt;\/span&gt; \r\n        &lt;span class=\"animcell\"&gt;Zack's&lt;\/span&gt; \r\n        &lt;span class=\"animcell\"&gt;JQuery&lt;\/span&gt; \r\n        &lt;span class=\"animcell\"&gt;Jumpstart&lt;\/span&gt;\r\n    &lt;\/p&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>Then the JavaScript kicks in:<\/p>\n<table class=\"code_table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td class=\"code-outline\">\n<pre class=\"displaycode\">function anim(<span class=\"code_comment\">\/*JQuery*\/<\/span> obj) {\r\n\r\n    <span class=\"code_comment\">\/*\r\n     * JavaScript doesn't give you direct access to threads\r\n     * so starting and stopping animations doesn't work \r\n     * very well.  We hack around that by only running the\r\n     * animation a certain number of times.\r\n     *\/<\/span>\r\n    var count = 0;\r\n\r\n    <span class=\"code_comment\">\/*\r\n     * These variables hold the current position of the element.\r\n     *\/<\/span>\r\n    var x = 0;\r\n    var y = 0;\r\n    \r\n    while(count < 300) {\r\n\r\n        <span class=\"code_comment\">\/*\r\n         * Step 1. Generate a random number for the direction to \r\n         * move the text.\r\n         *\/<\/span>\r\n        var direction = Math.floor(Math.random() * 5);\r\n        \r\n        count++;\r\n        if(x > 300 || x < -300 ||\r\n           y > 300 || y < -300) {\r\n            <span class=\"code_comment\">\/*\r\n             * Step 2a. We don't want the text to move too far out of\r\n             * the screen so we'll push it back to the center when it\r\n             * is too close to the edge.\r\n             *\/ <\/span>\r\n            obj.animate({ \r\n                left: \"0px\",\r\n                top: \"0px\"\r\n                }, 3000, \"linear\");\r\n            \r\n            x = 0;\r\n            y = 0;\r\n        } else {\r\n            <span class=\"code_comment\">\/*\r\n             * Step 2b.  We increase or decrease the X or the Y depending\r\n             * on the direction we want the text to move.\r\n             *\/<\/span>\r\n            if (direction == 1) { <span class=\"code_comment\">\/\/go left<\/span>\r\n                x -= 100 + Math.floor(Math.random() * 201);\r\n            } else if (direction == 2) { <span class=\"code_comment\">\/\/go right<\/span>\r\n                x += 100 + Math.floor(Math.random() * 201);\r\n            } else if (direction == 3) { <span class=\"code_comment\">\/\/go top<\/span>\r\n                y -= 100 + Math.floor(Math.random() * 201);\r\n            } else if (direction == 4) { <span class=\"code_comment\">\/\/go bottom<\/span>\r\n                y += 100 + Math.floor(Math.random() * 201);\r\n            }\r\n\r\n            <span class=\"code_comment\">\/*\r\n             * Step 3.  We run the animation.\r\n             *\/<\/span>\r\n            obj.animate({ \r\n                left: x + \"px\",\r\n                top: y + \"px\"\r\n                }, 3000, \"linear\");\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/table>\n<p>I know it looks a little complicated, but it's really pretty simple.  Each word chooses a random direction and moves a random amount in that direction.  If the words gets too close to the edge of the screen it bounces back to where it started.  The effect is simple, but strangely hypnotic.<\/p>\n<p>I must confess there is a hack here.  The animation will repeat 300 times and stop.  I've done multi-threaded programming in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Java_(programming_language)\">Java<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/C%2B%2B\">C++<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Erlang_(programming_language)\">Erlang<\/a>, and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Scala_(programming_language)\">Scala<\/a>, but the threading model of JavaScript is still a mystery to me.  If someone knows a better way to make this work I would love to hear about it.<\/p>\n<h2>Build Your Own Presentation<\/h2>\n<div class=\"sourcebox\">\n    Make your own<br \/><a href=\"\/extras\/jquery_pres\/presentation_example.zip\">presentation<\/a>\n<\/div>\n<p>Now that you've seen how it works you're ready to build your own presentation.  Just <a href=\"\/extras\/jquery_pres\/presentation_example.zip\">download the sample presentation<\/a> and add your slides to the index.html file.  When you're done just post it to your favorite web server.  The presentation will run with just about every browser and every operating system.<\/p>\n<h2>Conclusion<\/h2>\n<p>Building all of your presentations in HTML is just silly, but when you need to include many live web pages this is a good solution for the \"um... where is the button to get out of PowerPoint?\" problem.  The results are small, fast, and easy to share.  They'll also get indexed by Google unlike SlideShare presentations.<\/p>\n<p>Beyond the usefulness of this application I like the idea of turning a web browser into something else.  Browsers are an interesting platform, but if they want to be taken seriously they need to stop just supporting web pages.<\/p>\n<h2>Name This Application Contest<\/h2>\n<p>You may have noticed that this poor application doesn't have a name.  I'm holding a contest to suggest a name.  Just post your suggestions as a comment.  The winner gets a free copy of this open source software.  Good luck!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;d rather watch linoleum curl than sit through one more robotic technology presentations. A monotone drone over poorly organized slides turns even the most interesting topics sour. There are many great blogs about giving better presentations. Presentation Zen and the Duarte Design blog are two worth reading. I&#8217;ve even written a little of my own [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/279"}],"collection":[{"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/comments?post=279"}],"version-history":[{"count":17,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/279\/revisions"}],"predecessor-version":[{"id":291,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/posts\/279\/revisions\/291"}],"wp:attachment":[{"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/media?parent=279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/categories?post=279"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.zackgrossbart.com\/hackito\/wp-json\/wp\/v2\/tags?post=279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}