Skip to content

Instantly share code, notes, and snippets.

@defufna
Created November 16, 2024 19:37
Show Gist options
  • Save defufna/d74b7b5b85b5d2d74ff453a2d49779fd to your computer and use it in GitHub Desktop.
Save defufna/d74b7b5b85b5d2d74ff453a2d49779fd to your computer and use it in GitHub Desktop.
Roman
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Roman Numerals Quiz</title>
<style>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
transition: background-color 2s ease, color 2s ease;
}
#roman-numeral {
font-size: 100px;
font-weight: bold;
margin-bottom: 20px;
opacity: 1;
transition: opacity 20s linear;
}
#score {
margin-top: 20px;
font-size: 24px;
}
input {
font-size: 20px;
padding: 10px;
margin-top: 10px;
width: 200px;
text-align: center;
}
.particle {
position: absolute;
width: 10px;
height: 10px;
background-color: gold;
border-radius: 50%;
animation: particle-animation 2s ease-out;
pointer-events: none;
z-index:-1;
}
@keyframes particle-animation {
from {
opacity: 1;
transform: translate(0, 0) scale(1);
}
to {
opacity: 0;
transform: translate(var(--dx), var(--dy)) scale(0);
}
}
</style>
</head>
<body>
<div id="roman-numeral">X</div>
<input id="user-input" type="number" inputmode="numeric" placeholder="Enter the number">
<div id="score">Score: 0</div>
<script>
const romanMap = [
[1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'],
[100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'],
[10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']
];
const colorPairs = [
{ background: "#1E1E1E", particles: "#FFD700" }, // Dark gray and gold
{ background: "#2E8B57", particles: "#FFFFFF" }, // Sea green and white
{ background: "#1E90FF", particles: "#FF4500" }, // Dodger blue and orange red
{ background: "#800080", particles: "#FFFF00" }, // Purple and yellow
{ background: "#FF6347", particles: "#FFFFFF" }, // Tomato red and white
{ background: "#4B0082", particles: "#FFD700" }, // Indigo and gold
{ background: "#228B22", particles: "#FF69B4" }, // Forest green and hot pink
{ background: "#000080", particles: "#00FFFF" }, // Navy and cyan
{ background: "#A52A2A", particles: "#FFFFFF" }, // Brown and white
{ background: "#000000", particles: "#FF6347" } // Black and tomato red
];
let score = 0;
const numeralElement = document.getElementById('roman-numeral');
const inputElement = document.getElementById('user-input');
const scoreElement = document.getElementById('score');
function generateRandomNumber() {
return Math.floor(Math.random() * 1000) + 1;
}
function toRoman(num) {
let result = '';
for (const [value, numeral] of romanMap) {
while (num >= value) {
result += numeral;
num -= value;
}
}
return result;
}
let nextTimeout;
const timeout = 45;
function triggerCelebration(color) {
// Add particles
for (let i = 0; i < 100; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
// Randomize particle movement
const dx = (Math.random() - 0.5) * window.innerWidth + 'px';
const dy = (Math.random() - 0.5) * window.innerHeight + 'px';
// Set particle position
particle.style.left = window.innerWidth / 2 + 'px';
particle.style.top = window.innerHeight / 2 + 'px';
particle.style.setProperty('--dx', dx);
particle.style.setProperty('--dy', dy);
particle.style.backgroundColor = color;
document.body.appendChild(particle);
// Remove particle after animation
particle.addEventListener('animationend', () => particle.remove());
}
}
function showNextNumeral() {
const number = generateRandomNumber();
numeralElement.textContent = toRoman(number);
numeralElement.dataset.value = number;
numeralElement.style.transition = "none";
numeralElement.style.opacity = 1;
setTimeout(() => {
numeralElement.style.transition = `opacity ${timeout}s linear`;
numeralElement.style.opacity = 0;
nextTimeout = setTimeout(() => {
reset();
scoreElement.textContent = `Score: ${score}`;
showNextNumeral();
}, timeout*1000);
}); // Small timeout to ensure transition applies
}
function reset(){
score=0;
inputElement.value = '';
document.body.style.backgroundColor = "#f0f0f0";
document.body.style.color = "black";
}
inputElement.addEventListener('keydown', (event) => {
if (event.key === 'Enter') { // Check if the Enter key was pressed
const userValue = parseInt(inputElement.value, 10);
const correctValue = parseInt(numeralElement.dataset.value, 10);
clearTimeout(nextTimeout);
if (userValue === correctValue) {
score+=10;
if(score % 100 === 0){
let pair = colorPairs[(score / 100)%colorPairs.length];
triggerCelebration(pair.particles);
document.body.style.backgroundColor = pair.background;
document.body.style.color = pair.particles;
}
showNextNumeral();
} else if (inputElement.value !== '' && userValue !== correctValue) {
numeralElement.style.opacity = 0;
reset();
setTimeout(showNextNumeral, 500);
}
scoreElement.textContent = `Score: ${score}`;
inputElement.value = '';
}
});
showNextNumeral();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment