436 lines
11 KiB
Vue
436 lines
11 KiB
Vue
<template>
|
|
<div
|
|
class="navigationBox"
|
|
:class="[
|
|
isMenuOpen ? 'menu-active' : '',
|
|
screenWidth < 1350 ? 'mobile' : 'desk'
|
|
]"
|
|
role="navigation"
|
|
aria-label="Hauptnavigation"
|
|
tabindex="0"
|
|
>
|
|
<div
|
|
class="closer"
|
|
role="button"
|
|
tabindex="0"
|
|
aria-label="Navigation schließen"
|
|
@click="toggleMenu"
|
|
@keydown.enter="toggleMenu"
|
|
/>
|
|
|
|
<nav
|
|
v-if="isMenuOpen || screenWidth > 1350"
|
|
:aria-expanded="screenWidth < 1350 ? 'true' : undefined"
|
|
@mouseleave="screenWidth >= 1350 && hideSubNav()"
|
|
>
|
|
|
|
<!-- <div class="mobilNavLogo">
|
|
<NuxtImg
|
|
v-if="screenWidth < 1350"
|
|
provider="strapi"
|
|
src="/uploads/DML_Logo_mint_negative_2024_9257db5430.svg"
|
|
alt="digimedialoop Logo"
|
|
width="120"
|
|
/>
|
|
</div> -->
|
|
|
|
<span
|
|
v-for="link in navigationLinks"
|
|
:key="link.routeKey"
|
|
class="main-nav-item"
|
|
@mouseenter="screenWidth >= 1350 && showSubNav(link.routeKey)"
|
|
@mouseleave="screenWidth >= 1350 && hideSubNav(link.routeKey)"
|
|
>
|
|
<NuxtLinkLocale
|
|
:to="link.routeKey"
|
|
class="main-nav-link"
|
|
:aria-haspopup="link.subNav && link.subNav.length > 0 ? 'true' : undefined"
|
|
:aria-expanded="isSubNavOpen === link.routeKey ? 'true' : 'false'"
|
|
@click="handleMobileClose"
|
|
>
|
|
{{ $t(link.label) }}
|
|
</NuxtLinkLocale>
|
|
|
|
<!-- PFEIL FÜR MOBILE UND TOGGLE -->
|
|
<button
|
|
v-if="link.subNav && link.subNav.length > 0 && screenWidth < 1350"
|
|
class="submenu-toggle"
|
|
@click.prevent="toggleMobileSubNav(link.routeKey)"
|
|
:aria-expanded="isMobileSubNavOpen === link.routeKey ? 'true' : 'false'"
|
|
aria-label="Untermenü öffnen/schließen"
|
|
>
|
|
<svg
|
|
:class="{ 'open': isMobileSubNavOpen === link.routeKey }"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="12"
|
|
height="8"
|
|
viewBox="0 0 12 8"
|
|
fill="none"
|
|
>
|
|
<path d="M1 1L6 6L11 1" stroke="currentColor" stroke-width="2"/>
|
|
</svg>
|
|
</button>
|
|
|
|
<!-- SUBNAVIGATION -->
|
|
<ul
|
|
v-if="link.subNav && link.subNav.length > 0"
|
|
v-show="(screenWidth >= 1350 && isSubNavOpen === link.routeKey) || (screenWidth < 1350 && isMobileSubNavOpen === link.routeKey)"
|
|
class="sub-nav"
|
|
>
|
|
<li v-for="subLink in link.subNav" :key="subLink.routeKey" class="sub-nav-item">
|
|
<NuxtLinkLocale
|
|
:to="subLink.routeKey"
|
|
class="sub-nav-link"
|
|
@click="handleMobileClose"
|
|
>
|
|
{{ $t(subLink.label) }}
|
|
</NuxtLinkLocale>
|
|
</li>
|
|
</ul>
|
|
</span>
|
|
|
|
|
|
<a
|
|
class="menu_link" href="#"
|
|
role="button"
|
|
aria-label="Kontaktformular öffnen"
|
|
@click="toggleContactBubble"
|
|
>
|
|
{{ $t('contact') }}
|
|
</a>
|
|
<SettingsPanel v-if="screenWidth < 1350" />
|
|
</nav>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from 'vue'
|
|
import { useMainStore } from '@/stores/main'
|
|
const mainStore = useMainStore()
|
|
|
|
const screenWidth = computed(() => mainStore.screenWidth)
|
|
const scrollPosition = computed(() => mainStore.scrollPosition)
|
|
|
|
const isSubNavOpen = ref(null) // speichert, welches Submenü auf Desktop offen ist
|
|
const isMobileSubNavOpen = ref(null) // Trackt, welches Submenü auf Mobile offen ist
|
|
|
|
function toggleMobileSubNav(routeKey) {
|
|
if (screenWidth.value < 1350) {
|
|
isMobileSubNavOpen.value = isMobileSubNavOpen.value === routeKey ? null : routeKey
|
|
}
|
|
}
|
|
|
|
// Funktionen zum Öffnen und Schließen der Subnavigation auf Desktop
|
|
function showSubNav(routeKey) {
|
|
isSubNavOpen.value = routeKey
|
|
}
|
|
function hideSubNav(routeKey) {
|
|
if (isSubNavOpen.value === routeKey) {
|
|
isSubNavOpen.value = null
|
|
}
|
|
}
|
|
|
|
const isMenuOpen = computed(() => mainStore.menuOpen)
|
|
const toggleMenu = () => mainStore.toggleMenu()
|
|
|
|
const toggleContactBubble = () => mainStore.toggleContactBubble()
|
|
|
|
const handleMobileClose = () => {
|
|
if (screenWidth.value < 1350 && isMenuOpen.value) {
|
|
toggleMenu()
|
|
} else {
|
|
hideSubNav()
|
|
}
|
|
}
|
|
|
|
const navigationLinks = [
|
|
{
|
|
routeKey: 'webagency',
|
|
label: 'webagency'
|
|
},
|
|
{
|
|
routeKey: '',
|
|
label: 'services',
|
|
subNav: [
|
|
{ routeKey: 'services-cms', label: 'menuCms' },
|
|
{ routeKey: 'services-seo', label: 'menuSEO' },
|
|
{ routeKey: 'services-accessibility', label: 'menuAccessibility' },
|
|
{ routeKey: 'services-ai', label: 'menuAi' },
|
|
]
|
|
},
|
|
{
|
|
routeKey: '',
|
|
label: 'sectors',
|
|
subNav: [
|
|
{ routeKey: 'sectors-schools', label: 'menuSchools' },
|
|
{ routeKey: 'sectors-film', label: 'menuFilm' }
|
|
]
|
|
},
|
|
{ routeKey: 'references', label: 'references' }
|
|
]
|
|
</script>
|
|
|
|
<style lang="sass">
|
|
.navigationBox
|
|
position: relative
|
|
display: flex
|
|
align-items: center
|
|
justify-content: flex-end
|
|
width: 80%
|
|
transition: .8s
|
|
margin-top: 1.2rem // -1rem
|
|
|
|
nav
|
|
display: block
|
|
z-index: 102
|
|
//background: linear-gradient(to right, rgba($lightgrey, 0.8), rgba(white, 0.9), rgba(white, 0.9))
|
|
background: white
|
|
border: 1px solid adjust-color($beige, $lightness: 5%)
|
|
padding: 1rem 2rem
|
|
text-align: center
|
|
border-radius: 1rem
|
|
margin: 4.8rem 1rem 0 1rem
|
|
transition: .8s
|
|
|
|
a
|
|
margin: 0 1.2rem
|
|
text-decoration: none
|
|
color: $darkgrey
|
|
text-transform: uppercase
|
|
font-family: 'Comfortaa-Bold'
|
|
font-size: 1.1rem
|
|
letter-spacing: .05rem
|
|
transition: .6s
|
|
display: inline-block
|
|
|
|
&:hover
|
|
transform: scale(1.15)
|
|
background-image: radial-gradient(rgba(white, .5), rgba(white, .1))
|
|
box-shadow: 0 0 10px 10px rgba(white, 0.2)
|
|
border-radius: 10px
|
|
|
|
&.desk
|
|
.sub-nav
|
|
display: block
|
|
position: absolute
|
|
top: 3rem
|
|
right: 5%
|
|
background-color: rgba(white, .95)
|
|
padding: 2rem 2rem 1rem 2rem
|
|
text-align: left
|
|
cursor: pointer
|
|
border-bottom-left-radius: 1rem
|
|
border-bottom-right-radius: 1rem
|
|
list-style: none
|
|
|
|
.sub-nav-item
|
|
padding: 0 0 1.5rem 0
|
|
|
|
.sub-nav-link
|
|
position: relative
|
|
margin-left: 1.2rem
|
|
|
|
&::before
|
|
content: ''
|
|
width: .5rem
|
|
height: .4rem
|
|
background-color: rgba($primaryColor, .9)
|
|
border-radius: $loopShape
|
|
position: absolute
|
|
top: .4rem
|
|
left: -1.3rem
|
|
border-radius: 20px
|
|
|
|
&:hover
|
|
transform: scale(1.025)
|
|
|
|
&.mobile
|
|
top: 0
|
|
|
|
&.navigationBox
|
|
display: block
|
|
position: relative
|
|
background-color: $darkgrey
|
|
width: 4rem
|
|
height: 4rem
|
|
z-index: 8
|
|
border-radius: 50%
|
|
margin-right: 5vw
|
|
margin-top: 2rem
|
|
|
|
.closer
|
|
position: relative
|
|
width: 100%
|
|
height: 4rem
|
|
|
|
&::after, &::before
|
|
position: absolute
|
|
content: ''
|
|
width: 2rem
|
|
z-index: 12
|
|
height: 5px
|
|
border-radius: 4px
|
|
background-color: white
|
|
right: 75%
|
|
transform: translateX(100%)
|
|
transition: .8s
|
|
|
|
&::before
|
|
top: 35%
|
|
|
|
&::after
|
|
top: 55%
|
|
|
|
nav
|
|
display: none
|
|
background-image: none
|
|
background: transparent
|
|
border: none
|
|
padding-top: 0rem !important
|
|
|
|
.submenu-toggle
|
|
background: none
|
|
border: none
|
|
padding: 0 0 0 0.5rem
|
|
margin-top: -1rem
|
|
cursor: pointer
|
|
display: inline-flex
|
|
align-items: center
|
|
color: white
|
|
transition: transform 0.3s ease
|
|
|
|
svg
|
|
transition: transform 0.3s ease
|
|
|
|
&.open svg,
|
|
svg.open
|
|
transform: rotate(180deg) // Pfeil zeigt nach oben, wenn offen
|
|
|
|
.sub-nav
|
|
overflow: hidden
|
|
max-height: 0
|
|
opacity: 0
|
|
transition: max-height 0.4s ease, opacity 0.4s ease
|
|
|
|
&.open
|
|
max-height: 500px
|
|
opacity: 1
|
|
|
|
.sub-nav
|
|
list-style: none
|
|
padding-left: 1.8rem
|
|
margin: 0
|
|
|
|
.sub-nav-item
|
|
padding-left: 1rem
|
|
margin-bottom: 0.2rem
|
|
|
|
.sub-nav-link
|
|
color: white
|
|
font-size: 1rem !important
|
|
line-height: 1.5rem
|
|
padding: 0.5rem 1.5rem
|
|
|
|
&:hover
|
|
|
|
&::before
|
|
content: ''
|
|
width: .5rem
|
|
height: .4rem
|
|
background-color: rgba($primaryColor, .9)
|
|
border-radius: $loopShape
|
|
position: absolute
|
|
top: 1rem
|
|
left: 0
|
|
border-radius: 20px
|
|
|
|
.menu_link
|
|
margin-left: 1.5rem
|
|
transition: .8s
|
|
|
|
&:hover
|
|
transform: scale(1.06)
|
|
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
|
|
box-shadow: 0 0 0 0 transparent
|
|
border-radius: 20px
|
|
|
|
a, .menu_link
|
|
display: block
|
|
color: white
|
|
text-align: left
|
|
margin-bottom: .2rem
|
|
padding: 1rem 2.8rem .5rem 1.2rem
|
|
position: relative
|
|
font-size: 1.25rem !important
|
|
width: auto
|
|
max-width: 18rem
|
|
text-transform: uppercase
|
|
font-family: 'Mainfont-Bold'
|
|
|
|
&::before
|
|
content: ''
|
|
width: .8rem
|
|
height: .6rem
|
|
background-color: rgba($primaryColor, .9)
|
|
border-radius: $loopShape
|
|
position: absolute
|
|
top: 1.5rem
|
|
left: -.5rem
|
|
border-radius: 20px
|
|
|
|
&:hover
|
|
transform: scale(1.06)
|
|
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
|
|
box-shadow: 0 0 0 0 transparent
|
|
border-radius: 20px
|
|
|
|
&.menu-active
|
|
width: 100vw
|
|
height: 98vh
|
|
border-radius: 5px
|
|
margin: 0
|
|
background-color: rgba($darkgrey, .97)
|
|
|
|
.closer
|
|
&::before, &::after
|
|
top: 2rem
|
|
right: 2rem
|
|
|
|
&::before
|
|
transform: rotate(45deg)
|
|
|
|
&::after
|
|
transform: rotate(-45deg)
|
|
|
|
nav
|
|
display: block
|
|
padding: 10vh 0
|
|
margin: 0 5vw
|
|
|
|
.navigationBox
|
|
margin-top: .5rem
|
|
|
|
nav
|
|
display: flex
|
|
margin: 2.5rem 0 0 0
|
|
padding: 1rem .5rem
|
|
border-top-right-radius: 0
|
|
border-top-left-radius: 0
|
|
border-bottom-left-radius: 50px
|
|
border-bottom-right-radius: 0
|
|
background: transparent
|
|
border: 1px solid transparent
|
|
|
|
a
|
|
font-size: 1rem
|
|
font-weight: bold
|
|
margin: 0 .8rem
|
|
|
|
&.desk
|
|
.sub-nav
|
|
top: 1.5rem
|
|
right: 2%
|
|
background-color: transparent
|
|
background-image: linear-gradient(to bottom, transparent 0%, white 15%)
|
|
|
|
</style> |