Vue Sorteio Livro
by Plínio Naves
HTML
<script src="https://unpkg.com/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<div id="app">
<div class="container">
<button class="btn btn-primary mt-3 mb-3" @click="sortear">Sortear</button>
<template v-if="!terminou">
<div class="alert alert-info">
<h1>
<span class="font-weight-light">Número: </span>
<strong>{{ numeroSorteado }}</strong>
</h1>
</div>
<div class="progress">
<div
:style="{ width: (progresso + '%') }"
class="progress-bar bg-info"
role="progressbar"
:aria-valuenow="progresso"
aria-valuemin="0"
aria-valuemax="100">
{{ progresso }}%
</div>
</div>
<p>Rodadas restantes: {{ ponteiro }}</p>
</template>
<div class="alert alert-success" v-else>
<h1>
<span class="font-weight-light">Vencedor: </span>
<strong>{{ numeroSorteado }}</strong>
</h1>
</div>
</div>
</div>
JavaScript
new Vue({
el: '#app',
data: {
numero: 0,
numeroInterpolado: 0,
ponteiro: 0,
rodadas: 0,
terminou: false
},
computed: {
numeroSorteado() {
return this.numeroInterpolado.toFixed(0)
},
progresso() {
return 100 - (this.ponteiro / this.rodadas * 100).toFixed(0) || 0
}
},
methods: {
sortear() {
this.rodadas = this.sortearNumerosInclusive(15, 25)
this.ponteiro = this.rodadas
this.terminou = false
const loop = setInterval(() => {
this.numero = this.sortearNumerosInclusive(1, 23)
this.ponteiro--
if (this.ponteiro <= 0) {
clearInterval(loop)
setTimeout(() => this.terminou = true, 1000)
}
}, 1000)
},
sortearNumerosInclusive(min, max) {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}
},
watch: {
numero(novoNumero) {
TweenLite.to(this.$data, 1, { ease: Power0.easeNone, numeroInterpolado: novoNumero })
}
}
})