Slider Transition
by dhwanilshah
HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<transition-group tag="div" :name="directionClass" class="scrollable-content">
<div v-for="(card, index) in cards" :key="card['id']" class="card-slider" :id="card['id']">
Card - {{ card['id']}}
</div>
</transition-group>
<br>
{{ activeCardIDs }}
<button @click="swipeCard('left')">Left</button>
<button @click="swipeCard('right')">Right</button>
</div>
CSS
button {
}
.fade-enter-active,
.fade-leave-active {
transition: opacity .5s
}
.fade-enter,
.fade-leave-active {
opacity: 0
}
.scrollable-content {
max-width: 50%;
width: 50%;
min-width: 50%;
background-color: red;
position: relative;
display: flex;
padding: 10px 0;
margin-left: 25%;
}
.card-slider {
min-width: 33%;
color: white;
width: 50% !important;
display: inline-block;
padding: 5px 0;
text-align: center;
}
.card-slider:nth-child(odd) {
background-color: blue;
}
.card-slider:nth-child(even) {
background-color: lightblue;
}
.swipe-left-enter-active,
.swipe-left-leave-active,
.swipe-right-enter-active,
.swipe-right-leave-active {
transition: all 5s ease-in-out;
}
.swipe-right-enter-to {
transform: translateX(-300%);
}
.swipe-right-leave-to {
transform: translateX(-300%);
}
.swipe-left-enter-to {
background-color: grey;
transform: translateX(-488px);
}
.swipe-left-leave-to {
background-color: yellow;
transform: translateX(-488px);
}
Vue
new Vue({
el: '#app',
data: {
n: 0,
activeCardIDs: null,
activeCardIndex: 0,
cards: [],
swipeDirection: null,
scrollerConfig: {'cardsInView': 3},
cardsList: [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 4}, {'id': 5}]
},
beforeMount: function () {
console.log('Setting Up Cards: ', this)
this.setUpCards(this.cards)
},
computed: {
directionClass: function () {
return {
'left': 'swipe-left',
'right': 'swipe-right'
}[this.swipeDirection]
},
cardCount: function () {
return this.cardsList.length
},
},
methods: {
setUpCards: function (cards) {
this.activeCardIndex = 0
this.$nextTick(() => {
if (this.cardCount >= 1) {
this.makeCardsActive(this.activeCardIndex)
} else {
this.cards = []
}
})
},
swipeCard: function (direction) {
this.swipeDirection = direction
if (this.cardCount > this.scrollerConfig['cardsInView']) {
this.swipeDirection = direction
let cardsInView = this.scrollerConfig['cardsInView']
if (direction === 'left') {
if (this.activeCardIndex - cardsInView < 0) {
// if activeIndex goes into negative, then we need to wrap it, add the negative offset i.e. wrapped from end
let negativeOffset = this.activeCardIndex - cardsInView
this.activeCardIndex = this.cardCount - cardsInView < 0 ? 0 : this.cardCount + negativeOffset
} else {
// else, just subtract the number of cards we have to show
this.activeCardIndex = this.activeCardIndex - cardsInView
}
} else if (direction === 'right') {
this.activeCardIndex = (this.activeCardIndex + cardsInView) % this.cardCount
}
this.makeCardsActive(this.activeCardIndex)
}
},
makeCardsActive: function (startIndex) {
this.cards = null
this.activeCardIDs = null
this.$nextTick(() =>...