rewrite website
This commit is contained in:
		
							
								
								
									
										186
									
								
								src/app/layout/Menu.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/app/layout/Menu.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
<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 MenuAdmins from '@assets/img/menu-admins.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';
 | 
			
		||||
 | 
			
		||||
  // html bindings
 | 
			
		||||
  let navElem: HTMLDivElement;
 | 
			
		||||
 | 
			
		||||
  // states
 | 
			
		||||
  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: 'Admins',
 | 
			
		||||
      sprite: MenuAdmins.src,
 | 
			
		||||
      href: 'admins',
 | 
			
		||||
      active: false
 | 
			
		||||
    }
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  let showMenuPermanent = $state(isBrowser ? localStorage.getItem('showMenuPermanent') === 'true' : false);
 | 
			
		||||
  let isTouch = $state(false);
 | 
			
		||||
  let isOpen = $state(false);
 | 
			
		||||
  let windowHeight = $state(0);
 | 
			
		||||
 | 
			
		||||
  // lifecycle
 | 
			
		||||
  $effect(() => {
 | 
			
		||||
    localStorage.setItem('showMenuPermanent', `${showMenuPermanent}`);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  onMount(() => {
 | 
			
		||||
    updateActiveNavPath();
 | 
			
		||||
    new MutationObserver(updateActiveNavPath).observe(document.head, { childList: true });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // functions
 | 
			
		||||
  function updateActiveNavPath() {
 | 
			
		||||
    for (let i = 0; i < navPaths.length; i++) {
 | 
			
		||||
      navPaths[i].active = new URL(document.baseURI).pathname + navPaths[i].href === window.location.pathname;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</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)}
 | 
			
		||||
    role="tooltip"
 | 
			
		||||
  >
 | 
			
		||||
    <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