JSFiddle - React, Tailwind, and code Playground

change transition based on user interaction

by Travis Almand

HTML

<div id="app">
  <transition :name="currentTransition" mode="out-in">
    <component :is="slides[currentSlide]"></component>
  </transition>
   
  <div id="panel">
    <button :class="{disabled: currentSlide === 0}" @click="changeSlide('prev')">prev</button>
    <div>{{ currentSlide + 1}} of {{ slides.length }}</div>
    <button :class="{disabled: currentSlide === slides.length - 1}" @click="changeSlide('next')">next</button>
  </div>
</div>

SCSS

#app {
  align-items: center;
  display: flex;
  height: 100vh;
  justify-content: center;
  overflow: hidden;
  width: 100vw;
}

#panel {
  align-items: stretch;
  bottom: 0;
  display: flex;
  position: absolute;
  width: 100%;
  
  button {
    flex-grow: 1;
    font-size: 24px;
    margin: 20px;
    
    &.disabled {
      opacity: 0.5;
      pointer-events: none;
    }
  }
  div {
    align-items: center;
    display: flex;
    font-size: 24px;
  }
}

.slide {
  background-color: rebeccapurple;
  height: 200px;
  width: 400px;
}

.next-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); }
.next-enter-to { transform: scale3d(1, 1, 1); }
.next-enter-active,
.next-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.next-leave { transform: scale3d(1, 1, 1); }
.next-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); }

.prev-enter { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(-400px, 0, 0); }
.prev-enter-to { transform: scale3d(1, 1, 1); }
.prev-enter-active,
.prev-leave-active { transition: 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); }
.prev-leave { transform: scale3d(1, 1, 1); }
.prev-leave-to { opacity: 0; transform: scale3d(2, 0.5, 1) translate3d(400px, 0, 0); }

Vue

Vue.component('slideA', {
	template: '<div class="slide"></div>'
});
Vue.component('slideB', {
	template: '<div class="slide"></div>'
});

new Vue({
  el: "#app",
  data: {
  	slides: ['slideA', 'slideB', 'slideA', 'slideB'],
    currentSlide: 0,
    currentTransition: ''
  },
  methods: {
  	changeSlide: function (dir) {
    	this.currentSlide = dir === 'next' ? this.currentSlide + 1 : this.currentSlide - 1;
    	this.currentTransition = dir;
    }
  }
});