Some default Vue2 page transitions, Feel free to use them in your own projects. Suggestions are welcome! :)
A Pen by Tim Rijkse on CodePen.
| <!-- App --> | |
| <div id="app"> | |
| <component :is="state.view"> | |
| <h1>{{ state.view }}</h1> | |
| </component> | |
| <controls></controls> | |
| </div> | |
| <!-- Controls --> | |
| <template id="controls"> | |
| <ul class="controls"> | |
| <li v-for="(animation, index) in state.animations" @click.prevent="setView(animation)" v-bind:class="{ 'active': animation === state.view }"> | |
| {{ animation }} | |
| </li> | |
| </ul> | |
| </template> | |
| <!-- Transitions --> | |
| <template id="page"> | |
| <transition | |
| v-on:enter="enter" | |
| v-on:leave="leave" | |
| v-bind:css="false" | |
| appear | |
| > | |
| <div class="page" v-bind:class="state.view"> | |
| <div class="center"> | |
| <slot></slot> | |
| </div> | |
| </div> | |
| </transition> | |
| </template> |
| // State | |
| const state = { | |
| animations: ['fade', 'slide', 'slideUp', 'zoom', 'flipX', 'flipY'], | |
| view: 'slide' | |
| } | |
| // Controls | |
| const controls = Vue.component('controls', { | |
| template: '#controls', | |
| data: state, | |
| methods: { | |
| setView(animation) { | |
| state.view = animation | |
| } | |
| } | |
| }) | |
| // Transitions | |
| const fade = Vue.component('fade', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| TweenMax.fromTo(el, 1, { | |
| autoAlpha: 0, | |
| scale: 1.5, | |
| }, { | |
| autoAlpha: 1, | |
| scale: 1, | |
| transformOrigin: '50% 50%', | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| }, | |
| leave(el, done) { | |
| TweenMax.fromTo(el, 1, { | |
| autoAlpha: 1, | |
| scale: 1, | |
| }, { | |
| autoAlpha: 0, | |
| scale: 0.8, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| const slide = Vue.component('slide', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| const tl = new TimelineMax({ | |
| onComplete: done | |
| }) | |
| tl.set(el, { | |
| x: window.innerWidth * 1.5, | |
| scale: 0.8, | |
| transformOrigin: '50% 50%' | |
| }) | |
| tl.to(el, 0.5, { | |
| x: 0, | |
| ease: Power4.easeOut | |
| }); | |
| tl.to(el, 1, { | |
| scale: 1, | |
| ease: Power4.easeOut | |
| }); | |
| }, | |
| leave(el, done) { | |
| TweenMax.fromTo(el, 1, { | |
| autoAlpha: 1 | |
| }, { | |
| autoAlpha: 0, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| const slideUp = Vue.component('slideUp', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| const tl = new TimelineMax({ | |
| onComplete: done | |
| }) | |
| tl.set(el, { | |
| y: window.innerWidth * 1.5, | |
| scale: 0.8, | |
| transformOrigin: '50% 50%' | |
| }) | |
| tl.to(el, 0.5, { | |
| y: 0, | |
| ease: Power4.easeOut | |
| }); | |
| tl.to(el, 1, { | |
| scale: 1, | |
| ease: Power4.easeOut | |
| }); | |
| }, | |
| leave(el, done) { | |
| TweenMax.to(el, 1, { | |
| y: window.innerHeight * -1.5, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| const zoom = Vue.component('zoom', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| const tl = new TimelineMax({ | |
| onComplete: done | |
| }) | |
| tl.set(el, { | |
| autoAlpha: 0, | |
| scale: 2, | |
| transformOrigin: '50% 50%' | |
| }) | |
| tl.to(el, 1, { | |
| autoAlpha: 1, | |
| scale: 1, | |
| ease: Power4.easeOut | |
| }) | |
| }, | |
| leave(el, done) { | |
| TweenMax.to(el, 1, { | |
| scale: 0, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| const flipX = Vue.component('flipX', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| const tl = new TimelineMax({ | |
| onComplete: done | |
| }) | |
| tl.set(el, { | |
| autoAlpha: 0, | |
| rotationX: 90, | |
| transformOrigin: '50% 50%' | |
| }) | |
| tl.to(el, 1, { | |
| autoAlpha: 1, | |
| rotationX: 0, | |
| ease: Power4.easeOut | |
| }) | |
| }, | |
| leave(el, done) { | |
| TweenMax.to(el, 1, { | |
| scale: 0, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| const flipY = Vue.component('flipY', { | |
| template: '#page', | |
| methods: { | |
| enter(el, done) { | |
| const tl = new TimelineMax({ | |
| onComplete: done | |
| }) | |
| tl.set(el, { | |
| autoAlpha: 0, | |
| rotationY: 90, | |
| transformOrigin: '50% 50%' | |
| }) | |
| tl.to(el, 1, { | |
| autoAlpha: 1, | |
| rotationY: 0, | |
| ease: Power4.easeOut | |
| }) | |
| }, | |
| leave(el, done) { | |
| TweenMax.to(el, 1, { | |
| scale: 0, | |
| ease: Power4.easeOut, | |
| onComplete: done | |
| }); | |
| } | |
| } | |
| }) | |
| // App | |
| const app = new Vue({ | |
| el: '#app', | |
| data() { | |
| return state | |
| } | |
| }) |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.min.js"></script> |
| $color1: #461467; | |
| $color2: #ffba57; | |
| $color3: lighten(#ff7655, 20%); | |
| $color4: lighten(#00aca0, 10%); | |
| $color5: #8ed3c9; | |
| $color6: darken(#fcf5d8, 20%); | |
| * { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background: #202020; | |
| font-size: 62.5%; | |
| } | |
| // App | |
| #app { | |
| overflow: hidden; | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| width: 100vw; | |
| height: 100vh; | |
| background: rgba(76,76,76,1); | |
| background: -moz-linear-gradient(-45deg, rgba(76,76,76,1) 0%, rgba(43,43,43,0.74) 36%, rgba(28,28,28,0.5) 71%, rgba(19,19,19,0.29) 100%); | |
| background: -webkit-gradient(left top, right bottom, color-stop(0%, rgba(76,76,76,1)), color-stop(36%, rgba(43,43,43,0.74)), color-stop(71%, rgba(28,28,28,0.5)), color-stop(100%, rgba(19,19,19,0.29))); | |
| background: -webkit-linear-gradient(-45deg, rgba(76,76,76,1) 0%, rgba(43,43,43,0.74) 36%, rgba(28,28,28,0.5) 71%, rgba(19,19,19,0.29) 100%); | |
| background: -o-linear-gradient(-45deg, rgba(76,76,76,1) 0%, rgba(43,43,43,0.74) 36%, rgba(28,28,28,0.5) 71%, rgba(19,19,19,0.29) 100%); | |
| background: -ms-linear-gradient(-45deg, rgba(76,76,76,1) 0%, rgba(43,43,43,0.74) 36%, rgba(28,28,28,0.5) 71%, rgba(19,19,19,0.29) 100%); | |
| background: linear-gradient(135deg, rgba(76,76,76,1) 0%, rgba(43,43,43,0.74) 36%, rgba(28,28,28,0.5) 71%, rgba(19,19,19,0.29) 100%); | |
| filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313', GradientType=1 ); | |
| color: #fff; | |
| } | |
| // Controls | |
| .controls { | |
| position: absolute; | |
| left: 50%; | |
| bottom: 40px; | |
| transform: translate(-50%, 0); | |
| width: 100%; | |
| margin-top: 30px; | |
| text-align: center; | |
| padding: 0; | |
| li { | |
| opacity: 0.6; | |
| cursor: pointer; | |
| overflow: hidden; | |
| display: inline-block; | |
| height: 30px; | |
| margin: 0 10px; | |
| padding: 0 30px; | |
| border-radius: 10px; | |
| font: .8rem/30px Arial, sans-serif; | |
| font-family: 'Ubuntu', Helvetica, Arial, sans-serif; | |
| background: #505050; | |
| &.active { | |
| background: lighten(#505050, 40%); | |
| } | |
| } | |
| } | |
| // Page | |
| .page { | |
| position: absolute; | |
| left: 0; | |
| top: 0; | |
| width: 100vw; | |
| height: 100vh; | |
| background: #c0c0c0; | |
| .center { | |
| position: absolute; | |
| left: 50%; | |
| top: 50%; | |
| transform: translate(-50%, -50%); | |
| width: 100%; | |
| font-size: 3rem; | |
| text-align: center; | |
| } | |
| h1 { | |
| width: 100%; | |
| margin: 0; | |
| padding: 0; | |
| font-family: 'Ubuntu', Helvetica, Arial, sans-serif; | |
| font-size: 2.8rem; | |
| text-transform: capitalize; | |
| } | |
| p { | |
| font-family: 'Vollkorn', Georgia, Times, serif; | |
| font-size: 1.1rem; | |
| } | |
| a { | |
| transition: color 200ms ease-out; | |
| color: darken(rgba(#fff, .8), 40%); | |
| &:hover { | |
| color: darken(rgba(#fff, .8), 60%); | |
| } | |
| } | |
| } | |
| // Active animation | |
| .active-animation { | |
| position: absolute; | |
| top: 30px; | |
| left: 50%; | |
| transform: translate(-50%, 0); | |
| } | |
| // Page styles | |
| .fade { | |
| background: $color1; | |
| } | |
| .slide { | |
| background: $color2; | |
| } | |
| .zoom { | |
| background: $color3; | |
| } | |
| .flipX { | |
| background: $color4; | |
| } | |
| .flipY { | |
| background: $color5; | |
| } | |
| .slideUp { | |
| background: $color6; | |
| } |
Some default Vue2 page transitions, Feel free to use them in your own projects. Suggestions are welcome! :)
A Pen by Tim Rijkse on CodePen.