I gave a presentation to the local Linux Users' Group at the Universidad Bolivariana de Venezuela at Caracas a few weeks ago; materials, including slides, are at http://pobox.com/~kragen/talks/2006/ubv for those interested.
I tried using Lessig-style slides --- mostly one or two big words per slide, 50 slides a minute, etc. --- but because I didn't prepare and rehearse as much as I would have liked, I ended up at more like 3 slides per minute on average, throughout a 90-minute presentation. People still seemed to like it. Perhaps due to last-minute venue changes, there were about 15 attendees, half of what we were expecting. I think the syntax for the presentation slides here is about as good as I feel I can expect from HTML. Here's how I did the slides in DHTML; note that this depends on MochiKit. This doesn't work in Safari for some trivial reasons having to do with JavaScript syntax not allowing trailing commas in object literals, and I left out the vertical-centering kludges to support obsolete MSIE; beyond that, I don't know if it has other problems that prevent it from working in Safari, Konqueror, or MSIE. <html><head><title>Slides for UBV presentation</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <style type="text/css"> /* many thanks to "Yuhu" for his * http://www.jakpsatweb.cz/css/css-vertical-center-solution.html * "Vertical Centering in CSS: Yuhu's Definitive Solution with Unknown * Height" which is used here to more or less center the slides */ body, html { height: 100% } /* of the window, to enable vertical centering */ #presentation { display: table; /* all three of these are to enable vertical centering */ height: 100%; width: 100%; overflow: visible; /* so you can scroll if you make stuff too big */ } #presentation div { text-align: center; /* horizontal centering */ font-size: 72pt; /* big, for slides */ font-family: Trebuchet MS, Verdana, sans-serif; /* wish I had better */ padding-left: 54pt; /* wrap without hitting the edges */ padding-right: 54pt; display: none; /* by default, each slide is hidden */ } #presentation div.visible { /* except when it's visible */ display: table-cell; vertical-align: middle; } #presentation div img { vertical-align: middle; } /* center image in line */ /* the next bit is for animation */ .blink_in, .fade_in { opacity: 0; } .blink_in.animation_done, .fade_in.animation_done { opacity: 1 } /* quotes are much longer than normal slides */ q { font-size: 22pt; font-family: Palatino, serif } /* we use an input to get keystrokes to control the thing */ input { border: 0; width: 0px; height: 0px; margin: 0; padding: 0 } </style> <script src="lib/MochiKit/MochiKit.js"></script> <script type="text/javascript">// <![CDATA[ var currently_open = null /* currently visible slide */ function seek_element(node, direction) { while (node && node.nodeType != node.ELEMENT_NODE) { node = node[direction] } return node } function next_element(node) { return seek_element(node, 'nextSibling') } function go_to(node) { removeElementClass(currently_open, 'visible') forEach(currently_open.childNodes, function(child) { if (child.nodeType == node.ELEMENT_NODE) removeElementClass(child, 'animation_done') }) if (node) { currently_open = node addElementClass(currently_open, 'visible') } else { go_to_start() } } function needs_animation(node) { return (node && node.nodeType == node.ELEMENT_NODE && some(keys(animations), function(k) { return hasElementClass(node, k) }) && !hasElementClass(node, 'animation_done')) } function has_animation(node) { return some(node.childNodes, needs_animation) } function fade(node, from_what, frames, timing) { node.style.opacity = from_what if (frames > 0) { setTimeout(function() { fade(node, from_what + (1 - from_what)/frames, frames - 1, timing) }, timing) } else { /* remove explicit opacity, fall back to CSS animation_done rule */ node.style.opacity = '' } } animations = { blink_in: function() { }, fade_in: function(node) { fade(node, 0, 6, 300/6) }, } function animate(node) { var child = next_element(node.firstChild) while (!needs_animation(child)) child = next_element(child.nextSibling) if (!child) { alert('could not animate'); return } // this doesn't work for some reason: // var child_classes = filter(partial(hasElementClass, child), animated_classes) var child_classes = filter(function(k) { return hasElementClass(child, k) }, keys(animations)) log('trying to animate ', repr(child_classes), ' for ', child.innerHTML) animations[child_classes[0]](child) addElementClass(child, 'animation_done') } function next() { if (has_animation(currently_open)) animate(currently_open) else go_to(next_element(currently_open.nextSibling)) $('test_input').focus() } function prev() { go_to(seek_element(currently_open.previousSibling, 'previousSibling')) $('test_input').focus() } function handle_keypress(evt) { if (evt.key().string == ' ') next() } function handle_keydown(evt) { var key = evt.key().string if (key == 'KEY_BACKSPACE') prev() else if (key == 'KEY_ARROW_LEFT') prev() else if (key == 'KEY_ARROW_RIGHT') next() else log("key", key) } function setup() { var inp = $('test_input') connect(inp, 'onkeypress', handle_keypress) connect(inp, 'onkeydown', handle_keydown) inp.focus() go_to_start() } function go_to_start() { currently_open = next_element($('presentation').firstChild) go_to(currently_open) } // ]]> </script> </head> <body onclick="next()" onload="setup()"> <input id="test_input" /> <div id="presentation"> <div>soy Javier Sitaker</div> <div>demasiados temas:</div> <div>¿por que programar?</div> <div>mi historia</div> <div>como programar <span class="blink_in">(generalmente)</span></div> <div><span class="fade_in">¿por</span> <span class="fade_in">que</span> <span class="fade_in">programar?</span></div> <div>nuevo método de pensar</div> <div>Sussman en SICM:<br/> <q class="blink_in">When we started we expected that using this approach to formulate mechanics would be easy. We quickly learned that many things we thought we understood we did not in fact understand. Our requirement that our mathematical notations be explicit and precise enough that they can be interpreted automatically, as by a computer, is very effective in uncovering puns and flaws in reasoning. The resulting struggle to make the mathematics precise, yet clear and computationally effective, lasted far longer than we anticipated. We learned a great deal about both mechanics and computation by this process.<br /></q></div> </div> </body> </html>