townsquare/src/components/Vote.vue

224 lines
5.6 KiB
Vue
Raw Normal View History

2020-05-31 21:42:08 +00:00
<template>
2020-06-03 20:25:23 +00:00
<div id="vote">
2020-05-31 21:42:08 +00:00
<div class="arrows">
2020-06-01 10:59:39 +00:00
<span class="nominee" :style="nomineeStyle"></span>
<span class="nominator" :style="nominatorStyle"></span>
2020-05-31 21:42:08 +00:00
</div>
<div class="overlay">
2020-06-01 10:59:39 +00:00
<em class="blue">{{ nominator.name }}</em> nominated
<em>{{ nominee.name }}</em
2020-05-31 21:42:08 +00:00
>!
<br />
<template v-if="nominee.role.team !== 'traveler'">
2020-06-03 20:25:23 +00:00
<em class="blue">{{ Math.ceil(alive / 2) }} votes</em> required to
<em>execute</em>.
2020-05-31 21:42:08 +00:00
</template>
<template v-else>
2020-06-03 20:25:23 +00:00
<em>{{ Math.ceil(players.length / 2) }} votes</em> required to
<em>exile</em>.
2020-05-31 21:42:08 +00:00
</template>
2020-06-03 20:25:23 +00:00
<div class="button-group" v-if="!session.isSpectator">
2020-06-03 21:04:50 +00:00
<div class="button" v-if="!session.lockedVote" @click="start">
Start Vote
</div>
<div class="button" v-else @click="stop">
Reset Vote
</div>
<div class="button" @click="finish">Finish</div>
2020-05-31 21:42:08 +00:00
</div>
2020-06-03 20:25:23 +00:00
<div
class="button-group"
v-else-if="
player && (!player.isVoteless || nominee.role.team === 'traveler')
"
>
<div class="button vote-no" @click="vote(false)">Vote NO</div>
<div class="button vote-yes" @click="vote(true)">Vote YES</div>
</div>
<div v-else-if="!player">
Please claim a seat to vote.
</div>
2020-05-31 21:42:08 +00:00
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from "vuex";
export default {
computed: {
nominator: function() {
return this.$store.state.players.players[
this.$store.state.session.nomination[0]
];
},
2020-06-01 10:59:39 +00:00
nominatorStyle: function() {
const players = this.$store.state.players.players.length;
const nomination = this.$store.state.session.nomination[0];
return {
transform: `rotate(${Math.round((nomination / players) * 360)}deg)`
};
},
2020-05-31 21:42:08 +00:00
nominee: function() {
return this.$store.state.players.players[
this.$store.state.session.nomination[1]
];
},
2020-06-01 10:59:39 +00:00
nomineeStyle: function() {
const players = this.$store.state.players.players.length;
const nomination = this.$store.state.session.nomination[1];
2020-06-03 21:04:50 +00:00
const lock = this.$store.state.session.lockedVote;
const rotation = (360 * (nomination + Math.min(lock, players))) / players;
2020-06-01 10:59:39 +00:00
return {
2020-06-03 21:04:50 +00:00
transform: `rotate(${Math.round(rotation)}deg)`
2020-06-01 10:59:39 +00:00
};
},
2020-06-03 20:25:23 +00:00
player: function() {
const id = this.$store.state.session.playerId;
return this.$store.state.players.players.find(p => p.id === id);
},
2020-05-31 21:42:08 +00:00
...mapState("players", ["players"]),
...mapState(["session"]),
...mapGetters({ alive: "players/alive" })
},
methods: {
2020-06-03 21:04:50 +00:00
start() {
this.$store.commit("session/lockVote");
this.voteTimer = setInterval(() => {
this.$store.commit("session/lockVote");
if (this.session.lockedVote > this.players.length) {
clearInterval(this.voteTimer);
}
}, 3000);
},
stop() {
this.$store.commit("session/lockVote", 0);
clearInterval(this.voteTimer);
},
2020-05-31 21:42:08 +00:00
finish() {
this.$store.commit("session/nomination", false);
2020-06-03 20:25:23 +00:00
},
vote(vote) {
const index = this.players.findIndex(p => p.id === this.session.playerId);
if (index >= 0 && !!this.session.votes[index] !== vote) {
this.$store.commit("session/vote", [index, vote]);
}
2020-05-31 21:42:08 +00:00
}
}
};
</script>
<style lang="scss" scoped>
@import "../vars.scss";
2020-06-03 20:25:23 +00:00
#vote {
2020-05-31 21:42:08 +00:00
position: absolute;
2020-06-01 10:59:39 +00:00
width: 20%;
2020-05-31 21:42:08 +00:00
z-index: 20;
display: flex;
align-items: center;
align-content: center;
justify-content: center;
background: url("../assets/demon-head.png") center center no-repeat;
2020-06-01 10:59:39 +00:00
background-size: auto 75%;
2020-05-31 21:42:08 +00:00
text-align: center;
text-shadow: 0 1px 2px #000000, 0 -1px 2px #000000, 1px 0 2px #000000,
-1px 0 2px #000000;
2020-06-01 10:59:39 +00:00
&:after {
content: " ";
padding-bottom: 100%;
display: block;
}
2020-05-31 21:42:08 +00:00
em {
2020-06-01 10:59:39 +00:00
color: $demon;
2020-05-31 21:42:08 +00:00
font-style: normal;
font-weight: bold;
2020-06-01 10:59:39 +00:00
&.blue {
color: $townsfolk;
}
}
}
@keyframes arrow-cw {
0% {
opacity: 0;
transform: rotate(-180deg);
}
100% {
opacity: 1;
transform: rotate(0deg);
}
}
@keyframes arrow-ccw {
0% {
opacity: 0;
transform: rotate(180deg);
}
100% {
opacity: 1;
transform: rotate(0deg);
}
}
.arrows {
position: absolute;
display: flex;
height: 150%;
width: 20%;
span {
position: absolute;
width: 100%;
height: 100%;
2020-06-03 21:04:50 +00:00
transition: transform 3s;
2020-06-01 10:59:39 +00:00
}
span:before {
content: " ";
width: 100%;
height: 100%;
display: block;
background-size: auto 100%;
background-repeat: no-repeat;
background-position: center center;
position: absolute;
filter: drop-shadow(0px 0px 3px #000);
}
.nominator:before {
background-image: url("../assets/clock-small.png");
animation: arrow-ccw 1s ease-out;
}
.nominee:before {
background-image: url("../assets/clock-big.png");
animation: arrow-cw 1s ease-out;
2020-05-31 21:42:08 +00:00
}
}
2020-06-03 20:25:23 +00:00
.button.vote-no {
background: radial-gradient(
at 0 -15%,
rgba(255, 255, 255, 0.07) 70%,
rgba(255, 255, 255, 0) 71%
)
0 0/80% 90% no-repeat content-box,
linear-gradient(#0031ad, rgba(5, 0, 0, 0.22)) content-box,
linear-gradient(#292929, #001142) border-box;
box-shadow: inset 0 1px 1px #002c9c, 0 0 10px #000;
&:hover {
color: #008cf7;
}
}
.button.vote-yes {
background: radial-gradient(
at 0 -15%,
rgba(255, 255, 255, 0.07) 70%,
rgba(255, 255, 255, 0) 71%
)
0 0/80% 90% no-repeat content-box,
linear-gradient(#ad0000, rgba(5, 0, 0, 0.22)) content-box,
linear-gradient(#292929, #420000) border-box;
box-shadow: inset 0 1px 1px #9c0000, 0 0 10px #000;
}
2020-05-31 21:42:08 +00:00
</style>