tempo_estimator / index.html
justinxzhao's picture
Update index.html
cd88ef3 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tempo Estimator</title>
<!-- Bootstrap CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-light: #f0f0f0;
--text-color-light: #000;
--bg-color-dark: #2c2c2c;
--text-color-dark: #fff;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
font-family: 'Roboto', sans-serif;
transition: background-color 0.3s, color 0.3s;
text-align: center;
}
body.light-mode {
background-color: var(--bg-color-light);
color: var(--text-color-light);
}
body.dark-mode {
background-color: var(--bg-color-dark);
color: var(--text-color-dark);
}
.btn-custom {
padding: 30px 60px;
font-size: 36px;
margin: 10px;
border-radius: 50px;
position: relative;
}
.btn-reset {
padding: 15px 30px;
font-size: 18px;
margin: 10px;
border-radius: 50px;
position: relative;
}
#tempoDisplay {
font-size: 36px;
margin-bottom: 20px;
}
.toggle-button {
display: flex;
align-items: center;
cursor: pointer;
margin-top: 20px;
}
.toggle-button input {
display: none;
}
.toggle-label {
display: flex;
align-items: center;
background-color: #ccc;
border-radius: 50px;
padding: 5px;
width: 40px;
justify-content: space-between;
position: relative;
}
.toggle-label .ball {
background-color: #fff;
border-radius: 50%;
width: 20px;
height: 20px;
position: absolute;
left: 0;
transition: transform 0.3s;
}
input:checked + .toggle-label .ball {
transform: translateX(20px);
}
.sparkle {
position: absolute;
width: 20px;
height: 20px;
background: orange;
border-radius: 50%;
animation: sparkle 0.5s ease-out;
}
@keyframes sparkle {
from {
transform: scale(0);
opacity: 1;
}
to {
transform: scale(1.5);
opacity: 0;
}
}
</style>
</head>
<body class="light-mode">
<div id="tempoDisplay">-- BPM</div>
<button id="tapButton" class="btn btn-primary btn-custom">Tap</button>
<button id="resetButton" class="btn btn-secondary btn-reset">Reset</button>
<div class="toggle-button">
<input type="checkbox" id="modeToggle">
<label for="modeToggle" class="toggle-label">
<div class="ball"></div>
</label>
</div>
<script>
let tapTimes = [];
document.getElementById('tapButton').addEventListener('click', (e) => {
const currentTime = new Date().getTime();
tapTimes.push(currentTime);
if (tapTimes.length > 1) {
const timeIntervals = [];
for (let i = 1; i < tapTimes.length; i++) {
timeIntervals.push(tapTimes[i] - tapTimes[i - 1]);
}
const averageInterval = timeIntervals.reduce((a, b) => a + b) / timeIntervals.length;
const tempo = Math.round(60000 / averageInterval);
document.getElementById('tempoDisplay').innerText = `${tempo} BPM`;
}
if (tapTimes.length > 10) {
tapTimes.shift();
}
// Sparkle effect
const sparkle = document.createElement('div');
sparkle.className = 'sparkle';
sparkle.style.left = `${e.clientX - e.target.offsetLeft - 10}px`;
sparkle.style.top = `${e.clientY - e.target.offsetTop - 10}px`;
e.target.appendChild(sparkle);
setTimeout(() => {
sparkle.remove();
}, 500);
});
document.getElementById('resetButton').addEventListener('click', () => {
tapTimes = [];
document.getElementById('tempoDisplay').innerText = '-- BPM';
});
document.getElementById('modeToggle').addEventListener('change', () => {
const body = document.body;
if (body.classList.contains('light-mode')) {
body.classList.remove('light-mode');
body.classList.add('dark-mode');
} else {
body.classList.remove('dark-mode');
body.classList.add('light-mode');
}
});
document.addEventListener('keydown', (event) => {
if (event.key === ' ') {
document.getElementById('tapButton').click();
}
});
</script>
<!-- Bootstrap JS and dependencies -->
<script src="https://code.jquery.com/jquery-3.5.1.s