{"database": "24ways", "table": "articles", "is_view": false, "human_description_en": "where author = \"Dan Mall\" and year = 2010", "rows": [[235, "Real Animation Using JavaScript, CSS3, and HTML5 Video", "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 <div> 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 <div>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 <div> 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 <div> 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<style>\n\t.animate {\n\t\t-webkit-animation-name: ANIMATE;\n\t\t-webkit-animation-duration: 0.25s;\n\t\t-webkit-animation-iteration-count: 1;\n\t\t-webkit-animation-timing-function: ease-in;\n\t}\n\t@-webkit-keyframes ANIMATE {\n\t\tfrom {\n\t\ttop: 72px;\n\t\t}\n\t\tto {\n\t\t\ttop: 112px;\n\t\t}\n\t}\n</style>\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 <div> 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<style>\n\t@-webkit-keyframes ANIMATE {\n\t\t0% {\n\t\t\ttop: 72px;\n\t\t}\n\t\t40% { /* anticipation */\n\t\t\ttop: 57px;\n\t\t}\n\t\t70% { /* hold */\n\t\t\ttop: 56px;\n\t\t}\n\t\t80% { /* release */\n\t\t\ttop: 112px;\n\t\t}\n\t\t100% { /* return */\n\t\t\ttop: 72px;\n\t\t}\n\t}\n</style>\n\nTake 4\n\nThe button animation is starting to feel much better, but the reaction of the <div> 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 <video> element to the page and adjust its opacity to zero. Once the button is clicked, fade the button out and start playing the video. Once the video is finished playing, fade it out and bring the button back.\n\nfunction clickHandler(){\n\tif($('#main .inner').is(':hidden')){\n\t\t$('#button').fadeTo(100, 0);\n\t\t$('#clickVideo').fadeTo(100, 1, function(){\n\t\t\tvar clickVideo = document.getElementById('clickVideo');\n\t\t\tclickVideo.play();\n\t\t\tsetTimeout(removeVideo, 2400);\n\t\t\topenMain();\n\t\t});\n\t}\n\treturn false;\n}\nfunction removeVideo(){\n\t$('#button').fadeTo(500, 1);\n\t$('#clickVideo').fadeOut('slow');\n}\nfunction openMain(){\n\t$('#main .inner').delay(1100).slideDown('slow');\n}\n\nWrapping up\n\nI\u2019m no JavaScript expert by any stretch. I\u2019m sure a lot of you scripting wizards out there could write much cleaner and more efficient code, but I hope this gives you an idea of the theory behind more realistic motion with the technology we\u2019re using most. This is just one model of creating more convincing animation, but you can create countless variations of this, including\u2026\n\n\n\tExporting <video> animations in 3-D animation tools or 2-D animation tools like Flash or After Effects\n\tUsing <canvas> or SVG instead of <video>\n\tEmploying specific JavaScript animation frameworks\n\tMaking use of all the powerful properties of CSS Transforms and CSS Animation\n\tTrying out emerging CSS3 animation tools like Sencha Animator\n\n\nIf it wasn\u2019t already apparent, these demos show an exaggerated example and probably aren\u2019t practical in a lot of environments. However, there are a handful of great sites out there that honor animation techniques\u2014metaphor, physics, and misdirection, among others\u2014like Benjamin De Cock\u2019s vCard, 20 Things I Learned About Browsers and the Web by Fantasy Interactive, and the Nike Snowboarding site by Ian Coyle and HEGA. They\u2019re wonderful testaments to what you can do to aid interaction for users.\n\nMy goal was to show you the \u2018why\u2019 and the \u2018how.\u2019 Your charge is to discern the \u2018where\u2019 and the \u2018when.\u2019 Happy animating!", "2010", "Dan Mall", "danmall", "2010-12-15T00:00:00+00:00", "https://24ways.org/2010/real-animation-using-javascript-css3-and-html5-video/", "code"]], "truncated": false, "table_rows_count": 336, "filtered_table_rows_count": 1, "expanded_columns": [], "expandable_columns": [], "columns": ["rowid", "title", "contents", "year", "author", "author_slug", "published", "url", "topic"], "primary_keys": [], "units": {}, "query": {"sql": "select rowid, * from articles where \"author\" = :p0 and \"year\" = :p1 order by rowid limit 101", "params": {"p0": "Dan Mall", "p1": "2010"}}, "facet_results": {}, "suggested_facets": [], "next": null, "next_url": null, "query_ms": 10.6658935546875}