Skip to content

Instantly share code, notes, and snippets.

@fgouin2014
Created July 19, 2024 01:36
Show Gist options
  • Save fgouin2014/ce0a0f5e75213edf894671fb2c2ca302 to your computer and use it in GitHub Desktop.
Save fgouin2014/ce0a0f5e75213edf894671fb2c2ca302 to your computer and use it in GitHub Desktop.
Green Counter
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scoreboard VFD</title>
<style>
body {
background-color: #000;
color: #00ffcc;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
font-family: monospace;
}
.scoreboard-container {
width: 80%;
max-width: 1200px;
margin: 20px auto;
padding: 20px;
border: 2px solid #00ffcc;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 255, 204, 0.5);
background-color: #222;
overflow: hidden;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.stat {
flex: 1 0 calc(25% - 20px);
text-align: center;
margin: 10px;
}
.led-score {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
gap: 5px;
width: 100%;
}
.led-block {
width: 60%;
height: 50px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-color: #222;
border: 1px solid #00ffcc;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
font-size: calc(100% + 1vw);
text-align: center;
}
</style>
</head>
<body>
<div class="scoreboard-container">
<div class="stat">
<span class="stat-title">High-Score:</span>
<div class="led-score high-score">
<canvas class="led-block high-score-canvas"></canvas>
<canvas class="led-block high-score-canvas"></canvas>
<canvas class="led-block high-score-canvas"></canvas>
<canvas class="led-block high-score-canvas"></canvas>
<canvas class="led-block high-score-canvas"></canvas>
</div>
</div>
<div class="stat">
<span class="stat-title">Score actuel:</span>
<div class="led-score current-score">
<canvas class="led-block current-score-canvas"></canvas>
<canvas class="led-block current-score-canvas"></canvas>
<canvas class="led-block current-score-canvas"></canvas>
<canvas class="led-block current-score-canvas"></canvas>
<canvas class="led-block current-score-canvas"></canvas>
</div>
</div>
<div class="stat">
<span class="stat-title">Nombre d'essais:</span>
<div class="led-score error-count">
<canvas class="led-block error-count-canvas"></canvas>
<canvas class="led-block error-count-canvas"></canvas>
<canvas class="led-block error-count-canvas"></canvas>
</div>
</div>
<div class="stat">
<span class="stat-title">Temps écoulé:</span>
<div class="led-score elapsed-time">
<canvas class="led-block elapsed-time-canvas"></canvas></span>.</span>
<canvas class="led-block elapsed-time-canvas"></canvas>
<canvas class="led-block elapsed-time-canvas"></canvas>
</div>
</div>
</div>
<script>
const highScoreCanvas = document.querySelectorAll('.high-score-canvas');
const currentScoreCanvas = document.querySelectorAll('.current-score-canvas');
const errorCountCanvas = document.querySelectorAll('.error-count-canvas');
const elapsedTimeCanvas = document.querySelectorAll('.elapsed-time-canvas');
let highScore = 99999;
let currentScore = 0;
let errorCount = 0;
let elapsedTime = 5.00; // Initial countdown value in seconds
function drawVFDSquare(ctx, character) {
const rectWidth = ctx.canvas.width;
const rectHeight = ctx.canvas.height;
ctx.clearRect(0, 0, rectWidth, rectHeight); // Clear the canvas
ctx.fillStyle = '#00ffcc';
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
const fontSize = Math.min(rectWidth / 2.5, rectHeight * 0.8);
ctx.font = `${fontSize}px monospace`;
const textX = rectWidth / 2;
const textY = rectHeight / 2;
ctx.fillText(character, textX, textY);
}
function drawScanlines(ctx) {
const rectWidth = ctx.canvas.width;
const rectHeight = ctx.canvas.height;
const scanlineThickness = 1;
const scanlineSpacing = 2;
ctx.fillStyle = 'rgba(0, 255, 204, 0.5)';
for (let i = 0; i < rectHeight; i += scanlineSpacing) {
ctx.fillRect(0, i, rectWidth, scanlineThickness);
}
}
function updateHighScore() {
const scores = highScore.toString().padStart(5, '0').split('');
highScoreCanvas.forEach((canvas, index) => {
const ctx = canvas.getContext('2d');
drawVFDSquare(ctx, scores[index]);
drawScanlines(ctx);
});
}
function updateCurrentScore() {
currentScore++;
const scores = currentScore.toString().padStart(5, '0').split('');
currentScoreCanvas.forEach((canvas, index) => {
const ctx = canvas.getContext('2d');
drawVFDSquare(ctx, scores[index]);
drawScanlines(ctx);
});
}
function updateErrorCount() {
errorCount++;
const errors = '☠'.repeat(errorCount > 3 ? 3 : errorCount).split('');
errorCountCanvas.forEach((canvas, index) => {
const ctx = canvas.getContext('2d');
drawVFDSquare(ctx, errors[index] || ' ');
drawScanlines(ctx);
});
}
function updateElapsedTime() {
elapsedTime -= 0.01; // Reduce elapsed time by 0.01 second
if (elapsedTime <= 0) {
elapsedTime = 0.00; // Set elapsed time to 0.00 when countdown ends
errorCount = 0; // Reset error count when time resets
}
const timeFormatted = elapsedTime.toFixed(2).replace('.', '').split(''); // Remove dot from time string
elapsedTimeCanvas.forEach((canvas, index) => {
const ctx = canvas.getContext('2d');
drawVFDSquare(ctx, timeFormatted[index] || '0');
drawScanlines(ctx);
});
}
// Initial update
updateHighScore();
updateCurrentScore();
updateErrorCount();
updateElapsedTime();
// Simulation intervals
const highScoreInterval = setInterval(updateHighScore, 5000); // Simulate high score update every 5 seconds
const currentScoreInterval = setInterval(updateCurrentScore, 100); // Simulate current score increment every 100 milliseconds
const errorCountInterval = setInterval(updateErrorCount, 2000); // Simulate error count update every 2 seconds
const elapsedTimeInterval = setInterval(updateElapsedTime, 10); // Simulate elapsed time update every 10 milliseconds
// Stop intervals after 5 seconds
setTimeout(() => {
clearInterval(highScoreInterval);
clearInterval(currentScoreInterval);
clearInterval(errorCountInterval);
clearInterval(elapsedTimeInterval);
}, 5000);
</script>
</body>
</html>
<link href="https://rs-sv1-03.vercel.app/fonts.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment