moringaman
2/16/2018 - 1:23 AM

Vue Animations

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>