seawolf2357 commited on
Commit Β·
4b19933
1
Parent(s): 924b98d
Minimap mobile scaling, countdown pop-in, reduced-motion a11y
Browse files- style.css: scale #minimap to 0.62x on max-width:640px so it no longer
overlaps the right-cluster touch buttons; add countdownPop keyframe
and prefers-reduced-motion support.
- js/game.js: add setCountdown() helper that restarts the pop keyframe
on each digit change so 3->2->1->GO! punches into view.
- js/game.js +18 -13
- style.css +45 -2
js/game.js
CHANGED
|
@@ -486,6 +486,19 @@ countdownEl.style.cssText = `
|
|
| 486 |
`;
|
| 487 |
document.body.appendChild(countdownEl);
|
| 488 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
// ββ RESULTS OVERLAY ββ
|
| 490 |
const resultsEl = document.createElement('div');
|
| 491 |
resultsEl.id = 'results-overlay';
|
|
@@ -1021,23 +1034,15 @@ function update() {
|
|
| 1021 |
if (raceState === 'countdown') {
|
| 1022 |
const countdownElapsed = elapsed - countdownStartTime;
|
| 1023 |
|
| 1024 |
-
// Show 3, 2, 1, GO
|
| 1025 |
if (countdownElapsed < 1) {
|
| 1026 |
-
|
| 1027 |
-
countdownEl.style.color = '#ff3333';
|
| 1028 |
-
countdownEl.style.opacity = '1';
|
| 1029 |
} else if (countdownElapsed < 2) {
|
| 1030 |
-
|
| 1031 |
-
countdownEl.style.color = '#ffaa00';
|
| 1032 |
-
countdownEl.style.opacity = '1';
|
| 1033 |
} else if (countdownElapsed < 3) {
|
| 1034 |
-
|
| 1035 |
-
countdownEl.style.color = '#00ff66';
|
| 1036 |
-
countdownEl.style.opacity = '1';
|
| 1037 |
} else if (countdownElapsed < 3.8) {
|
| 1038 |
-
|
| 1039 |
-
countdownEl.style.color = '#ffffff';
|
| 1040 |
-
countdownEl.style.opacity = '1';
|
| 1041 |
} else {
|
| 1042 |
countdownEl.style.opacity = '0';
|
| 1043 |
}
|
|
|
|
| 486 |
`;
|
| 487 |
document.body.appendChild(countdownEl);
|
| 488 |
|
| 489 |
+
let _lastCountdownText = '';
|
| 490 |
+
function setCountdown(text, color) {
|
| 491 |
+
countdownEl.style.opacity = '1';
|
| 492 |
+
countdownEl.style.color = color;
|
| 493 |
+
if (_lastCountdownText === text) return; // same digit β don't retrigger
|
| 494 |
+
_lastCountdownText = text;
|
| 495 |
+
countdownEl.textContent = text;
|
| 496 |
+
// Restart the pop keyframe by toggling the animation property.
|
| 497 |
+
countdownEl.style.animation = 'none';
|
| 498 |
+
void countdownEl.offsetWidth; // force reflow
|
| 499 |
+
countdownEl.style.animation = 'countdownPop 0.55s cubic-bezier(0.2, 1.2, 0.4, 1) forwards';
|
| 500 |
+
}
|
| 501 |
+
|
| 502 |
// ββ RESULTS OVERLAY ββ
|
| 503 |
const resultsEl = document.createElement('div');
|
| 504 |
resultsEl.id = 'results-overlay';
|
|
|
|
| 1034 |
if (raceState === 'countdown') {
|
| 1035 |
const countdownElapsed = elapsed - countdownStartTime;
|
| 1036 |
|
| 1037 |
+
// Show 3, 2, 1, GO (each digit pops in via countdownPop keyframe)
|
| 1038 |
if (countdownElapsed < 1) {
|
| 1039 |
+
setCountdown('3', '#ff3333');
|
|
|
|
|
|
|
| 1040 |
} else if (countdownElapsed < 2) {
|
| 1041 |
+
setCountdown('2', '#ffaa00');
|
|
|
|
|
|
|
| 1042 |
} else if (countdownElapsed < 3) {
|
| 1043 |
+
setCountdown('1', '#00ff66');
|
|
|
|
|
|
|
| 1044 |
} else if (countdownElapsed < 3.8) {
|
| 1045 |
+
setCountdown('GO!', '#ffffff');
|
|
|
|
|
|
|
| 1046 |
} else {
|
| 1047 |
countdownEl.style.opacity = '0';
|
| 1048 |
}
|
style.css
CHANGED
|
@@ -87,8 +87,11 @@ body::after {
|
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
-
/* Scale the
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
| 92 |
@media (max-width: 640px) {
|
| 93 |
#hud-canvas {
|
| 94 |
transform: scale(0.68);
|
|
@@ -98,6 +101,11 @@ body::after {
|
|
| 98 |
transform: scale(0.85);
|
| 99 |
transform-origin: top left;
|
| 100 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
}
|
| 102 |
|
| 103 |
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -178,3 +186,38 @@ body::after {
|
|
| 178 |
85% { opacity: 1; }
|
| 179 |
100% { opacity: 0; }
|
| 180 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
+
/* Scale the HUD gauge, top overlay, and minimap down on phones so
|
| 91 |
+
they no longer overlap the on-screen steering / pedal / nitro
|
| 92 |
+
touch buttons. The minimap is bottom-right at 180Γ180 and the
|
| 93 |
+
right-cluster touch buttons live right: 24-212px Γ bottom: 100-252px,
|
| 94 |
+
so without this rule they collide directly. */
|
| 95 |
@media (max-width: 640px) {
|
| 96 |
#hud-canvas {
|
| 97 |
transform: scale(0.68);
|
|
|
|
| 101 |
transform: scale(0.85);
|
| 102 |
transform-origin: top left;
|
| 103 |
}
|
| 104 |
+
#minimap {
|
| 105 |
+
transform: scale(0.62);
|
| 106 |
+
transform-origin: bottom right;
|
| 107 |
+
opacity: 0.7;
|
| 108 |
+
}
|
| 109 |
}
|
| 110 |
|
| 111 |
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 186 |
85% { opacity: 1; }
|
| 187 |
100% { opacity: 0; }
|
| 188 |
}
|
| 189 |
+
|
| 190 |
+
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 191 |
+
* Countdown pop-in β applied via inline animation from
|
| 192 |
+
* js/game.js each time the countdown digit changes so the
|
| 193 |
+
* "3 β 2 β 1 β GO!" beats actually punch into view instead
|
| 194 |
+
* of just color-swapping. The transform is compounded with
|
| 195 |
+
* the existing `translate(-50%, -50%)` set on countdownEl.
|
| 196 |
+
* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 197 |
+
@keyframes countdownPop {
|
| 198 |
+
0% { transform: translate(-50%, -50%) scale(0.35); opacity: 0; filter: blur(6px); }
|
| 199 |
+
35% { transform: translate(-50%, -50%) scale(1.18); opacity: 1; filter: blur(0); }
|
| 200 |
+
55% { transform: translate(-50%, -50%) scale(0.96); opacity: 1; }
|
| 201 |
+
100% { transform: translate(-50%, -50%) scale(1.00); opacity: 1; }
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
/* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 205 |
+
* Accessibility: honor the user's "reduce motion" OS pref.
|
| 206 |
+
* We keep state transitions (fades) but strip the bouncy
|
| 207 |
+
* keyframes and vignette pulse so motion-sensitive players
|
| 208 |
+
* still get a usable, polished HUD.
|
| 209 |
+
* βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 210 |
+
@media (prefers-reduced-motion: reduce) {
|
| 211 |
+
*,
|
| 212 |
+
*::before,
|
| 213 |
+
*::after {
|
| 214 |
+
animation-duration: 0.001ms !important;
|
| 215 |
+
animation-iteration-count: 1 !important;
|
| 216 |
+
transition-duration: 0.08s !important;
|
| 217 |
+
}
|
| 218 |
+
#loading-veil .lv-dots span {
|
| 219 |
+
animation: none !important;
|
| 220 |
+
opacity: 0.7 !important;
|
| 221 |
+
transform: none !important;
|
| 222 |
+
}
|
| 223 |
+
}
|