[Archived] Archived WIP of vielle.dev

Add initial animation for popping balloons

+67 -4
+66 -4
src/components/blog/Balloon.astro
··· 25 25 --timing: ${utils.getRandom(blog.balloons.timing)}s; 26 26 `} 27 27 > 28 - <div 28 + <button 29 29 class="balloon" 30 30 style={`--width: ${utils.getRandom(blog.balloons.size[0])}rem; 31 31 --height: ${utils.getRandom(blog.balloons.size[1])}rem;`} 32 + tabindex="-1" 33 + data-min-time={blog.balloons.time[0]} 34 + data-max-time={blog.balloons.time[1]} 32 35 > 33 36 <div class="cable-tie"></div> 34 37 <div class="tie"></div> 35 - </div> 38 + </button> 36 39 </div> 40 + 41 + <script> 42 + const balloons = document.querySelectorAll(".balloon"); 43 + console.log(balloons); 44 + balloons.forEach((el) => { 45 + if (!(el instanceof HTMLButtonElement)) return; 46 + 47 + // reenable tab index as functional 48 + el.tabIndex = 0; 49 + 50 + const mintime = Number(el.dataset["minTime"] ?? "0"); 51 + const maxtime = Number(el.dataset["maxTime"] ?? "0"); 52 + 53 + el.addEventListener("click", () => { 54 + const postParent = el.parentElement?.parentElement; 55 + if (!postParent) throw new Error("No parent 2 levels up!!!"); 56 + console.log("clicked! popping", el, "with post", postParent); 57 + 58 + el.blur(); 59 + 60 + el.animate( 61 + [ 62 + { 63 + opacity: 1, 64 + }, 65 + { 66 + opacity: 0, 67 + }, 68 + { 69 + duration: 500, 70 + }, 71 + ], 72 + {} 73 + ).finished.then(() => 74 + el.animate( 75 + [ 76 + { opacity: 0, scale: 0 }, 77 + { opacity: 1, offset: 0.001 }, 78 + { scale: 1 }, 79 + ], 80 + { 81 + duration: (mintime + Math.random() * (maxtime - mintime)) * 1000, 82 + easing: "ease-out", 83 + } 84 + ) 85 + ); 86 + }); 87 + }); 88 + </script> 37 89 38 90 <style> 39 91 @property --rot-0 { ··· 135 187 } 136 188 137 189 .balloon { 190 + border: none; 191 + 138 192 width: var(--width); 139 193 height: var(--height); 140 194 border-radius: calc(var(--width) / 2); ··· 143 197 background: var(--colour); 144 198 /* 95% instead of 100% to prevent gaps between cable */ 145 199 translate: -50% -95%; 200 + transform-origin: bottom; 146 201 rotate: calc(-1 * var(--rot-0)); 147 202 148 203 @media (prefers-reduced-motion: no-preference) { 149 204 animation: infinite var(--timing) linear inv-tilt; 150 205 } 206 + 207 + transition: scale 0.2s; 208 + 209 + &:focus { 210 + outline: none; 211 + scale: 1.1; 212 + } 151 213 } 152 214 153 215 .cable-tie { 154 216 width: 1.75rem; 155 - height: .5rem; 217 + height: 0.5rem; 156 218 157 219 position: absolute; 158 - bottom: -.25rem; 220 + bottom: -0.25rem; 159 221 left: 50%; 160 222 translate: -50%; 161 223 z-index: 1;
+1
src/config.ts
··· 48 48 [10, 20], 49 49 ], 50 50 opacity: [0.6, 0.9], 51 + time: [2, 5], 51 52 }, 52 53 } as const; 53 54