Two teams try and fill in any horizontal, vertical, or diagonal line on a bingo board by playing maps on osu! osu.bingo
osu
at microservice 70 lines 1.6 kB view raw
1<script lang="ts"> 2 import { cubicInOut } from 'svelte/easing'; 3 import { tweened } from 'svelte/motion'; 4 5 export let tab = 0; 6 export let duration = 150; 7 8 const bar1 = tweened(0, { 9 duration, 10 easing: cubicInOut 11 }); 12 const bar2 = tweened(0, { 13 duration, 14 easing: cubicInOut 15 }); 16 17 let data: HTMLElement; 18 let icons: HTMLElement[] = []; 19 let panes: HTMLElement[] = []; 20 21 $: { 22 if (data) { 23 icons = []; 24 panes = []; 25 data.childNodes.forEach((v) => { 26 if ((v as HTMLElement)?.classList?.contains('pane')) panes.push(v as HTMLElement); 27 if ((v as HTMLElement)?.classList?.contains('icon')) icons.push(v as HTMLElement); 28 }); 29 } 30 31 switchTabs(tab); 32 } 33 34 const switchTabs = (n: number) => { 35 tab = n; 36 37 const interval = 1 / panes.length; 38 bar1.set(tab * interval); 39 bar2.set((panes.length - (tab + 1)) * interval); 40 }; 41</script> 42 43<!-- Used to get the slot data --> 44<div class="hidden" bind:this={data}> 45 <slot /> 46</div> 47 48<div class="flex size-full bg-zinc-800"> 49 {#if panes[tab]} 50 <div class="size-full"> 51 {@html panes[tab].innerHTML} 52 </div> 53 {/if} 54 <div class="space-evenly relative flex h-full w-[50px] flex-col align-middle"> 55 {#each icons as icon, i} 56 <button on:click={() => switchTabs(i)} class="z-10 size-full"> 57 {@html icon.innerHTML} 58 </button> 59 {/each} 60 <!-- Tab blockers --> 61 <div 62 class="absolute top-0 z-0 w-full rounded-bl-xl bg-zinc-900" 63 style="height: calc(100% * {$bar1})" 64 ></div> 65 <div 66 class="absolute bottom-0 z-0 w-full rounded-tl-xl bg-zinc-900" 67 style="height: calc(100% * {$bar2})" 68 ></div> 69 </div> 70</div>