JSFiddle - React, Tailwind, and code Playground
by Dutton
HTML
<div class="app">
<div class="game-container">
<img
class="bg"
src="https://i.imgur.com/5Cnwvxh.png"
alt="Achtergrond"
/>
<div class="sparkles"></div>
<div class="timer-wrap">
<span class="icon">⏱</span>
<span id="timer">1:50</span>
</div>
<div class="attempts">
Pogingen:
<span id="attemptsCount">0</span>
</div>
<div class="hangman-area" id="hangmanArea">
<svg viewBox="0 0 260 260" class="hangman" aria-label="Hangman">
<line class="gallows" x1="30" y1="230" x2="120" y2="230"></line>
<line class="gallows" x1="65" y1="230" x2="65" y2="35"></line>
<line class="gallows" x1="65" y1="35" x2="165" y2="35"></line>
<line class="gallows" x1="165" y1="35" x2="165" y2="60"></line>
<g class="part head-part">
<circle cx="165" cy="82" r="22"></circle>
</g>
<g class="part body-part">
<line x1="165" y1="104" x2="165" y2="155"></line>
<line x1="165" y1="118" x2="135" y2="138"></line>
<line x1="165" y1="118" x2="195" y2="138"></line>
</g>
<g class="part legs-part">
<line x1="165" y1="155" x2="140" y2="200"></line>
<line x1="165" y1="155" x2="190" y2="200"></line>
</g>
</svg>
</div>
<div id="word"></div>
<div id="keyboard"></div>
<div class="lives-bar">
<span class="lives-label">Levens:</span>
<div class="lives-wrap" id="lives"></div>
</div>
<div class="overlay show" id="startPopup">
<div class="popup">
<p>
<strong>GALGJE</strong><br>
Raad het woord.. en win een code!<br>
Je kunt het net zo vaak proberen totdat je het woord hebt geraden.<br>
De code is te claimen t/m zondag Succes!
</p>
<button id="startBtn" type="button">
Start
</button>
</div>
...
CSS
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
min-height: 100%;
font-family: Arial, sans-serif;
}
body {
background: #d9d9df;
display: flex;
justify-content: center;
}
.app {
width: 688px;
height: 700px;
position: relative;
overflow: hidden;
}
.game-container {
position: relative;
width: 688px;
height: 700px;
overflow: hidden;
}
.bg {
position: absolute;
inset: 0;
width: 688px;
height: 700px;
object-fit: cover;
display: block;
}
.sparkles {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 2;
overflow: hidden;
}
.sparkles::before,
.sparkles::after {
content: "";
position: absolute;
inset: -200%;
background-image:
radial-gradient(circle, rgba(255,255,255,0.9) 1px, transparent 1px),
radial-gradient(circle, rgba(255,255,255,0.7) 1px, transparent 1px),
radial-gradient(circle, rgba(255,255,255,0.6) 2px, transparent 2px);
background-size:
120px 120px,
180px 180px,
240px 240px;
animation: sparkleMove 18s linear infinite;
opacity: 0.35;
}
.sparkles::after {
animation-duration: 28s;
opacity: 0.2;
}
@keyframes sparkleMove {
from {
transform: translateY(0);
}
to {
transform: translateY(120px);
}
}
.timer-wrap {
position: absolute;
top: 125px;
left: 62px;
z-index: 3;
display: flex;
align-items: center;
gap: 6px;
color: #ffffff;
font-size: 18px;
font-weight: 700;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}
.timer-danger {
color: #ff6b8f !important;
animation: timerBlink 0.8s infinite;
}
@keyframes timerBlink {
0% {
opacity: 1;
}
50% {
opacity: 0.35;
}
100% {
opacity: 1;
}
}
.icon {
font-size: 15px;
line-height: 1;
}
.hangman-area {
position: absolute;
top: 160px;
left: 72px;
width: 185px;
z-index: 3;
}
.hangman {
width: 185px;
height:...
JavaScript
document.addEventListener("DOMContentLoaded", () => {
const wordRows = ["LENTE", "KRIEBELS"];
const fullWord = wordRows.join("");
let guessed = [];
let mistakes = 0;
let attempts = 0;
const maxMistakes = 3;
let timeLeft = 110;
let timerInterval = null;
let gameOver = false;
let started = false;
const wordDiv = document.getElementById("word");
const keyboardDiv = document.getElementById("keyboard");
const timerEl = document.getElementById("timer");
const livesEl = document.getElementById("lives");
const attemptsCount =
document.getElementById("attemptsCount");
const parts = [
document.querySelector(".head-part"),
document.querySelector(".body-part"),
document.querySelector(".legs-part")
];
const gameContainer =
document.querySelector(".game-container");
const startPopup =
document.getElementById("startPopup");
const losePopup =
document.getElementById("losePopup");
const endPopup =
document.getElementById("endPopup");
const startBtn =
document.getElementById("startBtn");
const tryAgainBtn =
document.getElementById("tryAgainBtn");
function updateTimer() {
const min = Math.floor(timeLeft / 60);
const sec = timeLeft % 60;
timerEl.textContent =
`${min}:${sec.toString().padStart(2, "0")}`;
if (timeLeft <= 15) {
timerEl.classList.add("timer-danger");
} else {
timerEl.classList.remove("timer-danger");
}
}
function updateAttempts() {
attemptsCount.textContent = attempts;
}
function updateLives() {
livesEl.innerHTML = "";
for (let i = 0; i < maxMistakes - mistakes; i++) {
const heart = document.createElement("span");
heart.textContent = "💗";
livesEl.appendChild(heart);
}
}
function renderWord() {
wordDiv.innerHTML = "";
wordRows.forEach((rowWord) => {
const row =...