Shuffle Deck of Cards
A Shuffle Deck of Cards Transitions with Vue example.
html
<div id="app">
<div class="title-section">
<h1 class="title">
<img class="vue" src="https://vuejs.org/images/logo.png" />
Card Shuffling</h1>
<div class="speed-buttons">
<a class="button is-small"
:class="[{ 'is-outlined': shuffleButtonActive === 0, 'is-light': shuffleButtonActive != 0 }]"
@click="selectShuffleSpeed(0)">
Slow
</a>
<a class="button is-small"
:class="[{ 'is-outlined': shuffleButtonActive === 1, 'is-light': shuffleButtonActive != 1 }]"
@click="selectShuffleSpeed(1)">
Medium
</a>
<a class="button is-small"
:class="[{ 'is-outlined': shuffleButtonActive === 2, 'is-light': shuffleButtonActive != 2 }]"
@click="selectShuffleSpeed(2)">
Fast
</a>
</div>
<div class="main-buttons">
<transition name="fade">
<a v-if="shuffledDeck" @click="displayInitialDeck" class="button is-primary is-outlined">
Reset
<i class="fas fa-undo"></i>
</a>
</transition>
<transition :name="shuffleSpeed">
<a @click="shuffleDeck" class="button is-primary">
Shuffle
<i class="fas fa-random"></i></a>
</transition>
</div>
<transition name="fade">
<div v-if="shuffleCount" class="count-section">
# of Shuffles: {{ shuffleCount }}
</div>
</transition>
</div>
<transition-group :name="shuffleSpeed" tag="div" class="deck">
<div v-for="card in cards" :key="card.id"
class="card"
:class="{ 'black': card.suit === '♠' || card.suit === '♣',
'red': card.suit === '♥' || card.suit === '♦' }">
<span class="card__suit card__suit--top">{{ card.suit}}</span>
<span class="card__number">{{ card.name}} </span>
<span class="card__suit card__suit--bottom">{{ card.suit}}</span>
</div>
</transition-group>
<a href="https://twitter.com/djirdehh" target="_blank" class="twitter-section">
<i class="fab fa-twitter-square"></i>
<a>
</div>
Css
@import url('https://fonts.googleapis.com/css?family=Roboto+Slab:300,400,700');
$large: 1210px;
$medium: 768px;
html, body, #app {
height: 100%;
background: ghostwhite;
}
.title-section {
font-family: Roboto Slab, sans-serif;
text-align: center;
margin-top: 30px;
}
.title-section .title {
font-weight: 300;
font-size: 3rem;
}
.title-section .vue {
height: 55px;
position: relative;
top: 10px;
}
.speed-buttons {
padding-bottom: 30px;
.button {
height: 2.50em;
}
}
.main-buttons {
display: block;
margin: 0 auto;
padding-bottom: 30px;
text-align: center;
margin-bottom: 0 !important;
}
.count-section {
position: absolute;
top: 10px;
right: 10px;
}
.deck {
margin-left: 30px;
}
.card {
width: 75px;
height: 100px;
float: left;
margin-right: 5px;
margin-bottom: 5px;
border-radius: 2px;
}
.card__suit {
width: 100%;
display: block;
}
.card__suit--top {
text-align: left;
padding-left: 5px;
}
.card__suit--bottom {
position: absolute;
bottom: 0px;
text-align: left;
transform: rotate(180deg);
padding-left: 5px;
}
.card__number {
width: 100%;
position: absolute;
top: 38%;
text-align: center;
}
.red {
color: #FF0000;
}
.black {
color: #000;
}
.twitter-section {
position: absolute;
bottom: 10px;
right: 10px;
.fa-twitter-square {
color: #00d1b2;
font-size: 30px;
}
}
// Transitions
.shuffleSlow-move {
transition: transform 2s;
}
.shuffleMedium-move {
transition: transform 1s;
}
.shuffleFast-move {
transition: transform 0.5s;
}
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
// Media
@media(max-width: $large) {
.deck {
position: initial;
top: 0;
}
.twitter-section {
display: none;
}
}
JavaScript
new Vue({
el: '#app',
data: {
names: ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'],
suits: ['♥','♦','♠','♣'],
cards: [],
shuffleButtonActive: 1,
shuffleSpeed: 'shuffleMedium',
shuffleCount: 0,
shuffledDeck: false
},
created() {
this.displayInitialDeck();
},
methods: {
displayInitialDeck() {
let id = 1;
this.cards = [];
for( let s = 0; s < this.suits.length; s++ ) {
for( let n = 0; n < this.names.length; n++ ) {
let card = {
id: id,
value: n + 1,
name: this.names[n],
suit: this.suits[s]
}
this.cards.push(card);
id++;
}
}
this.shuffledDeck = false;
this.shuffleCount = 0;
return this.cards;
},
selectShuffleSpeed(n) {
this.shuffleButtonActive = n;
if (n === 0) this.shuffleSpeed = 'shuffleSlow';
if (n === 1) this.shuffleSpeed = 'shuffleMedium';
if (n === 2) this.shuffleSpeed = 'shuffleFast';
},
shuffleDeck() {
let counter = this.cards.length;
while (counter > 0) {
let randomIndex = Math.floor(Math.random() * counter);
counter--;
let temp = this.cards[counter];
Vue.set(this.cards, counter, this.cards[randomIndex]);
Vue.set(this.cards, randomIndex, temp);
}
this.shuffledDeck = true;
this.shuffleCount++;
}
}
})
Author
Hassan Dj
Demo
See the Pen Vue Transitions - Shuffle Deck of Cards by Hassan Dj (@itslit) on CodePen.