{"rowid": 235, "title": "Real Animation Using JavaScript, CSS3, and HTML5 Video", "contents": "When I was in school to be a 3-D animator, I read a book called Timing for Animation. Though only 152 pages long, it\u2019s essentially the bible for anyone looking to be a great animator. In fact, Pixar chief creative officer John Lasseter used the first edition as a reference when he was an animator at Walt Disney Studios in the early 1980s.\n\nIn the book, authors John Halas and Harold Whitaker advise:\n\n\n\tTiming is the part of animation which gives meaning to movement. Movement can easily be achieved by drawing the same thing in two different positions and inserting a number of other drawings between the two. The result on the screen will be movement; but it will not be animation.\n\n\nBut that\u2019s exactly what we\u2019re doing with CSS3 and JavaScript: we\u2019re moving elements, not animating them. We\u2019re constantly specifying beginning and end states and allowing the technology to interpolate between the two. And yet, it\u2019s the nuances within those middle frames that create the sense of life we\u2019re looking for.\n\nAs bandwidth increases and browser rendering grows more consistent, we can create interactions in different ways than we\u2019ve been able to before. We\u2019re encountering motion more and more on sites we\u2019d generally label \u2018static.\u2019 However, this motion is mostly just movement, not animation. It\u2019s the manipulation of an element\u2019s properties, most commonly width, height, x- and y-coordinates, and opacity.\n\nSo how do we create real animation?\n\nThe metaphor\n\nIn my experience, animation is most believable when it simulates, exaggerates, or defies the real world. A bowling ball falls differently than a racquetball. They each have different weights and sizes, which affect the way they land, bounce, and impact other objects.\n\nThis is a major reason that JavaScript animation frequently feels mechanical; it doesn\u2019t complete a metaphor. Expanding and collapsing a
feels very different than a opening a door or unfolding a piece of paper, but it often shouldn\u2019t. The interaction itself should tie directly to the art direction of a page.\n\nPhysics\n\nUnderstanding the physics of a situation is key to creating convincing animation, even if your animation seeks to defy conventional physics. Isaac Newton\u2019s first law of motion\u2019s_laws_of_motion states, \u201cEvery body remains in a state of rest or uniform motion (constant velocity) unless it is acted upon by an external unbalanced force.\u201d Once a force acts upon an object, the object\u2019s shape can change accordingly, depending on the strength of the force and the mass of the object. Another nugget of wisdom from Halas and Whitaker:\n\n\n\tAll objects in nature have their own weight, construction, and degree of flexibility, and therefore each behaves in its own individual way when a force acts upon it. This behavior, a combination of position and timing, is the basis of animation. The basic question which an animator is continually asking himself is this: \u201cWhat will happen to this object when a force acts upon it?\u201d And the success of his animation largely depends on how well he answers this question.\n\n\nIn animating with CSS3 and JavaScript, keep physics in mind. How \u2018heavy\u2019 is the element you\u2019re interacting with? What kind of force created the action? A gentle nudge? A forceful shove? These subtleties will add a sense of realism to your animations and make them much more believable to your users.\n\nMisdirection\n\nMagicians often use misdirection to get their audience to focus on one thing rather than another. They fool us into thinking something happened that actually didn\u2019t.\n\nAnimation is the same, especially on a screen. By changing the arrangement of pixels on screen at a fast enough rate, your eyes fool your mind into thinking an object is actually in motion. \n\nAnother important component of misdirecting in animation is the use of multiple objects. Try to recall a cartoon where a character vanishes. More often, the character makes some sort of exaggerated motion (this is called anticipation) then disappears, and a puff a smoke follows. That smoke is an extra element, but it goes a long way into make you believe that character actually disappeared.\n\nVery rarely does a vanishing character\u2019s opacity simply go from one hundred per cent to zero. That\u2019s not believable. So why do we do it with
s?\n\nArmed with the ammunition of metaphors and misdirection, let\u2019s code an example.\n\nShake, rattle, and roll\n\n(These demos require at least a basic understanding of jQuery and CSS3. Run away if your\u2019re afraid, or brush up on CSS animation and resources for learning jQuery. Also, these demos use WebKit-specific features and are best viewed in the latest version of Safari, so performance in other browsers may vary.)\n\nWe often see the design pattern of clicking a link to reveal content. Our \u201cfirst demo\u201d:\u201d/examples/2010/real-animation/demo1/ shows us exactly that. It uses jQuery\u2019s \u201c slideDown()\u201d:http://api.jquery.com/slideDown/ method, as many instances do.\n\nBut what force acted on the
that caused it to open? Did pressing the button unlatch some imaginary hook? Did it activate an unlocking sequence with some gears?\n\nTake 2\n\nOur second demo is more explicit about what happens: the button fell on the
and shook its content loose. Here\u2019s how it\u2019s done. \n\nfunction clickHandler(){\n\t$('#button').addClass('animate');\n\treturn false;\n}\n\nClicking the link adds a class of animate to our button. That class has the following CSS associated with it:\n\n\n\nIn our keyframe definition, we\u2019ve specified from and to states. This is great, because we can be explicit about how an object starts and finishes moving. \n\nWhat\u2019s also extra handy is that these CSS keyframes broadcast events that you can react to with JavaScript. In this example, we\u2019re listening to the webkitAnimationEnd event and opening the
only when the sequence is complete. Here\u2019s that code.\n\nfunction attachAnimationEventHandlers(){\n\tvar wrap = document.getElementById('wrap');\n\twrap.addEventListener('webkitAnimationEnd', function($e) {\n\t\tswitch($e.animationName){\n\t\t\tcase \"ANIMATE\" :\n\t\t\topenMain();\n\t\t\tbreak;\n\t\t\tdefault:\n\t\t}\n\t}, false);\n}\nfunction openMain(){\n\t$('#main .inner').slideDown('slow');\n}\n\n(For more info on handling animation events, check out the documentation at the Safari Reference Library.)\n\nTake 3\n\nThe problem with the previous demo is that the subtleties of timing aren\u2019t evident. It still feels a bit choppy.\n\nFor our third demo, we\u2019ll use percentages instead of keywords so that we can insert as many points as we need to communicate more realistic timing. The percentages allow us to add the keys to well-timed animation: anticipation, hold, release, and reaction. \n\n\n\nTake 4\n\nThe button animation is starting to feel much better, but the reaction of the
opening seems a bit slow.\n\nThis fourth demo uses jQuery\u2019s delay() method to time the opening precisely when we want it. Since we know the button\u2019s animation is one second long and its reaction starts at eighty per cent of that, that puts our delay at 800ms (eighty per cent of one second). However, here\u2019s a little pro tip: let\u2019s start the opening at 750ms instead. The extra fifty milliseconds makes it feel more like the opening is a reaction to the exact hit of the button. Instead of listening for the webkitAnimationEnd event, we can start the opening as soon as the button is clicked, and the movement plays on the specified delay.\n\nfunction clickHandler(){\n\t$('#button').addClass('animate');\n\topenMain();\n\treturn false;\n}\nfunction openMain(){\n\t$('#main .inner').delay(750).slideDown('slow');\n}\n\nTake 5\n\nWe can tweak the timing of that previous animation forever, but that\u2019s probably as close as we\u2019re going to get to realistic animation with CSS and JavaScript. However, for some extra sauce, we could relegate the whole animation in our final demo to a video sequence which includes more nuances and extra elements for misdirection.\n\nHere\u2019s the basis of video replacement. Add a