<!-- 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>
$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;
}
View Compiled
// 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
	}
})
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.min.js