A Astro blog hosted on Vercel

pat squeak page

+80
public/pat.webp

This is a binary file and will not be displayed.

public/rat-squeak.mp3

This is a binary file and will not be displayed.

+80
src/pages/pat.astro
··· 1 + --- 2 + import { Head } from '@/components'; 3 + import { Image } from 'astro:assets'; 4 + --- 5 + 6 + <!doctype html> 7 + <html lang="en"> 8 + <head> 9 + <Head title={'🐀'} description={'Pat the rat'} /> 10 + <style> 11 + @keyframes squish { 12 + 0% { 13 + transform: scaleY(1); 14 + } 15 + 50% { 16 + transform: scaleY(0.5); 17 + } 18 + 100% { 19 + transform: scaleY(1); 20 + } 21 + } 22 + 23 + body > main { 24 + display: flex; 25 + justify-content: center; 26 + align-items: center; 27 + } 28 + 29 + body > main > img { 30 + width: auto; 31 + scale: 2; 32 + image-rendering: pixelated; 33 + cursor: pointer; 34 + 35 + animation-name: squish; 36 + animation-duration: 0.1s; 37 + animation-iteration-count: 1; 38 + animation-timing-function: linear; 39 + animation-play-state: paused; 40 + } 41 + </style> 42 + </head> 43 + <body data-theme="dark"> 44 + <audio id="squeak"> 45 + <source src="/rat-squeak.mp3" type="audio/mp3" /> 46 + </audio> 47 + <main> 48 + <Image 49 + id={'pat'} 50 + alt="Pat the rat" 51 + src={'/pat.webp'} 52 + width={128} 53 + height={128} 54 + /> 55 + </main> 56 + <script> 57 + const pat = document.querySelector<HTMLImageElement>('img#pat'); 58 + 59 + pat?.addEventListener('click', () => { 60 + if (!pat) return; 61 + const squeakAudio = new Audio('rat-squeak.mp3'); 62 + 63 + pat.style.animationName = 'none'; 64 + pat.offsetHeight; 65 + 66 + pat.style.animationName = 'squish'; 67 + pat.style.animationPlayState = 'running'; 68 + squeakAudio.currentTime = 0; 69 + squeakAudio.play(); 70 + }); 71 + 72 + pat?.addEventListener('animationend', () => { 73 + if (!pat) return; 74 + 75 + pat.style.animationName = 'none'; 76 + pat.style.animationPlayState = 'paused'; 77 + }); 78 + </script> 79 + </body> 80 + </html>