From 759977435efba5c1f6bc82c8e211f907881ca426 Mon Sep 17 00:00:00 2001 From: Max Martens Date: Tue, 22 Jul 2025 09:59:18 +0000 Subject: [PATCH] Add animated stick figure indicating angryness level --- frustrationmeter/index.html | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/frustrationmeter/index.html b/frustrationmeter/index.html index a004190..139a663 100644 --- a/frustrationmeter/index.html +++ b/frustrationmeter/index.html @@ -17,6 +17,138 @@ box-shadow: 0 0 25px rgba(79, 70, 229, 0.7); color: white; } + + /* Stick Figure Styles */ + .stick-figure { + width: 120px; + height: 200px; + position: relative; + margin: 20px auto; + } + .head { + width: 50px; + height: 50px; + border-radius: 50%; + border: 2px solid white; + position: absolute; + left: 35px; + top: 0; + transition: all 0.3s ease; + } + .eye { + width: 8px; + height: 8px; + background: white; + border-radius: 50%; + position: absolute; + top: 15px; + } + .eye.left { left: 15px; } + .eye.right { right: 15px; } + .mouth { + width: 20px; + height: 10px; + border-bottom: 2px solid white; + position: absolute; + bottom: 10px; + left: 15px; + border-radius: 0 0 10px 10px; + transition: all 0.3s ease; + } + .body { + width: 4px; + height: 70px; + background: white; + position: absolute; + left: 58px; + top: 50px; + } + .arm { + width: 50px; + height: 4px; + background: white; + position: absolute; + top: 70px; + transform-origin: left center; + transition: all 0.3s ease; + } + .arm.left { left: 10px; transform: rotate(20deg); } + .arm.right { left: 60px; transform: rotate(-20deg); } + .leg { + width: 4px; + height: 60px; + background: white; + position: absolute; + top: 120px; + transform-origin: top center; + transition: all 0.3s ease; + } + .leg.left { left: 45px; transform: rotate(5deg); } + .leg.right { left: 70px; transform: rotate(-5deg); } + + /* Anger states */ + .angry .eye { + transform: scaleY(0.6); + border-radius: 50% 50% 0 0; + background: transparent; + border-top: 2px solid white; + } + .angry .mouth { + border-radius: 10px 10px 0 0; + border-top: 2px solid white; + border-bottom: none; + transform: scaleY(0.7); + } + .very-angry .eye { + transform: scale(0.8) rotate(45deg); + background: #ff4444; + border: 2px solid #ff4444; + } + .very-angry .mouth { + border: 2px solid #ff4444; + border-bottom: none; + border-radius: 10px 10px 0 0; + height: 15px; + background: #ff4444; + } + .very-angry .arm { + transform: rotate(0deg) !important; + top: 80px; + } + .very-angry .leg { + transform: rotate(0deg) !important; + } + .enraged .head { + background: #ff0000; + animation: shake 0.1s infinite; + } + .enraged .eye { + background: #ff0000; + border-color: #ff0000; + animation: blink 0.5s infinite; + } + .enraged .mouth { + border-color: #ff0000; + background: #ff0000; + animation: shout 0.3s infinite alternate; + } + .enraged .arm, .enraged .leg { + background: #ff0000; + animation: shake 0.05s infinite; + } + @keyframes shake { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-2px); } + 75% { transform: translateX(2px); } + } + @keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.3; } + } + @keyframes shout { + from { transform: scale(1); } + to { transform: scale(1.3); } + } @@ -26,6 +158,20 @@
+ + +
+
+
+
+
+
+
+
+
+
+
+
Dots: 0
@@ -50,6 +196,7 @@ const dotCountEl = document.getElementById('dot-count'); const resultEl = document.getElementById('result'); const restartBtn = document.getElementById('restart'); + const stickFigure = document.getElementById('stick-figure'); let gameInterval = null; let currentDots = 0; @@ -62,6 +209,17 @@ currentTarget = s.target; } + function updateAngerLevel(dots) { + stickFigure.className = 'stick-figure'; + if (dots > currentTarget * 1.5) { + stickFigure.classList.add('enraged'); + } else if (dots > currentTarget) { + stickFigure.classList.add('very-angry'); + } else if (dots > currentTarget * 0.7) { + stickFigure.classList.add('angry'); + } + } + function startPress() { if (isHolding) return; isHolding = true; @@ -70,11 +228,13 @@ dotCountEl.textContent = '0'; resultEl.classList.add('hidden'); restartBtn.classList.add('hidden'); + stickFigure.className = 'stick-figure'; gameInterval = setInterval(() => { currentDots++; dotDisplay.textContent += '.'; dotCountEl.textContent = currentDots; + updateAngerLevel(currentDots); }, 40); }