refactored 404 page, fixed copy image toast on mobile and filtered missing images to exclude sealed

This commit is contained in:
zach
2026-03-12 13:40:12 -04:00
parent c10e34cc34
commit 835a174da2
5 changed files with 242 additions and 178 deletions

View File

@@ -6,9 +6,6 @@ import NavBar from '../components/NavBar.astro';
import Footer from '../components/Footer.astro';
import pokedexList from '../data/pokedex.json';
const searchParams = Astro.url.searchParams;
const query = searchParams.get('q') || '*';
// Get random # (00011025)
const randomNumber = String(Math.floor(Math.random() * 1025) + 1).padStart(4, "0");
@@ -34,7 +31,7 @@ const pokemonName = pokemon?.Name || "Unknown Pokémon";
</p>
</div>
<div class="col-12 col-md-5 offset-md-1">
<div class="alert alert-warning border p-2" role="alert">
<div id="reveal-hint" class="alert alert-warning border p-2" role="alert">
<h4 class="alert-heading">Who's that Pokémon?</h4>
<p class="mb-0">Click the image to reveal.</p>
</div>
@@ -47,12 +44,14 @@ const pokemonName = pokemon?.Name || "Unknown Pokémon";
<img class="w-100 starburst top-0 bottom-0 left-0 right-0" src="/404/glow.png" alt="" />
<img
class="m-auto position-absolute w-75 top-0 left-25 bottom-10 right-0 d-block img-fluid masked-image top-50 start-50 translate-middle"
class="m-auto position-absolute w-75 top-0 left-25 bottom-10 right-0 d-block img-fluid masked-image top-50 start-50 translate-middle pokemon-clickable"
src={pokedexImage}
alt={pokemonName}
alt=""
data-name={pokemonName}
role="button"
tabindex="0"
draggable="false"
aria-label="Reveal the Pokémon"
/>
</div>
</div>
@@ -60,21 +59,97 @@ const pokemonName = pokemon?.Name || "Unknown Pokémon";
<!-- Pokémon name reveal -->
<div class="col-12 text-center mt-3">
<h3 id="pokemon-name" class="opacity-0 transition-opacity">???</h3>
<h3
id="pokemon-name"
class="opacity-0 pokemon-transition"
aria-live="polite"
aria-atomic="true"
>???</h3>
<button
id="play-again"
class="btn btn-primary mt-3 opacity-0 pokemon-transition"
style="pointer-events: none;"
aria-hidden="true"
>
Guess another Pokémon
</button>
</div>
</div>
</div>
<Footer slot="footer" />
</Layout>
<style>
.pokemon-transition {
transition: opacity 0.4s ease;
}
.pokemon-clickable {
cursor: pointer;
}
.pokemon-clickable:focus-visible {
outline: 3px solid #ffc107;
outline-offset: 4px;
border-radius: 4px;
}
@keyframes pokemon-pulse {
0%, 100% { filter: brightness(0) drop-shadow(0 0 6px var(--bs-info-border-subtle)); }
50% { filter: brightness(0) drop-shadow(0 0 18px var(--bs-info)); }
}
.masked-image {
filter: brightness(0);
animation: pokemon-pulse 2s ease-in-out infinite;
}
</style>
<script>
const img = document.querySelector('.masked-image') as HTMLImageElement | null;
const nameEl = document.querySelector('#pokemon-name');
const playAgainBtn = document.querySelector('#play-again') as HTMLButtonElement | null;
const hintEl = document.querySelector('#reveal-hint');
function revealPokemon() {
if (!img || !nameEl) return;
const doReveal = () => {
img.classList.remove('masked-image');
nameEl.textContent = img.dataset.name || "Unknown Pokémon";
// Remove masked styles and interactivity from image
img.classList.remove('masked-image', 'pokemon-clickable');
img.removeAttribute('role');
img.removeAttribute('tabindex');
img.removeAttribute('aria-label');
img.style.animation = '';
// Update alt text now that it's revealed
img.alt = img.dataset.name || 'Unknown Pokémon';
// Reveal name
nameEl.textContent = img.dataset.name || 'Unknown Pokémon';
nameEl.classList.remove('opacity-0');
dataLayer.push({ event: '404reveal', pokemonName: img.dataset.name });
// Update hint text
if (hintEl) {
hintEl.querySelector('p')!.textContent = "It's " + (img.dataset.name || 'Unknown Pokémon') + "!";
}
// Show play again button
if (playAgainBtn) {
playAgainBtn.classList.remove('opacity-0');
playAgainBtn.style.pointerEvents = '';
playAgainBtn.removeAttribute('aria-hidden');
}
// Fire analytics safely
try {
if (typeof dataLayer !== 'undefined') {
dataLayer.push({ event: '404reveal', pokemonName: img.dataset.name });
}
} catch (e) {
// Analytics unavailable, continue silently
}
};
if (!document.startViewTransition) {
@@ -98,9 +173,8 @@ const pokemonName = pokemon?.Name || "Unknown Pokémon";
revealPokemon();
}
});
</script>
</div>
<Footer slot="footer" />
</Layout>
playAgainBtn?.addEventListener('click', () => {
window.location.reload();
});
</script>