{"id":250426,"date":"2017-02-03T08:18:20","date_gmt":"2017-02-03T15:18:20","guid":{"rendered":"http:\/\/css-tricks.com\/?p=250426"},"modified":"2019-09-30T11:16:59","modified_gmt":"2019-09-30T18:16:59","slug":"intro-to-vue-5-animations","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/intro-to-vue-5-animations\/","title":{"rendered":"Intro to Vue.js: Animations"},"content":{"rendered":"
This is the fifth part in a five-part series about the JavaScript framework, Vue.js. In this last part of the series, we’ll cover Animations (if you know me at all, you probably knew this was coming). This is not intended to be a complete guide, but rather an overview of the basics to get you up and running so you can get to know Vue.js and understand what the framework has to offer.<\/p>\n
<\/p>\n There are built-in We’ll start off by talking about CSS Transitions, then move on to CSS Animations, then we’ll talk about JS Animation Hooks and then animating with Lifecycle Methods. Transitioning state is out of the scope of this article, but it is possible. Here’s a well-commented Pen I made that does just that<\/a>. I could probably be convinced to write that article too, once I take a long nap.<\/p>\n Just in case you’re confused by why Transitions and Animations have different sections in this article, let me explain that though they sound similar, they’re a bit different. A transition basically works by interpolating the values from state to another. We can do great things with them, but they are rather simple. Here, to there, and back again. <\/p>\n Animations are a bit different in that you can make multiple states occur within one declaration. For instance, you could set a keyframe 50% into the animation, and then another totally different thing can occur at 70%, and so on. You can even chain many animations with delays for really complex movement. Animations have the ability to behave<\/em> like transitions, where we only interpolate something from here to there, but transitions can’t have multiple steps like an animation (not without some crazy hacky development that it’s not really supposed to be used for.) <\/p>\n In terms of tools, both are useful. Think of transitions as a saw and animations as a powersaw. Sometimes you just need to saw one thing and it would be silly to go out and buy really expensive equipment. For other more robust projects, it makes more sense to make the powersaw investment.<\/p>\n Now that we have those basics down, let’s talk about Vue!<\/p>\n Let’s say we have a simple modal. The modal shows and hides on a click of a button. Based on the previous sections, we already know that we might: make a Vue instance with a button, make a child component from that instance, set the data on the state so that it toggles some sort of boolean and add an event handler to show and hide this child component. We could use See the Pen<\/a> by Sarah Drasner.<\/p>\n This works, but it’s pretty jarring to have that modal just pop in our faces like that. 😳<\/p>\n We’re already mounting and unmounting that child component with Now, we could just use I’m going to use a graphic from the docs to show this because I think it describes the classes as beautifully and clearly as possible:<\/p>\n Personally, I don’t usually work with the default Now that we have our hooks, we can create the transition using them:<\/p>\n The Another thing to note here: I’m using You can see we’ve also set the .fade-enter and the .fade-to to See the Pen<\/a> by Sarah Drasner.<\/p>\n This works nicely! But what would happen if we wanted to make that background content fade out of view, so that the modal took center stage and the background lost focus? We can’t use the See the Pen<\/a> by Sarah Drasner.<\/p>\n Now that we understand how transitions work, we can build off of those core concepts to create some nice CSS animations. We’ll still use the In the last section, we talked a little about how you can designate a special name for the transition component that we can then use as class hooks. But in this section, we’ll go a step further, and apply different class hooks to different sections of the animation. You’ll recall that enter-active and leave-active is where all the juicy business of animating happens. We can set different properties on each of these class hooks, but we can go one step further and give special classes to each instance:<\/p>\n This means we can reuse those classes or even plug into the classes from CSS animation libraries.<\/p>\n Let\u2019s say we want a ball to bounce in and roll out:<\/p>\n For the bounce, we’d need a lot of keyframes if we want to do this in CSS (though in JS this could be one line of code), we also will use a SASS mixin to keep our styles DRY (don’t repeat yourself). We’ve also designated the For rolling the ball out, you can see that we need to nest two different animations. This is because the transform is being applied to the entire child component, and spinning the whole thing would result in a huge rotation. So we’ll move the component across the screen with a translation, and spin the ball within with a rotation:<\/p>\n See the Pen Ball Bouncing using Vue transition and CSS Animation<\/a> by Sarah Drasner (@sdras<\/a>) on CodePen<\/a>.<\/p>\n Do you recall when I said that Vue offers some really nice sugary bits in transitions that make nerds like me happy? Here’s a small one that I really love. If you try to transition one component in while another component is leaving, you’ll end up with this really weird moment where both exist at the same time and then snap back into place (this small example from the Vue docs): <\/p>\n Vue offers transition modes, which will allow you to transition one component out while bringing another component in without any strange position flashing or blocking. It does so by ordering the transitioning instead of having them occur at the same time. There are two modes to choose from:<\/p>\n In-out<\/strong>: The current element waits until the new element is done transitioning in to fire<\/p>\n Out-in<\/strong>: The current element transitions out and then the new element transitions in.<\/p>\n Check out the demo below. You can see the mode- See the Pen Vue in-out modes<\/a> by Sarah Drasner (@sdras<\/a>) on CodePen<\/a>.<\/p>\n If we were to take out that mode, you can see that one flip obscures the other, and the animation looks jarring, not at all the effect we want to achieve:<\/p>\n See the Pen Vue in-out modes – no modes contrast<\/a> by Sarah Drasner (@sdras<\/a>) on CodePen<\/a>.<\/p>\n We have some nice JS hooks that are very easy to use or not use as we see fit for our animation. All hooks pass in the At the most basic level, this is really what you would need for an entrance and exit animation, including the corresponding methods:<\/p>\n Here’s an example of how I would use this to plug into a GreenSock timeline:<\/p>\n See the Pen Vue Book Content Typer<\/a> by Sarah Drasner (@sdras<\/a>) on CodePen<\/a>.<\/p>\n Two of the more interesting things to note in the above animation, I\u2019m passing It’s important to note that you can also set what you want for the animation directly in the CSS as the default state as well. People sometimes ask me how to decide what to set in the CSS and what to set in All of this is really nice, but what happens if you need to animate something very complex, something that works with a ton of DOM elements? This is a really nice time to use some lifecycle methods. In the following animation, we have used both the See the Pen Vue Weather Notifier<\/a> by Sarah Drasner (@sdras<\/a>) on CodePen<\/a>.<\/p>\n When we transition a single element, we’ll use the transition component, for instance, when the stroke around the phone button shows up:<\/p>\n But when a component first shows up and we have 30 elements or more animating, it would not longer be efficient to wrap each one in a separate We can really use either depending on what’s more efficient and as you can see, you can create really complex effects. Vue offers a really beautiful and flexible API, not just for creating composable front-end architecture, but also for fluid movement and seamless transitions between views.<\/p>\n This series of articles is not intended to be documentation. Though we\u2019ve covered a lot of ground, there’s still so much more to explore: routing, mixins, server-side rendering, etc. There are so many amazing things to work with. Head over to the very excellent docs<\/a> and this repo full of examples and resources<\/a> to dig in further. There is also a book called The Majesty of Vue.js<\/a>, and courses on Egghead.io<\/a>. <\/p>\n Many thanks to Robin Rendle, Chris Coyier, Blake Newman, and Evan You for proofreading various sections of this series. I hope this series conveys why I\u2019m so excited about Vue and helps you get up and running trying out some of the material! <\/p>\n This is the fifth part in a five-part series about the JavaScript framework, Vue.js. In this last part of the […]<\/p>\n","protected":false},"author":7699,"featured_media":250563,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_share_on_mastodon":"0","_share_on_mastodon_status":"%title% %permalink%"},"categories":[4],"tags":[612,432,1073],"class_list":["post-250426","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","tag-animation","tag-javascript","tag-vue"],"acf":{"show_toc":"No"},"share_on_mastodon":{"url":"","error":""},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-5.jpg?fit=800%2C507&ssl=1","jetpack-related-posts":[{"id":261678,"url":"https:\/\/css-tricks.com\/creating-vue-js-transitions-animations\/","url_meta":{"origin":250426,"position":0},"title":"Creating Vue.js Transitions & Animations","author":"Nicolas Udy","date":"October 24, 2017","format":false,"excerpt":"My last two projects hurled me into the JAMstack. SPAs, headless content management, static generation... you name it. More importantly, they gave me the opportunity to learn Vue.js. More than \"Build a To-Do App\" Vue.js, I got to ship real-life, production-ready Vue apps. The agency behind Snipcart (Spektrum) wanted to\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/10\/s_F5250556F7D3391E68057B73327023BE3FABE38B82BFDFDDC88FB44D203DAEA0_1507664011389_calvin-chin-1929.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/10\/s_F5250556F7D3391E68057B73327023BE3FABE38B82BFDFDDC88FB44D203DAEA0_1507664011389_calvin-chin-1929.jpg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/10\/s_F5250556F7D3391E68057B73327023BE3FABE38B82BFDFDDC88FB44D203DAEA0_1507664011389_calvin-chin-1929.jpg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/10\/s_F5250556F7D3391E68057B73327023BE3FABE38B82BFDFDDC88FB44D203DAEA0_1507664011389_calvin-chin-1929.jpg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/10\/s_F5250556F7D3391E68057B73327023BE3FABE38B82BFDFDDC88FB44D203DAEA0_1507664011389_calvin-chin-1929.jpg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":294862,"url":"https:\/\/css-tricks.com\/learn-design-for-developers-and-svg-animation-with-sarah-drasner-%e2%9c%a8%f0%9f%92%96\/","url_meta":{"origin":250426,"position":1},"title":"Learn Design for Developers and SVG Animation with Sarah Drasner ✨💖","author":"Geoff Graham","date":"September 5, 2019","format":false,"excerpt":"Hey, Marc here from Frontend Masters \u2014 excited to support CSS-Tricks \u2764\ufe0f! Have you checked out Sarah Drasner's courses yet? She has two awesome courses on Design for Developers and SVG! Plus another introducing Vue.js! Design for Developers In the Design for Developers course, you\u2019ll learn to become self-sufficient throughout\u2026","rel":"","context":"In "Sponsored"","block_context":{"text":"Sponsored","link":"https:\/\/css-tricks.com\/category\/sponsored\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/1080.jpg?fit=1200%2C675&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/1080.jpg?fit=1200%2C675&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/1080.jpg?fit=1200%2C675&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/1080.jpg?fit=1200%2C675&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/08\/1080.jpg?fit=1200%2C675&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":250503,"url":"https:\/\/css-tricks.com\/intro-to-vue-4-vuex\/","url_meta":{"origin":250426,"position":2},"title":"Intro to Vue.js: Vuex","author":"Sarah Drasner","date":"February 2, 2017","format":false,"excerpt":"This is the fourth part in a five-part series about the JavaScript framework, Vue.js. In this part, we'll cover Vuex for state management. This is not intended to be a complete guide, but rather an overview of the basics to get you up and running so you can get to\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-4.jpg?fit=800%2C507&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-4.jpg?fit=800%2C507&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-4.jpg?fit=800%2C507&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-4.jpg?fit=800%2C507&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":265413,"url":"https:\/\/css-tricks.com\/creating-vue-js-component-instances-programmatically\/","url_meta":{"origin":250426,"position":3},"title":"Creating Vue.js Component Instances Programmatically","author":"Kushagra Gour","date":"January 23, 2018","format":false,"excerpt":"I have been on a Vue.js project that required the ability to create components programmatically. By programmatically, I mean you create and insert the components completely from JavaScript, without writing anything in the template. This article aims to illustrate how different aspects of using components in a template, such as\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":250488,"url":"https:\/\/css-tricks.com\/intro-to-vue-3-vue-cli-lifecycle-hooks\/","url_meta":{"origin":250426,"position":4},"title":"Intro to Vue.js: Vue-cli and Lifecycle Hooks","author":"Sarah Drasner","date":"February 1, 2017","format":false,"excerpt":"This is the third part in a five-part series about the JavaScript framework, Vue.js. We'll cover Vue-cli, and talk a little more about real-life development processes. This is not intended to be a complete guide, but rather an overview of the basics to get you up and running so you\u2026","rel":"","context":"In "Articles"","block_context":{"text":"Articles","link":"https:\/\/css-tricks.com\/category\/articles\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-3.jpg?fit=800%2C507&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-3.jpg?fit=800%2C507&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-3.jpg?fit=800%2C507&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2017\/01\/vue-3.jpg?fit=800%2C507&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":260954,"url":"https:\/\/css-tricks.com\/vue-js-style-guide\/","url_meta":{"origin":250426,"position":5},"title":"Vue.js Style Guide","author":"Chris Coyier","date":"October 4, 2017","format":false,"excerpt":"\"Style guide\" as in, if you're writing JavaScript using the Vue framework, these are some guidelines they suggest you follow. Not to be confused with a pattern or component library, which happens. Things like using multi-word PascalCase components and abstracting complex logic away from templates. There are a couple dozen\u2026","rel":"","context":"In "Links"","block_context":{"text":"Links","link":"https:\/\/css-tricks.com\/category\/links\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/250426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/7699"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=250426"}],"version-history":[{"count":10,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/250426\/revisions"}],"predecessor-version":[{"id":296678,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/250426\/revisions\/296678"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media\/250563"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=250426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=250426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=250426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}
<\/figure>\nArticle Series:<\/h4>\n
\n
Some background<\/h3>\n
<transition><\/code> and <transition-group><\/code> components that allow for both CSS and JS hooks. If you come from React, the concept behind the transition component will be familiar to you, because it works similarly to ReactCSSTransitionGroup<\/code> in relationship to lifecycle hooks, but it has some notable differences that make nerds like me excited.<\/p>\nTransitions vs. Animations<\/h4>\n
CSS Transitions<\/h3>\n
v-if<\/code> or v-show<\/code> to toggle the visibility. We might even use a slot to pass the button toggle into the modal as well.<\/p>\n<div id=\"app\">\r\n <h3>Let's trigger this here modal!<\/h3>\r\n <button @click=\"toggleShow\">\r\n <span v-if=\"isShowing\">Hide child<\/span>\r\n <span v-else>Show child<\/span>\r\n <\/button>\r\n <app-child v-if=\"isShowing\" class=\"modal\">\r\n <button @click=\"toggleShow\">\r\n Close\r\n <\/button>\r\n <\/app-child>\r\n<\/div>\r\n\r\n<script type=\"text\/x-template\" id=\"childarea\">\r\n <div>\r\n <h2>Here I am!<\/h2>\r\n <slot><\/slot>\r\n <\/div>\r\n<\/script><\/code><\/pre>\nconst Child = {\r\n template: '#childarea'\r\n};\r\n\r\nnew Vue({\r\n el: '#app',\r\n data() {\r\n return {\r\n isShowing: false\r\n }\r\n },\r\n methods: {\r\n toggleShow() {\r\n this.isShowing = !this.isShowing;\r\n }\r\n },\r\n components: {\r\n appChild: Child\r\n }\r\n});<\/code><\/pre>\nv-if<\/code>, so Vue will let us track changes on that event if we wrap that conditional in a transition component:<\/p>\n<transition name=\"fade\">\r\n <app-child v-if=\"isShowing\" class=\"modal\">\r\n <button @click=\"toggleShow\">\r\n Close\r\n <\/button>\r\n <\/app-child>\r\n<\/transition><\/code><\/pre>\n<transition><\/code> out of the box. This will give us a v-<\/code> prefix for some transition hooks we can use in our CSS. It will offer enter\/leave<\/code> which is the position that the animation starts with on the first frame, enter-active\/leave-active<\/code> while the animation is running- this is the one you\u2019d place the animation properties themselves on<\/strong>, and enter-to\/leave-to<\/code>, which specifies where the element should be on the last frame.<\/p>\n
<\/figure>\nv-<\/code> prefix. I’ll always give the transition a name so that there are no collisions if I want to eventually apply another animation. It’s not hard to do so, as you can see above, we simply added a name<\/code> attribute to the transition component: name=\"fade\"<\/code>.<\/p>\n.fade-enter-active, .fade-leave-active {\r\n transition: opacity 0.25s ease-out;\r\n}\r\n\r\n.fade-enter, .fade-leave-to {\r\n opacity: 0;\r\n}<\/code><\/pre>\n.fade-enter-active<\/code> and .fade-leave-active<\/code> classes will be where we apply the actual transition. This is normal CSS, you can pass in cubic-beziers for eases, delays, or specify other properties to transition. Truthfully, this would also work just as well if you placed the transition in these classes on the component classes themselves as a default. These don’t necessarily need to be defined by the transition component hooks. They’ll just chill there, and wait until that property changes and use it to transition if it does. (so you would still need the transition component and .fade-enter, .fade-leave-to). The one reason I do use it on the enter-active and leave-active classes is that I can reuse the same transition for other elements as well, and not run around the codebase applying the same default CSS to each instance.<\/p>\nease-out<\/code> for both active classes. This works and looks fine for something like opacity. But you may find that if you’re transitioning properties such as transform, you might want to separate the two and use ease-out<\/code> for the enter-active class and ease-in<\/code> for the enter-leave class (or cubic-beziers that vaguely follow the same curve). I find it makes the animation look more… classy (har har).<\/p>\nopacity: 0<\/code>. These will be the first and last positions of the animation, the initial state as it mounts, the end state as it unmounts. You may think you need to set opacity: 1<\/code> on .fade-enter-to<\/code>, and .fade-leave<\/code>, but that is unnecessary as it’s the default state for the component, so it would be redundant. CSS transitions and animations will always use the default state unless told otherwise.<\/p>\n<transition><\/code> component, as that component works based on something being mounted or unmounted, and the background is just sticking around. What we can do is transition classes based on the state, and use the classes to create CSS transitions that alter the background:<\/p>\n<div v-bind:class=\"[isShowing ? blurClass : '', bkClass]\">\r\n <h3>Let's trigger this here modal!<\/h3>\r\n <button @click=\"toggleShow\">\r\n <span v-if=\"isShowing\">Hide child<\/span>\r\n <span v-else>Show child<\/span>\r\n <\/button>\r\n <\/div><\/code><\/pre>\n.bk {\r\n transition: all 0.1s ease-out;\r\n}\r\n\r\n.blur {\r\n filter: blur(2px);\r\n opacity: 0.4;\r\n}<\/code><\/pre>\nnew Vue({\r\n el: '#app',\r\n data() {\r\n return {\r\n isShowing: false,\r\n bkClass: 'bk',\r\n blurClass: 'blur'\r\n }\r\n },\r\n ...\r\n});<\/code><\/pre>\nCSS Animation<\/h3>\n
<transition><\/code> component, and we’ll still give it a name, allowing us to have the same class hooks. The difference here will be that instead of just setting the final state and saying how we want it to interpolate between beginning and end, we’ll use @keyframes<\/code> in CSS to create fun and lovely effects. <\/p>\nenter-active-class=\"toasty\"
\nleave-active-class=\"bounceOut\"<\/code><\/p>\n<div id=\"app\">\r\n <h3>Bounce the Ball!<\/h3>\r\n <button @click=\"toggleShow\">\r\n <span v-if=\"isShowing\">Get it gone!<\/span>\r\n <span v-else>Here we go!<\/span>\r\n <\/button>\r\n <transition\r\n name=\"ballmove\"\r\n enter-active-class=\"bouncein\"\r\n leave-active-class=\"rollout\">\r\n <div v-if=\"isShowing\">\r\n <app-child class=\"child\"><\/app-child>\r\n <\/div>\r\n <\/transition>\r\n<\/div><\/code><\/pre>\n.ballmove-enter<\/code> class to let the component know that it should start offscreen:<\/p>\n@mixin ballb($yaxis: 0) {\r\n transform: translate3d(0, $yaxis, 0);\r\n}\r\n\r\n@keyframes bouncein { \r\n 1% { @include ballb(-400px); }\r\n 20%, 40%, 60%, 80%, 95%, 99%, 100% { @include ballb() }\r\n 30% { @include ballb(-80px); }\r\n 50% { @include ballb(-40px); }\r\n 70% { @include ballb(-30px); }\r\n 90% { @include ballb(-15px); }\r\n 97% { @include ballb(-10px); }\r\n}\r\n\r\n.bouncein { \r\n animation: bouncein 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\r\n}\r\n\r\n.ballmove-enter {\r\n @include ballb(-400px);\r\n}<\/code><\/pre>\n@keyframes rollout { \r\n 0% { transform: translate3d(0, 300px, 0); }\r\n 100% { transform: translate3d(1000px, 300px, 0); }\r\n}\r\n\r\n@keyframes ballroll {\r\n 0% { transform: rotate(0); }\r\n 100% { transform: rotate(1000deg); }\r\n}\r\n\r\n.rollout { \r\n width: 60px;\r\n height: 60px;\r\n animation: rollout 2s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; \r\n div {\r\n animation: ballroll 2s cubic-bezier(0.55, 0.085, 0.68, 0.53) both; \r\n }\r\n}<\/code><\/pre>\nSweet, Sweet Transition Modes<\/h4>\n
<\/figure>\nout-in<\/code> on the transition component so that it appears that only one piece is flipping:<\/p>\n<transition name=\"flip\" mode=\"out-in\">\r\n <slot v-if=\"!isShowing\"><\/slot>\r\n <img v-else src=\"https:\/\/s3-us-west-2.amazonaws.com\/s.cdpn.io\/28963\/cartoonvideo14.jpeg\" \/>\r\n<\/transition><\/code><\/pre>\nJS Animation<\/h3>\n
el<\/code> parameter (short for element) except on the actual animation hooks, enter and leave, which also pass done<\/code> as a parameter, which, you guessed it, is used to tell Vue that the animation is completed. You’ll notice we\u2019re also binding CSS to a falsy value to let the component know we’ll be using JavaScript instead of CSS.<\/p>\n<transition \r\n @before-enter=\"beforeEnter\"\r\n @enter=\"enter\"\r\n @after-enter=\"afterEnter\"\r\n @enter-cancelled=\"enterCancelled\"\r\n\r\n @before-Leave=\"beforeLeave\"\r\n @leave=\"leave\"\r\n @after-leave=\"afterLeave\"\r\n @leave-cancelled=\"leaveCancelled\"\r\n :css=\"false\">\r\n \r\n <\/transition><\/code><\/pre>\n<transition \r\n @enter=\"enterEl\"\r\n @leave=\"leaveEl\"\r\n :css=\"false\">\r\n <!-- put element here-->\r\n <\/transition><\/code><\/pre>\nmethods: {\r\n enterEl(el, done) {\r\n \/\/entrance animation\r\n done();\r\n },\r\n leaveEl(el, done) {\r\n \/\/exit animation\r\n done();\r\n },\r\n}<\/code><\/pre>\nnew Vue({\r\n el: '#app',\r\n data() {\r\n return {\r\n message: 'This is a good place to type things.',\r\n load: false\r\n }\r\n },\r\n methods: {\r\n beforeEnter(el) {\r\n TweenMax.set(el, {\r\n transformPerspective: 600,\r\n perspective: 300,\r\n transformStyle: \"preserve-3d\",\r\n autoAlpha: 1\r\n });\r\n },\r\n enter(el, done) {\r\n ...\r\n \r\n tl.add(\"drop\");\r\n for (var i = 0; i < wordCount; i++) {\r\n tl.from(split.words[i], 1.5, {\r\n z: Math.floor(Math.random() * (1 + 150 - -150) + -150),\r\n ease: Bounce.easeOut\r\n }, \"drop+=0.\" + (i\/ 0.5));\r\n ...\r\n \r\n }\r\n }\r\n});<\/code><\/pre>\n{onComplete:done}<\/code> as a parameter to the Timeline instance, and I\u2019m using the beforeEnter<\/code> hook to place my TweenMax.set<\/code> code, which allows me to set any properties on the words I need for the animation before it happens, in this case, things like transform-style: preserve-3d<\/code>. <\/p>\nTweenMax.set<\/code>. As a rule of thumb, I generally put any properties I need specifically for the animation into the TweenMax.set<\/code>. That way if something in the animation changes and I need to update it, it’s already part of my workflow. <\/p>\nAnimations in Lifecycle Hooks<\/h3>\n
<transition><\/code> component as well as the mounted()<\/code> method to create some animations.<\/p>\n<transition \r\n @before-enter=\"beforeEnterStroke\"\r\n @enter=\"enterStroke\"\r\n :css=\"false\"\r\n appear>\r\n <path class=\"main-button\" d=\"M413,272.2c5.1,1.4,7.2,4.7,4.7,7.4s-8.7,3.8-13.8,2.5-7.2-4.7-4.7-7.4S407.9,270.9,413,272.2Z\" transform=\"translate(0 58)\" fill=\"none\"\/>\r\n<\/transition><\/code><\/pre>\nbeforeEnterStroke(el) {\r\n el.style.strokeWidth = 0;\r\n el.style.stroke = 'orange';\r\n},\r\nenterStroke(el, done) {\r\n const tl = new TimelineMax({\r\n onComplete: done\r\n });\r\n\r\n tl.to(el, 0.75, {\r\n strokeWidth: 1,\r\n ease: Circ.easeOut\r\n }, 1);\r\n\r\n tl.to(el, 4, {\r\n strokeWidth: 0,\r\n opacity: 0,\r\n ease: Sine.easeOut\r\n });\r\n},<\/code><\/pre>\ntransition<\/code> component. So, we’ll use the lifecycle methods we mentioned in section 3 of this series to hook into the same event that the transition hook is using under the hook: mounted()<\/code><\/p>\nconst Tornadoarea = {\r\n template: '#tornadoarea',\r\n mounted () {\r\n let audio = new Audio('https:\/\/s3-us-west-2.amazonaws.com\/s.cdpn.io\/28963\/tornado.mp3'),\r\n tl = new TimelineMax();\r\n\r\n audio.play();\r\n tl.add(\"tornado\");\r\n\r\n \/\/tornado timeline begins\r\n tl.staggerFromTo(\".tornado-group ellipse\", 1, {\r\n opacity: 0\r\n }, {\r\n opacity: 1,\r\n ease: Sine.easeOut\r\n }, 0.15, \"tornado\");\r\n ...\r\n }\r\n};<\/code><\/pre>\nConclusion<\/h3>\n
Article Series:<\/h4>\n
\n