<script lang="ts"> import '../app.css'; import { env } from '$env/dynamic/public'; import { goto } from '$app/navigation'; import Settings from './Settings.svelte'; import { playAudio } from '$lib/stores'; import { page } from '$app/stores'; let navPaths = [ { name: 'Startseite', sprite: `${env.PUBLIC_BASE_PATH}/img/menu-home.png`, href: `${env.PUBLIC_BASE_PATH}/`, active: false }, { name: 'Registrieren', sprite: `${env.PUBLIC_BASE_PATH}/img/menu-register.png`, href: `${env.PUBLIC_BASE_PATH}/register`, active: false }, { name: 'Regeln', sprite: `${env.PUBLIC_BASE_PATH}/img/menu-rules.png`, href: `${env.PUBLIC_BASE_PATH}/rules`, active: false } ]; let showMenuPermanent = false; let menuButtonScrollIndex: number | null = null; function onMenuButtonScroll(e: WheelEvent) { if (menuButtonScrollIndex == null) { if (e.deltaY < 0) { menuButtonScrollIndex = navPaths.length - 1; } else if (e.deltaY > 0) { menuButtonScrollIndex = 0; } else { menuButtonScrollIndex = navPaths.length - 1; } } else { navPaths[menuButtonScrollIndex].active = false; if (e.deltaY > 0) { menuButtonScrollIndex++; } else if (e.deltaY < 0) { menuButtonScrollIndex--; } if (menuButtonScrollIndex > navPaths.length - 1) { menuButtonScrollIndex = 0; } else if (menuButtonScrollIndex < 0) { menuButtonScrollIndex = navPaths.length - 1; } } navPaths[menuButtonScrollIndex].active = true; } let onAdminPage = false; $: onAdminPage = $page.url.pathname.startsWith(`${env.PUBLIC_BASE_PATH}/admin`) && $page.url.pathname !== `${env.PUBLIC_BASE_PATH}/admin/login`; let isTouch = false; let nav: HTMLDivElement; let settings: HTMLDialogElement; </script> <svelte:body on:keyup={(e) => { if (e.key === 'Escape') { e.preventDefault(); if (settings.open) { settings.close(); } else { settings.show(); } } }} on:touchend={(e) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore if (isTouch && !nav.contains(e.target)) showMenuPermanent = false; }} /> <main> <div class="h-screen w-full"> <slot /> </div> </main> <nav> <div class="fixed bottom-4 right-4 sm:left-4 sm:right-[initial] group/menu-bar flex flex-col-reverse justify-center items-center" class:hidden={onAdminPage} bind:this={nav} > <button class={isTouch ? 'btn btn-square relative w-16 h-16' : 'btn btn-square group/menu-button relative w-16 h-16'} on:click={() => { if (!isTouch) { let activePath = navPaths.find((path) => path.active); if (activePath !== undefined) { goto(activePath.href); } else if ($playAudio) { new Audio( `${env.PUBLIC_BASE_PATH}/aud/chest-${showMenuPermanent ? 'close' : 'open'}.mp3` ).play(); } showMenuPermanent = !showMenuPermanent; } }} on:touchend={() => { isTouch = true; showMenuPermanent = !showMenuPermanent; }} on:mouseleave={() => { if (menuButtonScrollIndex !== null) { navPaths[menuButtonScrollIndex].active = false; } menuButtonScrollIndex = null; }} on:wheel|preventDefault={onMenuButtonScroll} > <img class="absolute w-full h-full p-1 pixelated" src="{env.PUBLIC_BASE_PATH}/img/menu-button.png" alt="menu" /> <img class="opacity-0 transition-opacity delay-50 group-hover/menu-button:opacity-100 absolute w-full h-full p-[3px] pixelated" class:opacity-100={isTouch && showMenuPermanent} src="{env.PUBLIC_BASE_PATH}/img/selected-frame.png" alt="menu hover" /> </button> <div class:hidden={!showMenuPermanent} class={isTouch ? 'pb-3' : 'group-hover/menu-bar:block pb-3'} > <ul class="flex flex-col bg-base-200 rounded"> {#each navPaths as navPath, i} <li class="flex justify-center tooltip tooltip-left sm:tooltip-right" data-tip={navPath.name} > <a class="btn btn-square border-none group/menu-item relative w-[3.5rem] h-[3.5rem] flex justify-center items-center" href={navPath.href} > <div style="background-image: url('{env.PUBLIC_BASE_PATH}/img/menu-inventory-bar.png'); background-position: -{i * 3.5}rem 0;" class="block w-full h-full bg-no-repeat bg-horizontal-sprite pixelated" /> <div class="absolute flex justify-center items-center w-full h-full"> <img class="w-1/2 h-1/2 pixelated" src={navPath.sprite} alt={navPath.name} /> </div> <img class="transition-opacity delay-50 group-hover/menu-item:opacity-100 absolute w-full h-full pixelated scale-110 z-10" class:opacity-0={!navPath.active} src="{env.PUBLIC_BASE_PATH}/img/selected-frame.png" alt="menu hover" /> </a> </li> {/each} </ul> </div> </div> </nav> <dialog class="modal" bind:this={settings}> <form method="dialog" class="modal-box" style="overflow: unset"> <button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button> <Settings /> </form> <form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]"> <button>close</button> </form> </dialog>