A Astro blog hosted on Vercel

pat cheese confetti

Changed files
+61 -13
src
pages
+61 -13
src/pages/pat.astro
··· 6 6 <!doctype html> 7 7 <html lang="en"> 8 8 <head> 9 - <Head title={'🐀'} description={'Pat the rat'} /> 9 + <Head title={'🐀'} description={'pat the rat'} /> 10 + <script 11 + defer 12 + src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js" 13 + > 14 + </script> 10 15 <style> 11 16 @keyframes squish { 12 17 0% { ··· 24 29 display: flex; 25 30 justify-content: center; 26 31 align-items: center; 32 + gap: 8rem; 33 + } 34 + 35 + body > main > p#cheeses { 36 + display: flex; 37 + flex-direction: row; 38 + gap: 1rem; 39 + font-size: 2rem; 40 + } 41 + 42 + body > main > p#cheeses[data-cheeses='0'] { 43 + visibility: hidden; 44 + } 45 + 46 + body > main > p#cheeses::after { 47 + content: attr(data-cheeses); 27 48 } 28 49 29 50 body > main > img { ··· 45 66 <source src="/rat-squeak.mp3" type="audio/mp3" /> 46 67 </audio> 47 68 <main> 69 + <p id="cheeses" data-cheeses="0">🧀</p> 48 70 <Image 49 71 id={'pat'} 50 - alt="Pat the rat" 72 + alt="pat the rat" 51 73 src={'/pat.webp'} 52 74 width={128} 53 75 height={128} 54 76 /> 55 77 </main> 56 78 <script> 57 - const pat = document.querySelector<HTMLImageElement>('img#pat'); 79 + let cheeses = 0; 80 + const $PAT = document.querySelector<HTMLImageElement>('img#pat'); 81 + const $CHEESES = 82 + document.querySelector<HTMLParagraphElement>('p#cheeses'); 83 + const cheese = confetti.shapeFromText({ text: '🧀', scalar: 5 }); 58 84 59 - pat?.addEventListener('click', () => { 60 - if (!pat) return; 85 + window.addEventListener('load', () => { 86 + window.cookieStore.get('cheeses').then((item) => { 87 + if (!$CHEESES) return; 88 + cheeses = parseInt(item?.value ?? '0'); 89 + $CHEESES.setAttribute('data-cheeses', cheeses.toString()); 90 + }); 91 + }); 92 + 93 + $PAT?.addEventListener('click', () => { 94 + if (!$PAT) return; 95 + if (!$CHEESES) return; 61 96 const squeakAudio = new Audio('rat-squeak.mp3'); 62 97 63 - pat.style.animationName = 'none'; 64 - pat.offsetHeight; 98 + $PAT.style.animationName = 'none'; 99 + $PAT.offsetHeight; 65 100 66 - pat.style.animationName = 'squish'; 67 - pat.style.animationPlayState = 'running'; 101 + $PAT.style.animationName = 'squish'; 102 + $PAT.style.animationPlayState = 'running'; 68 103 squeakAudio.currentTime = 0; 69 104 squeakAudio.play(); 105 + 106 + cheeses += 1; 107 + $CHEESES.setAttribute('data-cheeses', cheeses.toString()); 108 + window.cookieStore.set('cheeses', cheeses.toString()); 109 + 110 + if (cheeses % 100 === 0) { 111 + confetti({ 112 + particleCount: cheeses, 113 + spread: 360, 114 + shapes: [cheese], 115 + scalar: 5, 116 + }); 117 + } 70 118 }); 71 119 72 - pat?.addEventListener('animationend', () => { 73 - if (!pat) return; 120 + $PAT?.addEventListener('animationend', () => { 121 + if (!$PAT) return; 74 122 75 - pat.style.animationName = 'none'; 76 - pat.style.animationPlayState = 'paused'; 123 + $PAT.style.animationName = 'none'; 124 + $PAT.style.animationPlayState = 'paused'; 77 125 }); 78 126 </script> 79 127 </body>