refactoring/cleanup / beta
This commit is contained in:
91
index.html
91
index.html
@@ -11,7 +11,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<table class="main invisible" id="main">
|
<table class="invisible" id="main">
|
||||||
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -21,44 +21,44 @@
|
|||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="player">
|
<td class="player" id="player1">
|
||||||
<table class="player">
|
<table>
|
||||||
<tr class="player-name active">
|
<tr>
|
||||||
<td id="player1-name">Player 1</td>
|
<td class="player-name active">Player 1</td>
|
||||||
</tr>
|
|
||||||
<tr class="player-score">
|
|
||||||
<td class="player-score" id="player-score-1">0</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="player-extension">Extension</td>
|
<td class="player-score" data-player="1">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="player-extension active">Extension</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
<td class="display">
|
<td class="display">
|
||||||
<table class="display">
|
<table>
|
||||||
<tr class="display-race">
|
<tr>
|
||||||
<td class="display-break active" id="display-break1"> </td>
|
<td class="display-break active" id="display-break-player1"> </td>
|
||||||
<td>Race to <span id="display-race">9</span></td>
|
<td>Race to <span class="display-race">9</span></td>
|
||||||
<td class="display-break" id="display-break2"> </td>
|
<td class="display-break" id="display-break-player2"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="display-time">
|
<tr>
|
||||||
<td colspan="3" id="display-time">30</td>
|
<td class="display-timer" colspan="3">30</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="display-bar">
|
<tr>
|
||||||
<td colspan="3" id="display-bar"> </td>
|
<td class="display-bar" colspan="3"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
<td class="player">
|
<td class="player" id="player2">
|
||||||
<table class="player">
|
<table>
|
||||||
<tr class="player-name">
|
<tr>
|
||||||
<td id="player2-name">Player 2</td>
|
<td class="player-name">Player 2</td>
|
||||||
</tr>
|
|
||||||
<tr class="player-score">
|
|
||||||
<td class="player-score" id="player-score-2">0</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="player-extension">Extension</td>
|
<td class="player-score" data-player="2">0</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="player-extension active">Extension</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
@@ -84,25 +84,29 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="settings-inputs">
|
<tr>
|
||||||
<td><label for="settings-time">Time</label></td>
|
<td><label for="settings-time">Time</label></td>
|
||||||
<td><input id="settings-time" type="number"></td>
|
<td><input id="settings-time" type="number"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="settings-inputs">
|
<tr>
|
||||||
<td><label for="settings-race">Race to</label></td>
|
<td><label for="settings-race">Race to</label></td>
|
||||||
<td><input id="settings-race" type="number"></td>
|
<td><input id="settings-race" type="number"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="settings-inputs">
|
<tr>
|
||||||
<td><label for="settings-alternate">Alternate break</label></td>
|
<td><label for="settings-alternate">Alternate break</label></td>
|
||||||
<td><input id="settings-alternate" type="checkbox"></td>
|
<td><input id="settings-alternate" type="checkbox"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="settings-inputs">
|
<tr>
|
||||||
<td><label for="settings-reset">Reset</label></td>
|
<td><label for="settings-reset">Reset Game</label></td>
|
||||||
<td><button id="settings-reset"><i class="fa-solid fa-clock-rotate-left"></i></button></td>
|
<td>
|
||||||
|
<button id="settings-reset"><i class="fa-solid fa-clock-rotate-left"></i></button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="settings-fullscreen">
|
<tr>
|
||||||
<td><label for="settings-fullscreen">Recover Fullscreen</label></td>
|
<td><label for="settings-fullscreen">Recover Fullscreen</label></td>
|
||||||
<td><button id="settings-fullscreen"><i class="fa-solid fa-up-right-and-down-left-from-center"></i></button></td>
|
<td>
|
||||||
|
<button id="settings-fullscreen"><i class="fa-solid fa-up-right-and-down-left-from-center"></i></button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
@@ -125,23 +129,20 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="welcome-text">
|
|
||||||
<td>
|
|
||||||
<h4>Todo:</h4>
|
|
||||||
<ul>
|
|
||||||
<li>Play pool.</li>
|
|
||||||
<li>Have fun.</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td id="welcome-confirm"><img src="12ball.png"></td>
|
<td class="welcome-text">
|
||||||
|
<h4>Todo:</h4>
|
||||||
|
<p>
|
||||||
|
Play pool. Have fun. Keep an eye on the clock.<br>
|
||||||
|
<img id="welcome-confirm" src="12ball.png">
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr class="controls">
|
<tr class="controls">
|
||||||
<td> </td>
|
<td id="welcome-play"><i class="fa-solid fa-play"></i></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|
||||||
|
|||||||
100
shotclock.css
100
shotclock.css
@@ -1,3 +1,4 @@
|
|||||||
|
/* generics */
|
||||||
body {
|
body {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
color: #f12f12;
|
color: #f12f12;
|
||||||
@@ -34,68 +35,67 @@ td {
|
|||||||
vertical-align: center;
|
vertical-align: center;
|
||||||
font-size: 5vh;
|
font-size: 5vh;
|
||||||
}
|
}
|
||||||
ul li {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr.player-score {
|
/* player */
|
||||||
height: 50%;
|
.player-name {
|
||||||
|
border: 1vh solid transparent;
|
||||||
}
|
}
|
||||||
td.player-score {
|
.player-name.active {
|
||||||
|
border: 1vh solid #f12f12;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
.player-score {
|
||||||
|
height: 50%;
|
||||||
font-size: 30vh;
|
font-size: 30vh;
|
||||||
font-family: 'Seven segment', sans-serif;
|
font-family: 'Seven segment', sans-serif;
|
||||||
}
|
}
|
||||||
td.player-extension {
|
.player-extension {
|
||||||
background-color: #00f120;
|
|
||||||
border-radius: 25px;
|
|
||||||
}
|
|
||||||
td.player-extension.inactive {
|
|
||||||
background-color: #f12f12;
|
background-color: #f12f12;
|
||||||
color: grey;
|
color: grey;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
.player-extension.active {
|
||||||
|
background-color: #00f120;
|
||||||
|
color: #f12f12;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.display {
|
/* display */
|
||||||
|
.display {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
tr.display-time {
|
|
||||||
height: 80%;
|
|
||||||
}
|
|
||||||
#display-time {
|
|
||||||
font-size: 50vh;
|
|
||||||
font-family: 'Seven segment', sans-serif;
|
|
||||||
}
|
|
||||||
#display-bar {
|
|
||||||
border-radius: 25px;
|
|
||||||
background: linear-gradient(90deg, rgba(0,0,0,1) -200%, rgba(255,0,0,1) -200%, rgba(0,241,32,1) 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
height: 20%;
|
|
||||||
}
|
|
||||||
.controls td {
|
|
||||||
padding: 2vh;
|
|
||||||
font-size: 20vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invisible {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.settings-inputs td {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
#welcome-confirm img {
|
|
||||||
height: 30vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.player-name td {
|
|
||||||
border: 1vh solid transparent;
|
|
||||||
}
|
|
||||||
.player-name.active td{
|
|
||||||
border: 1vh solid #f12f12;
|
|
||||||
border-radius: 25px;
|
|
||||||
}
|
|
||||||
.display-break.active{
|
.display-break.active{
|
||||||
background-image: url("12ball.png");
|
background-image: url("12ball.png");
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
.display-timer {
|
||||||
|
height: 80%;
|
||||||
|
font-size: 50vh;
|
||||||
|
font-family: 'Seven segment', sans-serif;
|
||||||
|
}
|
||||||
|
.display-bar {
|
||||||
|
border-radius: 25px;
|
||||||
|
background: linear-gradient(90deg, rgba(0,0,0,1) -200%, rgba(255,0,0,1) -200%, rgba(0,241,32,1) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* controls */
|
||||||
|
.controls td {
|
||||||
|
padding: 2vh;
|
||||||
|
font-size: 20vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* modal welcome */
|
||||||
|
#welcome-confirm {
|
||||||
|
height: 10vh;
|
||||||
|
margin: 5vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.settings-inputs td {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* helpers */
|
||||||
|
.invisible {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|||||||
571
shotclock.js
571
shotclock.js
@@ -1,21 +1,281 @@
|
|||||||
let startTime = 30;
|
let interval = 0;
|
||||||
let timer = 30;
|
let resetTime = 30;
|
||||||
let race = 9;
|
let timer = resetTime * 2;
|
||||||
let breakPlayer = 1;
|
let race = 7;
|
||||||
let alternateBreak = false;
|
let alternateBreak = false;
|
||||||
let cookies;
|
let player1 = 'Player 1';
|
||||||
var audioCtx;
|
let player2 = 'Player 2';
|
||||||
let interval;
|
let activePlayer = 1;
|
||||||
|
let breakedPlayer = 1;
|
||||||
|
let element;
|
||||||
|
|
||||||
|
document.body.oncontextmenu = function () {
|
||||||
|
return false;
|
||||||
|
}; // i know this is useless. it was just distracting me ;)
|
||||||
|
|
||||||
|
/* get data from cookie if possible */
|
||||||
|
if (document.cookie.length) {
|
||||||
|
var cookies = document.cookie.split('; ').reduce((prev, current) => {
|
||||||
|
const [name, ...value] = current.split('=');
|
||||||
|
prev[name] = value.join('=');
|
||||||
|
return prev;
|
||||||
|
}, {});
|
||||||
|
resetTime = cookies.resetTime ?? resetTime;
|
||||||
|
timer = resetTime * 2;
|
||||||
|
updateDisplay();
|
||||||
|
race = cookies.race ?? race;
|
||||||
|
document.querySelector('.display-race').innerText = race;
|
||||||
|
player1 = cookies.player1 ?? player1;
|
||||||
|
document.querySelector('#player1 .player-name').innerText = player1;
|
||||||
|
player2 = cookies.player2 ?? player2;
|
||||||
|
document.querySelector('#player2 .player-name').innerText = player2;
|
||||||
|
alternateBreak = cookies.alternateBreak ? (cookies.alternateBreak == 'true') : alternateBreak;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('welcome-confirm').addEventListener('click', toggleWelcome);
|
||||||
|
document.getElementById('welcome-play').addEventListener('click', toggleWelcome);
|
||||||
|
|
||||||
|
// Player
|
||||||
|
function setPlayername() {
|
||||||
|
var name = prompt('Enter name:', this.innerText);
|
||||||
|
if (name) {
|
||||||
|
this.innerText = name;
|
||||||
|
}
|
||||||
|
player1 = document.querySelector('#player1 .player-name').innerText;
|
||||||
|
document.cookie = "player1=" + player1;
|
||||||
|
player2 = document.querySelector('#player2 .player-name').innerText;
|
||||||
|
document.cookie = "player2=" + player2;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.player-name').forEach(element => element.addEventListener('click', setPlayername));
|
||||||
|
|
||||||
|
function toggleActivePlayer() {
|
||||||
|
document.querySelector('#player' + activePlayer + ' .player-name').classList.remove('active');
|
||||||
|
activePlayer = activePlayer == 1 ? 2 : 1;
|
||||||
|
document.querySelector('#player' + activePlayer + ' .player-name').classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.player-name').forEach(function (element) {
|
||||||
|
onLongPress(element, toggleActivePlayer);
|
||||||
|
});
|
||||||
|
|
||||||
|
function increasePlayerScore() {
|
||||||
|
if (interval) {
|
||||||
|
toggleTimer();
|
||||||
|
}
|
||||||
|
timer = resetTime * 2;
|
||||||
|
updateDisplay();
|
||||||
|
|
||||||
|
this.innerText = Number.parseInt(this.innerText) + 1;
|
||||||
|
if (alternateBreak) {
|
||||||
|
breakedPlayer = breakedPlayer == 1 ? 2 : 1;
|
||||||
|
} else {
|
||||||
|
breakedPlayer = this.dataset.player;
|
||||||
|
}
|
||||||
|
if (activePlayer != breakedPlayer) {
|
||||||
|
toggleActivePlayer();
|
||||||
|
}
|
||||||
|
document.querySelector('.display-break.active').classList.remove('active');
|
||||||
|
document.getElementById("display-break-player" + breakedPlayer).classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('td.player-score').forEach(element => element.addEventListener('click', increasePlayerScore));
|
||||||
|
|
||||||
|
function setPlayerScore(element) {
|
||||||
|
var score = prompt('Enter current score:', element.innerText)
|
||||||
|
element.innerText = score ? score : element.innerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.player-score').forEach(function (element) {
|
||||||
|
onLongPress(element, () => setPlayerScore(element));
|
||||||
|
});
|
||||||
|
|
||||||
|
function playerExtension() {
|
||||||
|
timer += resetTime;
|
||||||
|
updateDisplay();
|
||||||
|
this.classList.remove('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.player-extension').forEach(element => element.addEventListener('click', playerExtension));
|
||||||
|
document.querySelectorAll('.player-extension').forEach(function (element) {
|
||||||
|
onLongPress(element, () => element.classList.toggle('active'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display
|
||||||
|
function toggleBreakedPlayer() {
|
||||||
|
document.querySelectorAll('.display-break').forEach(element => element.classList.toggle('active'));
|
||||||
|
breakedPlayer = breakedPlayer == 1 ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.display-break').forEach(function (element) {
|
||||||
|
onLongPress(element, () => toggleBreakedPlayer());
|
||||||
|
});
|
||||||
|
|
||||||
|
function resetTimer() {
|
||||||
|
timer = resetTime;
|
||||||
|
updateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelector('.display-timer').addEventListener('click', resetTimer);
|
||||||
|
|
||||||
|
function setTimer(element) {
|
||||||
|
if (interval) {
|
||||||
|
toggleTimer();
|
||||||
|
}
|
||||||
|
var newTimer = prompt('Enter current time:', element.innerText);
|
||||||
|
element.innerText = newTimer ? newTimer : element.innerText;
|
||||||
|
timer = newTimer ? Number.parseInt(newTimer) : timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
element = document.querySelector('.display-timer');
|
||||||
|
onLongPress(element, () => setTimer(element));
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
function toggleTimer() {
|
||||||
|
if (timer == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!interval) {
|
||||||
|
interval = setInterval(runTimer, 1000);
|
||||||
|
runTimer();
|
||||||
|
} else {
|
||||||
|
clearInterval(interval);
|
||||||
|
interval = null;
|
||||||
|
}
|
||||||
|
document.querySelector('#controls-play i').classList.toggle('fa-play');
|
||||||
|
document.querySelector('#controls-play i').classList.toggle('fa-pause');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('controls-play').addEventListener('click', toggleTimer);
|
||||||
|
|
||||||
|
function switchPlayer() {
|
||||||
|
resetTimer();
|
||||||
|
toggleActivePlayer();
|
||||||
|
if (!interval) {
|
||||||
|
toggleTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('controls-switch').addEventListener('click', switchPlayer);
|
||||||
|
element = document.getElementById('controls-switch');
|
||||||
|
onLongPress(element, () => {
|
||||||
|
switchPlayer();
|
||||||
|
timer = resetTime * 2;
|
||||||
|
updateDisplay();
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleSettings() {
|
||||||
|
document.getElementById('main').classList.toggle('invisible');
|
||||||
|
document.getElementById('settings').classList.toggle('invisible');
|
||||||
|
document.getElementById('settings-time').value = resetTime;
|
||||||
|
document.getElementById('settings-race').value = race;
|
||||||
|
document.getElementById('settings-alternate').checked = alternateBreak;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('controls-settings').addEventListener('click', toggleSettings);
|
||||||
|
|
||||||
|
// Modals
|
||||||
|
// Welcome screen
|
||||||
|
function toggleWelcome() {
|
||||||
|
document.getElementById('main').classList.toggle('invisible');
|
||||||
|
document.getElementById('welcome').classList.toggle('invisible');
|
||||||
|
document.body.requestFullscreen();
|
||||||
|
screen.orientation.lock('landscape');
|
||||||
|
}
|
||||||
|
|
||||||
|
// settings
|
||||||
|
function resetGame() {
|
||||||
|
document.querySelectorAll('.player-score').forEach(element => element.innerText = 0);
|
||||||
|
if (activePlayer == 2) {
|
||||||
|
toggleActivePlayer();
|
||||||
|
}
|
||||||
|
if (breakedPlayer == 2) {
|
||||||
|
toggleBreakedPlayer();
|
||||||
|
}
|
||||||
|
if (interval) {
|
||||||
|
toggleTimer();
|
||||||
|
}
|
||||||
|
timer = resetTime * 2;
|
||||||
|
updateDisplay();
|
||||||
|
document.querySelectorAll('.player-extension').forEach(element => element.classList.add('active'));
|
||||||
|
document.body.requestFullscreen();
|
||||||
|
screen.orientation.lock('landscape');
|
||||||
|
toggleSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('settings-reset').addEventListener('click', resetGame);
|
||||||
|
|
||||||
|
function setFullscreen() {
|
||||||
|
document.body.requestFullscreen();
|
||||||
|
screen.orientation.lock('landscape');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('settings-fullscreen').addEventListener('click', setFullscreen);
|
||||||
|
|
||||||
|
document.getElementById('settings-cancel').addEventListener('click', toggleSettings);
|
||||||
|
|
||||||
|
function saveSettings() {
|
||||||
|
var inputtime = document.getElementById('settings-time').value;
|
||||||
|
if (isNaN(inputtime) || inputtime <= 0) {
|
||||||
|
alert("Must input numbers > 0");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
resetTime = Math.floor(inputtime)
|
||||||
|
document.cookie = "resetTime=" + resetTime;
|
||||||
|
resetTimer();
|
||||||
|
var newRace = document.getElementById('settings-race').value;
|
||||||
|
race = newRace ? newRace : race;
|
||||||
|
document.cookie = "race=" + race;
|
||||||
|
document.querySelector('.display-race').innerText = race;
|
||||||
|
alternateBreak = document.getElementById('settings-alternate').checked;
|
||||||
|
document.cookie = "alternateBreak=" + alternateBreak;
|
||||||
|
toggleSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('settings-save').addEventListener('click', saveSettings);
|
||||||
|
|
||||||
|
// update timer + bar concurrently
|
||||||
|
function updateDisplay() {
|
||||||
|
document.querySelector('.display-timer').innerText = timer;
|
||||||
|
document.querySelector('.display-bar').style.background = "linear-gradient(90deg, rgba(0,0,0,1) -200%, rgba(255,0,0,1) " + (Math.ceil(100 - (timer / resetTime) * 300)) + "%, rgba(0,241,32,1) 100%)";
|
||||||
|
}
|
||||||
|
function runTimer() {
|
||||||
|
if (timer < 0) {
|
||||||
|
toggleTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateDisplay();
|
||||||
|
timer--;
|
||||||
|
|
||||||
|
if (timer < 0) {
|
||||||
|
beep(1000, 1212);
|
||||||
|
toggleTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer < 5) {
|
||||||
|
beep(100, 606);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
const parseCookie = str =>
|
function onLongPress(element, callback) {
|
||||||
str
|
let timer;
|
||||||
.split(';')
|
|
||||||
.map(v => v.split('='))
|
element.addEventListener('touchstart', () => {
|
||||||
.reduce((acc, v) => {
|
timer = setTimeout(() => {
|
||||||
acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
|
timer = null;
|
||||||
return acc;
|
callback();
|
||||||
}, {});
|
}, 500);
|
||||||
|
});
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
element.addEventListener('touchend', cancel);
|
||||||
|
element.addEventListener('touchmove', cancel);
|
||||||
|
}
|
||||||
|
|
||||||
//duration of the tone in milliseconds. Default is 500
|
//duration of the tone in milliseconds. Default is 500
|
||||||
//frequency of the tone in hertz. default is 440
|
//frequency of the tone in hertz. default is 440
|
||||||
@@ -49,284 +309,3 @@ function beep(duration, frequency, volume, type, callback) {
|
|||||||
oscillator.stop(audioCtx.currentTime + ((duration || 500) / 1000));
|
oscillator.stop(audioCtx.currentTime + ((duration || 500) / 1000));
|
||||||
};
|
};
|
||||||
|
|
||||||
function onLongPress(element, callback) {
|
|
||||||
let timer;
|
|
||||||
|
|
||||||
element.addEventListener('touchstart', () => {
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
timer = null;
|
|
||||||
callback();
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
|
|
||||||
function cancel() {
|
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
element.addEventListener('touchend', cancel);
|
|
||||||
element.addEventListener('touchmove', cancel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init
|
|
||||||
document.body.oncontextmenu = function () {
|
|
||||||
return false;
|
|
||||||
}; // i know this is useless. it was just distracting me ;)
|
|
||||||
|
|
||||||
if (document.cookie.length > 0) {
|
|
||||||
cookies = parseCookie(document.cookie);
|
|
||||||
startTime = cookies['time'];
|
|
||||||
updateTimer(cookies['time']);
|
|
||||||
updateRace(cookies['race']);
|
|
||||||
} else {
|
|
||||||
updateTimer(startTime);
|
|
||||||
updateRace(race);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Player
|
|
||||||
function setPlayername() {
|
|
||||||
var name = prompt('Enter name:', this.innerText)
|
|
||||||
this.innerText = name ? name : this.innerText;
|
|
||||||
document.body.requestFullscreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('.player-name td').forEach(element => element.addEventListener('click', setPlayername));
|
|
||||||
document.querySelectorAll('.player-name td').forEach(function (element) {
|
|
||||||
onLongPress(element, () => document.querySelectorAll('.player-name').forEach(element => element.classList.toggle('active')));
|
|
||||||
});
|
|
||||||
|
|
||||||
function playerScoreIncrease() {
|
|
||||||
if (interval) {
|
|
||||||
toggleTimer();
|
|
||||||
}
|
|
||||||
timer = startTime*2;
|
|
||||||
setTimer(timer);
|
|
||||||
this.innerText = Number.parseInt(this.innerText) + 1;
|
|
||||||
var wonPlayer = this.id == 'player-score-1' ? 1 : 2;
|
|
||||||
if (alternateBreak || wonPlayer != breakPlayer) {
|
|
||||||
toggleDisplayBreakActive();
|
|
||||||
document.querySelectorAll('.player-name').forEach(element => element.classList.toggle('active'));
|
|
||||||
breakPlayer = wonPlayer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('td.player-score').forEach(element => element.addEventListener('click', playerScoreIncrease));
|
|
||||||
|
|
||||||
function setPlayerScore(element) {
|
|
||||||
var score = prompt('Enter current score:', element.innerText)
|
|
||||||
element.innerText = score ? score : element.innerText;
|
|
||||||
document.body.requestFullscreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('td.player-score').forEach(function (element) {
|
|
||||||
onLongPress(element, () => setPlayerScore(element));
|
|
||||||
breakPlayer = breakPlayer == 1 ? 2 : 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
function playerExtension() {
|
|
||||||
timer = Number.parseInt(timer) + Number.parseInt(startTime);
|
|
||||||
setTimer(timer);
|
|
||||||
this.classList.add('inactive');
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('.player-extension').forEach(element => element.addEventListener('click', playerExtension));
|
|
||||||
document.querySelectorAll('.player-extension').forEach(function (element) {
|
|
||||||
onLongPress(element, () => element.classList.toggle('inactive'));
|
|
||||||
});
|
|
||||||
|
|
||||||
function toggleDisplayBreakActive() {
|
|
||||||
document.querySelectorAll('.display-break').forEach(element => element.classList.toggle('active'));
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('.display-break').forEach(function (element) {
|
|
||||||
onLongPress(element, () => toggleDisplayBreakActive());
|
|
||||||
});
|
|
||||||
|
|
||||||
function setTimerDisplay(element) {
|
|
||||||
console.log(element);
|
|
||||||
if (interval) {
|
|
||||||
toggleTimer();
|
|
||||||
}
|
|
||||||
var newTimer = prompt('Enter current time:', element.innerText)
|
|
||||||
element.innerText = newTimer ? newTimer : element.innerText;
|
|
||||||
timer = newTimer ? newTimer : timer;
|
|
||||||
}
|
|
||||||
var element = document.getElementById('display-time');
|
|
||||||
onLongPress(element, () => setTimerDisplay(element));
|
|
||||||
|
|
||||||
// settings
|
|
||||||
function reset() {
|
|
||||||
document.querySelectorAll('td.player-score').forEach(function (element) {
|
|
||||||
onLongPress(element, () => setPlayerScore(element));
|
|
||||||
breakPlayer = breakPlayer == 1 ? 2 : 1;
|
|
||||||
});
|
|
||||||
if (interval) {
|
|
||||||
toggleTimer();
|
|
||||||
}
|
|
||||||
resetTimer();
|
|
||||||
document.querySelectorAll('.player-score td').forEach(element => element.innerText = 0);
|
|
||||||
document.querySelectorAll('.player-extension').forEach(element => element.classList.remove('inactive'));
|
|
||||||
document.body.requestFullscreen();
|
|
||||||
screen.orientation.lock('landscape');
|
|
||||||
toggleSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('settings-reset').addEventListener('click', reset);
|
|
||||||
|
|
||||||
function setFullscreen() {
|
|
||||||
document.body.requestFullscreen();
|
|
||||||
screen.orientation.lock('landscape');
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('settings-fullscreen').addEventListener('click', setFullscreen);
|
|
||||||
|
|
||||||
function toggleSettings() {
|
|
||||||
document.getElementById('main').classList.toggle('invisible');
|
|
||||||
document.getElementById('settings').classList.toggle('invisible');
|
|
||||||
document.getElementById('settings-time').value = startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('controls-settings').addEventListener('click', toggleSettings);
|
|
||||||
document.getElementById('settings-cancel').addEventListener('click', toggleSettings);
|
|
||||||
|
|
||||||
function saveSettings() {
|
|
||||||
var inputtime = document.getElementById('settings-time').value;
|
|
||||||
if (isNaN(inputtime) || inputtime <= 0) {
|
|
||||||
alert("Must input numbers");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
startTime = Math.floor(inputtime)
|
|
||||||
document.cookie = "time=" + startTime;
|
|
||||||
updateTimer(startTime);
|
|
||||||
updateRace(document.getElementById('settings-race').value);
|
|
||||||
alternateBreak = document.getElementById('settings-alternate').checked;
|
|
||||||
toggleSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('settings-save').addEventListener('click', saveSettings);
|
|
||||||
|
|
||||||
function updateTimer(newTime) {
|
|
||||||
timer = startTime;
|
|
||||||
document.getElementById('display-time').innerText = newTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateRace(newRace) {
|
|
||||||
race = newRace;
|
|
||||||
document.getElementById('display-race').innerText = newRace;
|
|
||||||
document.getElementById('settings-race').value = newRace;
|
|
||||||
document.cookie = "race=" + newRace;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleWelcome() {
|
|
||||||
document.getElementById('main').classList.toggle('invisible');
|
|
||||||
document.getElementById('welcome').classList.toggle('invisible');
|
|
||||||
document.body.requestFullscreen();
|
|
||||||
screen.orientation.lock('landscape');
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('welcome-confirm').addEventListener('click', toggleWelcome);
|
|
||||||
|
|
||||||
function runTimer() {
|
|
||||||
if (timer < 0) {
|
|
||||||
toggleTimer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTimer(timer);
|
|
||||||
timer--;
|
|
||||||
|
|
||||||
if (timer < 0) {
|
|
||||||
|
|
||||||
beep(1000, 1212);
|
|
||||||
toggleTimer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timer < 5) {
|
|
||||||
beep(100, 606);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function setTimer(targetTime) {
|
|
||||||
document.getElementById('display-time').innerText = targetTime;
|
|
||||||
var timerPercentage = Math.ceil(100 - (targetTime / startTime) * 300);
|
|
||||||
document.getElementById('display-bar').style.background = "linear-gradient(90deg, rgba(0,0,0,1) -200%, rgba(255,0,0,1) " + timerPercentage + "%, rgba(0,241,32,1) 100%)";
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleTimer() {
|
|
||||||
if (timer == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!interval) {
|
|
||||||
interval = setInterval(runTimer, 1000);
|
|
||||||
runTimer();
|
|
||||||
} else {
|
|
||||||
clearInterval(interval);
|
|
||||||
interval = null;
|
|
||||||
}
|
|
||||||
document.querySelector('#controls-play i').classList.toggle('fa-play');
|
|
||||||
document.querySelector('#controls-play i').classList.toggle('fa-pause');
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('controls-play').addEventListener('click', toggleTimer);
|
|
||||||
|
|
||||||
function resetTimer() {
|
|
||||||
timer = startTime;
|
|
||||||
setTimer(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('display-time').addEventListener('click', resetTimer);
|
|
||||||
|
|
||||||
function switchPlayer() {
|
|
||||||
resetTimer();
|
|
||||||
document.querySelectorAll('.player-name').forEach(element => element.classList.toggle('active'));
|
|
||||||
if (!interval) {
|
|
||||||
toggleTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('controls-switch').addEventListener('click', switchPlayer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
var element = document.getElementById('controls-switch');
|
|
||||||
onLongPress(element, () => {
|
|
||||||
console.log('Long pressed', element);
|
|
||||||
});
|
|
||||||
|
|
||||||
function Sleep(milliseconds) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function beep2(frequency = 440, type = 'sawtooth', volume, callback) {
|
|
||||||
if (!audioCtx) {
|
|
||||||
audioCtx = new (window.AudioContext || window.webkitAudioContext || window.audioContext);
|
|
||||||
}
|
|
||||||
var oscillator = audioCtx.createOscillator();
|
|
||||||
var gainNode = audioCtx.createGain();
|
|
||||||
|
|
||||||
oscillator.connect(gainNode);
|
|
||||||
gainNode.connect(audioCtx.destination);
|
|
||||||
|
|
||||||
if (volume) {
|
|
||||||
gainNode.gain.value = volume;
|
|
||||||
}
|
|
||||||
if (frequency) {
|
|
||||||
oscillator.frequency.value = frequency;
|
|
||||||
}
|
|
||||||
if (type) {
|
|
||||||
oscillator.type = type;
|
|
||||||
}
|
|
||||||
if (callback) {
|
|
||||||
oscillator.onended = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
oscillator.start(audioCtx.currentTime);
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
oscillator.frequency.setValueAtTime(Math.floor(Math.random() * 1000), audioCtx.currentTime);
|
|
||||||
await Sleep(Math.floor(Math.random() * 100));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
element = document.getElementById('controls-settings');
|
|
||||||
onLongPress(element, beep2);
|
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user