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 68 lines 1.7 kB view raw
1<script lang="ts"> 2 import { browser } from '$app/environment'; 3 import { goto } from '$app/navigation'; 4 import { promise } from '$lib/toast'; 5 import { Trash2Icon } from 'lucide-svelte'; 6 import { cubicOut } from 'svelte/easing'; 7 import { tweened } from 'svelte/motion'; 8 9 const confirm_time = 2_000; 10 11 let clicked = false; 12 const action = async () => { 13 clicked = true; 14 15 const body = new FormData(); 16 const p = fetch('?/delete_game', { method: 'POST', body }); 17 18 p.then(() => { 19 setTimeout(() => { 20 if (browser) goto('/games'); 21 }, 1000); 22 }); 23 24 promise(p, { 25 progress: 'Deleting Game...' 26 }); 27 }; 28 29 const progress = tweened(0, { 30 easing: cubicOut, 31 duration: confirm_time 32 }); 33 34 const size = 24; 35 36 let timeout: NodeJS.Timer; 37 const mousedown = () => { 38 timeout = setTimeout(action, confirm_time); 39 progress.set(1, { duration: confirm_time }); 40 }; 41 const mouseup = () => { 42 clearTimeout(timeout); 43 if (!clicked) progress.set(0, { duration: 100 }); 44 }; 45</script> 46 47<button 48 style="--s: {size}px" 49 class="group relative overflow-hidden rounded-lg bg-zinc-900 p-[calc(var(--s)/2)] text-red-400 transition hover:bg-red-500 hover:text-zinc-300" 50 on:mousedown={mousedown} 51 on:mouseup={mouseup} 52 on:mouseleave={mouseup} 53> 54 <div 55 class="absolute left-0 top-0 h-full bg-red-400" 56 style="width: calc(100% * {$progress})" 57 ></div> 58 <div 59 class="relative grid h-[--s] w-[--s] overflow-hidden transition-all group-hover:w-[calc(var(--s)*10)]" 60 > 61 <div class="flex h-[--s] w-[--s] justify-center transition group-hover:-translate-y-[100%]"> 62 <Trash2Icon /> 63 </div> 64 <div class="h-[--s] font-black uppercase transition group-hover:-translate-y-[100%]"> 65 Delete game 66 </div> 67 </div> 68</button>