refactored 404 page, fixed copy image toast on mobile and filtered missing images to exclude sealed
This commit is contained in:
@@ -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 # (0001–1025)
|
||||
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>
|
||||
Reference in New Issue
Block a user