242 lines
6.1 KiB
Vue
242 lines
6.1 KiB
Vue
<template>
|
|
<div class="timer">
|
|
<div class="end" v-on:click="resetTime()">X</div>
|
|
<div class="timer-container">
|
|
<div class="timer-column no-mobile">
|
|
<div class="timer-item">
|
|
|
|
</div>
|
|
<div class="timer-item rotate-left">
|
|
<p v-if="warning == false" v-bind:class="{ danger: danger == true }" class="timeleft">{{ countDown.toString() }}</p>
|
|
<p v-if="(warning == true) || (typeof warning == 'undefined')" class="timeout">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
</p>
|
|
</div>
|
|
<div class="timer-item">
|
|
|
|
</div>
|
|
</div>
|
|
<div class="timer-column mobile">
|
|
<div class="timer-item reverse">
|
|
<p v-if="warning == false" v-bind:class="{ danger: danger == true }" class="timeleft">{{ countDown.toString() }}</p>
|
|
<p v-if="(warning == true) || (typeof warning == 'undefined')" class="timeout">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
</p>
|
|
</div>
|
|
<button v-on:click="restartTimer()" v-on:keyup.space="restartTimer" v-on:keyup.enter="restartTimer" ref="timerBtn" class="timerBtn"><span class="timerBtn-inner"></span></button>
|
|
<div class="timer-item">
|
|
<p v-if="warning == false" v-bind:class="{ danger: danger == true }" class="timeleft">{{ countDown.toString() }}</p>
|
|
<p v-if="warning == true || (typeof warning == 'undefined')" class="timeout">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="timer-column no-mobile">
|
|
<div class="timer-item">
|
|
|
|
</div>
|
|
<div class="timer-item rotate-right">
|
|
<p v-if="warning == false" v-bind:class="{ danger: danger == true }" class="timeleft">{{ countDown.toString() }}</p>
|
|
<p v-if="(warning == true) || (typeof warning == 'undefined')" class="timeout">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
<img src="joker.png" alt="joker">
|
|
</p>
|
|
</div>
|
|
<div class="timer-item">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "Timer",
|
|
props: {
|
|
time: Number,
|
|
playsound: Boolean,
|
|
},
|
|
data: function() {
|
|
return {
|
|
countDown: -2,
|
|
warning: true,
|
|
danger: false,
|
|
wakeLock: null,
|
|
interval: null,
|
|
sfxTimeout: this.playsound ? new Audio('sfx/timeout.wav') : null,
|
|
sfxWarning: this.playsound ? new Audio('sfx/warning.wav') : null,
|
|
sfxNext: this.playsound ? new Audio('sfx/next.wav') : null,
|
|
}
|
|
},
|
|
mounted: function() {
|
|
this.$refs['timerBtn'].focus();
|
|
},
|
|
methods: {
|
|
resetTime: function() {
|
|
clearInterval(this.interval);
|
|
this.$emit('set-time', 0);
|
|
},
|
|
timeleft: function(){
|
|
this.countDown--;
|
|
switch (this.countDown) {
|
|
case 5:
|
|
if(this.playsound) {
|
|
this.sfxWarning.play();
|
|
}
|
|
this.danger = true;
|
|
break;
|
|
case 4:
|
|
if(this.playsound) {
|
|
this.sfxWarning.play();
|
|
}
|
|
break;
|
|
case 3:
|
|
if(this.playsound) {
|
|
this.sfxWarning.play();
|
|
}
|
|
break;
|
|
case 2:
|
|
if(this.playsound) {
|
|
this.sfxWarning.play();
|
|
}
|
|
break;
|
|
case 1:
|
|
if(this.playsound) {
|
|
this.sfxWarning.play();
|
|
}
|
|
break;
|
|
case 0:
|
|
this.warning = true
|
|
|
|
if(this.playsound) {
|
|
this.sfxTimeout.play();
|
|
}
|
|
clearInterval(this.interval);
|
|
break;
|
|
}
|
|
this.$refs['timerBtn'].focus();
|
|
},
|
|
restartTimer: function() {
|
|
if(this.wakeLock == null && 'wakeLock' in navigator) {
|
|
this.wakeLock = navigator.wakeLock.request('screen');
|
|
}
|
|
if(this.playsound) {
|
|
this.sfxNext.play();
|
|
}
|
|
this.countDown = this.time;
|
|
this.warning = false;
|
|
this.danger = false;
|
|
clearInterval(this.interval);
|
|
this.interval = setInterval(() => {
|
|
this.timeleft()
|
|
}, 1000);
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.timer {
|
|
height: 100%;
|
|
}
|
|
.timer-container {
|
|
display: flex;
|
|
height: 100%;
|
|
|
|
.timer-column {
|
|
height: 100%;
|
|
width: 100%;
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
&.mobile {
|
|
display: flex;
|
|
}
|
|
.timer-item {
|
|
&.reverse {
|
|
transform: rotate(180deg);
|
|
}
|
|
&.rotate-left {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
&.rotate-right {
|
|
transform: rotate(-90deg);
|
|
}
|
|
&.empty {
|
|
height: 33%;
|
|
}
|
|
}
|
|
@media (min-width: 768px) {
|
|
&.no-mobile {
|
|
display: flex;
|
|
}
|
|
}
|
|
}
|
|
.timeleft {
|
|
font-size: 60px;
|
|
padding: 23px 20px 84px 20px;
|
|
margin: 10px 0;
|
|
color: $black;
|
|
background-image: url("~@/img/tile-back.svg");
|
|
background-size: cover;
|
|
text-align: center;
|
|
width: 80px;
|
|
height: 60px;
|
|
|
|
&.danger {
|
|
color: $red;
|
|
}
|
|
}
|
|
|
|
.timeout {
|
|
margin: 40px;
|
|
|
|
img {
|
|
height: 3rem;
|
|
}
|
|
}
|
|
|
|
.timerBtn {
|
|
appearance: none;
|
|
border: 1px solid $white;
|
|
border-radius: 3px;
|
|
font-size: 3rem;
|
|
background: none;
|
|
padding: 2rem;
|
|
|
|
.timerBtn-inner {
|
|
display: inline-block;
|
|
height: 2rem;
|
|
width: 8rem;
|
|
background-color: $white;
|
|
}
|
|
}
|
|
}
|
|
.end {
|
|
display: block;
|
|
position: absolute;
|
|
right: 1px;
|
|
top: 1px;
|
|
font-size: 32px;
|
|
}
|
|
|
|
</style> |