move components
This commit is contained in:
179
src/app/layout/Menu.svelte
Normal file
179
src/app/layout/Menu.svelte
Normal file
@ -0,0 +1,179 @@
|
||||
<script lang="ts">
|
||||
import MenuHome from '@assets/img/menu-home.webp';
|
||||
import MenuSignup from '@assets/img/menu-signup.webp';
|
||||
import MenuRules from '@assets/img/menu-rules.webp';
|
||||
import MenuFaq from '@assets/img/menu-faq.webp';
|
||||
import MenuFeedback from '@assets/img/menu-feedback.webp';
|
||||
import MenuTeam from '@assets/img/menu-team.webp';
|
||||
import MenuButton from '@assets/img/menu-button.webp';
|
||||
import MenuInventoryBar from '@assets/img/menu-inventory-bar.webp';
|
||||
import MenuSelectedFrame from '@assets/img/menu-selected-frame.webp';
|
||||
import { isBrowser } from '@antfu/utils';
|
||||
import { navigate } from 'astro:transitions/client';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let navPaths = $state([
|
||||
{
|
||||
name: 'Startseite',
|
||||
sprite: MenuHome.src,
|
||||
href: ``,
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'Registrieren',
|
||||
sprite: MenuSignup.src,
|
||||
href: 'signup',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'Regeln',
|
||||
sprite: MenuRules.src,
|
||||
href: 'rules',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'FAQ',
|
||||
sprite: MenuFaq.src,
|
||||
href: 'faq',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'Feedback & Kontakt',
|
||||
sprite: MenuFeedback.src,
|
||||
href: 'feedback',
|
||||
active: false
|
||||
},
|
||||
{
|
||||
name: 'Team',
|
||||
sprite: MenuTeam.src,
|
||||
href: 'team',
|
||||
active: false
|
||||
}
|
||||
]);
|
||||
|
||||
let showMenuPermanent = $state(isBrowser ? localStorage.getItem('showMenuPermanent') === 'true' : false);
|
||||
let isTouch = $state(false);
|
||||
let isOpen = $state(false);
|
||||
let windowHeight = $state(0);
|
||||
|
||||
$effect(() => {
|
||||
localStorage.setItem('showMenuPermanent', `${showMenuPermanent}`);
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
new MutationObserver(() => {
|
||||
for (let i = 0; i < navPaths.length; i++) {
|
||||
console.log(navPaths[i].href, window.location.pathname);
|
||||
navPaths[i].active = new URL(navPaths[i].href).pathname === window.location.pathname;
|
||||
}
|
||||
}).observe(document.head, { childList: true });
|
||||
});
|
||||
|
||||
let navElem: HTMLDivElement;
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerHeight={windowHeight} />
|
||||
<svelte:body
|
||||
ontouchend={(e) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
if (isTouch && !navElem.contains(e.target)) showMenuPermanent = false;
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
class="fixed bottom-4 right-4 sm:left-4 sm:right-[initial] group/menu-bar flex flex-col-reverse justify-center items-center z-50 main-menu"
|
||||
bind:this={navElem}
|
||||
>
|
||||
<button
|
||||
class={isTouch ? 'btn btn-square relative w-16 h-16' : 'btn btn-square group/menu-button relative w-16 h-16'}
|
||||
onclick={() => {
|
||||
if (!isTouch) {
|
||||
let activePath = navPaths.find((path) => path.active);
|
||||
if (activePath !== undefined) {
|
||||
navigate(activePath.href);
|
||||
}
|
||||
showMenuPermanent = !showMenuPermanent;
|
||||
}
|
||||
}}
|
||||
ontouchend={() => {
|
||||
isTouch = true;
|
||||
showMenuPermanent = !showMenuPermanent;
|
||||
}}
|
||||
>
|
||||
<img class="absolute w-full h-full p-1 pixelated" src={MenuButton.src} 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={isOpen || (isTouch && showMenuPermanent)}
|
||||
src={MenuSelectedFrame.src}
|
||||
alt="menu hover"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class:hidden={!(isOpen || showMenuPermanent)}
|
||||
class={isTouch ? 'pb-3' : 'group-hover/menu-bar:block pb-3'}
|
||||
onmouseenter={() => (isOpen = true)}
|
||||
onmouseleave={() => (isOpen = false)}
|
||||
>
|
||||
<ul class="bg-base-200 rounded">
|
||||
{#each navPaths as navPath, i (navPath.href)}
|
||||
<li
|
||||
class="flex justify-center tooltip"
|
||||
class:tooltip-left={windowHeight > 450}
|
||||
class:sm:tooltip-right={windowHeight > 450}
|
||||
class:tooltip-top={windowHeight <= 450}
|
||||
class:tooltip-open={isTouch || windowHeight <= 450}
|
||||
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}
|
||||
onclick={() => navigate(navPath.href)}
|
||||
>
|
||||
<div
|
||||
style="background-image: url({MenuInventoryBar.src}); background-position: -{i * 3.5}rem 0;"
|
||||
class="block w-full h-full bg-no-repeat bg-horizontal-sprite pixelated"
|
||||
></div>
|
||||
<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={MenuSelectedFrame.src}
|
||||
alt="menu hover"
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@media (max-height: 450px) {
|
||||
.main-menu {
|
||||
flex-direction: row;
|
||||
}
|
||||
.main-menu > div {
|
||||
padding: 0.25rem 0 0 0.5rem;
|
||||
}
|
||||
.main-menu li {
|
||||
display: inline-block;
|
||||
|
||||
&::before {
|
||||
transform-origin: 0;
|
||||
transform: rotate(-90deg);
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pixelated {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.bg-horizontal-sprite {
|
||||
background-size: auto 100%;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user