A study of view animations using css & javascript animation
<template>
<section class="container">
<div>
<logo/>
<h1 class="title">
nuxt-animation
</h1>
<h2 class="subtitle">
My rad Nuxt.js project
</h2>
<select name="" id="" v-model="alertAnimation" class="form-control">
<option value="slide">slide</option>
<option value="fade">Fade</option>
</select><br><br>
<button class="btn btn-primary" @click="showAlert = !showAlert">Send Alert</button>
<br><br>
<transition :name="alertAnimation">
<div class="alert alert-primary" v-if="showAlert">This is an Alert not to ignore!</div>
</transition>
<transition :name="alertAnimation" type="animation">
<div class="alert alert-primary" v-if="showAlert">This is an Alert not to ignore!</div>
</transition>
<hr>
<button class="btn btn-primary" @click="showElement = !showElement">Show / Hide Element</button>
<br><br>
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
:css='false'>
<div style="height: 100px; width: 300px; background-color: lightgreen" v-if="showElement"></div>
</transition>
</div>
</section>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
},
data () {
return {
showAlert: true,
alertAnimation: "fade",
showElement: false,
elementWidth: 100,
}
},
methods: {
beforeEnter(el) {
console.log("beforeEnter")
this.elementWidth = 100
el.style.with = this.elementWidth + 'pxs'
},
enter(el, done){
console.log('enter')
let round = 1
const interval = setInterval(()=>{
el.style.width = (this.elementWidth + round * 10) + 'px'
round++
if (round > 20) {
clearInterval(interval)
done()
}
},20)
},
afterEnter(el){
console.log('afterEnter')
},
enterCancelled(el) {
console.log("enterCancelled")
},
beforeLeave(el){
console.log('beforeLeave')
this.elementWidth = 300
el.style.width = this.elementWidth + 'px'
},
leave(el, done){
console.log("leave")
let round = 1
const interval = setInterval(()=>{
el.style.width = (this.elementWidth - round * 10) + 'px'
round++
if (round > 20) {
clearInterval(interval)
done()
}
},20)
},
afterLeave(el){
console.log("afterLeave")
},
leaveCancelled(el){
console.log('leaveCancelled')
}
}
}
</script>
<style>
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 1s;
}
.fade-leave {
}
.fade-leave-active {
transition: opacity 1s;
opacity: 0;
}
/* CSS animations */
.slide-enter {
opacity: 0;
}
.slide-enter-active {
animation: slide-in 1s ease-out forwards;
transition: opacity .5s;
}
.slide-leave {
}
.slide-leave-active {
animation: slide-out 1s ease-out forwards;
transition: opacity 3s;
opacity: 0;
}
@keyframes slide-in {
from {
transform: translateY(20px);
}
to {
transform: translateY(0);
}
}
@keyframes slide-out {
from {
transform: translateY(0px);
}
to {
transform: translateY(20px);
}
}
.container
{
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.title
{
font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
.subtitle
{
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
.links
{
padding-top: 15px;
}
</style>