Files
wm-AllKids-tibi2023/frontend/src/lib/components/header/mobile.svelte
robin 0bb518341d
All checks were successful
deploy to production / deploy (push) Successful in 1m6s
SSR
2023-12-06 20:22:56 +00:00

431 lines
17 KiB
Svelte

<script lang="ts">
import { navigation, refresh, sites } from "../../stores"
import { onMount } from "svelte"
import { apiBaseURL } from "../../../config"
import { navigate } from "svelte-routing"
export let show = false
let images: HTMLImageElement[] = []
function changeStateOfSite(menuOn: boolean) {
let element = document.getElementById("menu") as HTMLElement
element.classList.toggle("show-menu")
show = !show
let body = document.body
if (menuOn) {
body.style.overflow = "initial"
} else {
body.style.overflow = "hidden"
}
let button = document.getElementsByClassName("button-three")[0]
const currentState = button.getAttribute("data-state")
if (!currentState || currentState === "closed") {
button.setAttribute("data-state", "opened")
button.setAttribute("aria-expanded", "true")
} else {
button.setAttribute("data-state", "closed")
button.setAttribute("aria-expanded", "false")
}
}
function imageSlide(images: HTMLImageElement[]) {
let currentImage = 0
images[0].classList.add("show-img")
if (typeof window !== "undefined") {
let interval = setInterval(() => {
images[currentImage].classList.remove("show-img")
currentImage += 1
if (images.length == currentImage) currentImage = 0
images[currentImage].classList.add("show-img")
}, 4000)
return () => clearInterval(interval)
}
}
function pushImages(node: HTMLImageElement) {
images[0] = node
}
$: {
if (typeof window !== "undefined") {
const images = Array.from(document.getElementsByClassName("img-menu")) as HTMLImageElement[]
if (images.length !== 0) {
imageSlide(images)
}
}
}
function stretchText() {
let container = document.getElementById("logo-container")
let textElement = document.getElementById("upper")
if (!textElement) return
if (!container) return
let containerWidth = container.offsetWidth
let textWidth = textElement.offsetWidth
let currentLetterSpacing = parseFloat(
window.getComputedStyle(textElement, null).getPropertyValue("letter-spacing")
)
let characterCount = textElement.textContent.length - 1
let spaceNeeded = containerWidth - textWidth
if (characterCount > 0 && spaceNeeded > 0) {
const additionalLetterSpacing = spaceNeeded / characterCount
const newLetterSpacing = additionalLetterSpacing
textElement.style.letterSpacing = `${newLetterSpacing}px`
}
// Do the same for "lower"
textElement = document.getElementById("lower")
textWidth = textElement.offsetWidth
currentLetterSpacing = parseFloat(window.getComputedStyle(textElement, null).getPropertyValue("letter-spacing"))
characterCount = textElement.textContent.length - 1
spaceNeeded = containerWidth - textWidth
console.log(containerWidth, textWidth, characterCount)
if (characterCount > 0 && spaceNeeded > 0) {
const additionalLetterSpacing = spaceNeeded / characterCount
const newLetterSpacing = additionalLetterSpacing
textElement.style.letterSpacing = `${newLetterSpacing}px`
}
}
if (typeof window !== "undefined") {
window.addEventListener("resize", stretchText)
onMount(stretchText)
}
// test
</script>
<ul>
<div class="header">
<button
class="logo-container"
on:click="{() => {
navigate('/')
$refresh = !$refresh
}}"
>
<button class="img-logo-container">
<img src="/media/MädchenmitBlume.svg" alt="logo" />
</button>
<div class="logo-text" id="logo-container">
<div id="upper">all kids</div>
<div id="lower">SO GÜNSTIG WIE NACHHALTIG</div>
</div>
<button class="img-logo-container">
<img src="/media/Radfahrer.svg" alt="logo" />
</button>
</button>
<button
class="button-three"
on:click="{(e) => {
let element = document?.getElementById('menu')
if (element) changeStateOfSite(element.classList.contains('show-menu'))
}}"
aria-controls="primary-navigation"
aria-expanded="false"
>
<svg stroke="var(--button-color)" fill="none" class="hamburger" viewBox="-10 -10 120 120" width="45">
<path
class="line"
stroke-width="10"
stroke-linecap="round"
stroke-linejoin="round"
d="m 20 40 h 60 a 1 1 0 0 1 0 20 h -60 a 1 1 0 0 1 0 -40 h 30 v 70"
>
</path>
</svg>
</button>
</div>
<div class="menu-container" id="menu">
{#if $navigation?.elemente}
<div class="inner-container">
<div class="higher-absolute">
{#each $navigation.elemente as link, i (i)}
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<li
class="menu"
on:mousedown|stopPropagation="{(e) => {
if (link.endpoint) {
navigate(`${$sites[link.seite ?? '']?.path}`)
let element = document.getElementById('menu')
if (element) changeStateOfSite(element.classList.contains('show-menu'))
$refresh = !$refresh
return
}
let element = e.currentTarget
if (element) {
element.classList.toggle('active')
let chevronContainer = document.getElementById('chevron-' + i)
if (chevronContainer)
// @ts-ignore
chevronContainer.src = // @ts-ignore
chevronContainer.src.split('/')?.pop() == 'chevron-down.png'
? 'media/chevron-up.png'
: 'media/chevron-down.png'
}
}}"
>
<div class="menu-point">
<div>{link?.name}</div>
<div class:hidden="{link?.endpoint}">
<img id="{`chevron-${i}`}" src="media/chevron-down.png" alt="chev" />
</div>
</div>
{#if !link?.endpoint}
<ul class="submenu">
{#each link.elemente ?? [] as submenu, i (i)}
<li>
<button
on:mousedown="{(e) => {
navigate(`${$sites[submenu.seite ?? '']?.path}`)
let element = document.getElementById('menu')
if (element)
changeStateOfSite(element.classList.contains('show-menu'))
$refresh = !$refresh
}}">{submenu.name}</button
>
</li>
{/each}
</ul>
{/if}
</li>
{/each}
<button class="socials">
<a target="_blank" href="https://www.facebook.com/allkids.erfurt/">
<svg
width="36"
height="36"
viewBox="0 0 36 36"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18 3.06c-8.25 0-15 6.735-15 15.03 0 7.5 5.49 13.725 12.66 14.85v-10.5h-3.81v-4.35h3.81v-3.315c0-3.765 2.235-5.835 5.67-5.835 1.635 0 3.345.285 3.345.285v3.705h-1.89c-1.86 0-2.445 1.155-2.445 2.34v2.82h4.17l-.675 4.35H20.34v10.5A15 15 0 0 0 33 18.09c0-8.295-6.75-15.03-15-15.03z"
fill="#fff"></path>
</svg>
</a>
</button>
</div>
<div class="img-container">
<div class="img-relative">
{#each $navigation.elemente?.map((e) => e.image?.src) as imgSrc, i (i)}
{#if imgSrc != undefined}
<div>
<img
use:pushImages
src="{`${apiBaseURL}navigation/${$navigation.id}/${imgSrc}?filter=${
window?.innerWidth > 500 ? 'xl' : 'm'
}`}"
alt="img"
class="img img-menu"
/>
</div>
{/if}
{/each}
</div>
</div>
</div>
{/if}
</div>
</ul>
<style lang="less" global>
@import "../../assets/css/variables.less";
@desktop: ~"only screen and (min-width: 1440px)";
@media @tablet {
.socials {
display: none;
}
}
@media @mobile {
nav {
.hidden {
visibility: hidden;
}
position: relative;
width: 100%;
height: 100vh;
ul {
.header {
padding: 0px min(4.5vw, 100px);
display: flex;
align-items: center;
justify-content: space-between;
height: 105px;
.button-three {
--button-color: var(--hover-color);
overflow: hidden;
background: transparent;
}
.button-three .hamburger {
transition: translate 400ms, rotate 400ms;
}
.button-three[aria-expanded="true"] .hamburger {
translate: 1px -1px;
rotate: 0.125turn;
}
.button-three .line {
transition: 1s;
stroke-dasharray: 60 31 60 300;
}
.button-three[aria-expanded="true"] .line {
stroke-dasharray: 60 105 60 300;
stroke-dashoffset: -90;
}
.logo-container {
height: 38px;
display: flex;
align-items: center;
margin-top: -15px;
.logo-text {
padding: 0px 5px;
width: 200px;
p {
white-space: nowrap;
text-align: left;
}
& > #upper {
font-family: "Dekko" !important;
font-size: 42px;
font-weight: 700;
word-spacing: 5px;
letter-spacing: 4px;
color: rgb(184, 16, 16);
}
& > #lower {
font-size: 10px;
letter-spacing: 0.4px;
margin-top: -15px;
font-weight: bold;
color: orange;
font-family: "Grandstander" !important;
}
font-weight: bold;
font-size: 1.2rem;
padding-left: 10px;
}
.img-logo-container {
height: 100%;
position: relative;
top: 15px;
img {
height: 100%;
width: auto;
object-fit: contain;
}
}
}
}
.img-container {
position: absolute;
bottom: 5px;
width: 100%;
left: 0px;
height: calc((105vw / 16) * 9);
padding: 0px min(4.5vw, 100px);
.img-relative {
position: relative;
height: 100%;
width: 100%;
div {
position: absolute;
height: 100%;
width: 100%;
.show-img {
visibility: visible !important;
opacity: 1;
}
img {
opacity: 0;
height: 100%;
width: 100%;
object-fit: cover;
}
}
}
}
.menu-container {
background-color: var(--background-color);
position: absolute;
z-index: 2000;
opacity: 0;
top: 105px;
height: calc(100vh - 105px);
width: 100%;
left: -100vw;
overflow: scroll;
.inner-container {
position: relative;
height: 100%;
.menu {
padding: 10px;
border-radius: 10px;
}
.higher-absolute {
position: absolute;
z-index: 2000;
width: 100%;
left: 0px;
padding: 0px min(4.5vw, 100px);
background-color: var(--background-color);
border-radius: 0px 0px 10px 10px;
}
.socials {
width: 100%;
background-color: var(--link-font-color);
height: 50px;
border-radius: 20px;
color: var(--background-color);
}
.active {
background-color: var(--normal-font-color-12) !important;
.submenu {
visibility: visible;
max-height: 250px;
}
}
li {
padding: 6px 0px;
margin: 2px 0px;
margin-left: 5px !important;
button {
height: 100%;
width: 100%;
text-align: start;
}
.menu-point {
display: flex;
justify-content: space-between;
}
div {
font-weight: bold;
}
.submenu {
visibility: hidden;
max-height: 0px;
overflow: hidden;
}
}
}
}
.show-menu {
left: 0vw;
opacity: 1;
}
}
}
}
</style>