project nearly finished. TODO Next : Project page and refine some text

This commit is contained in:
2023-05-29 19:50:07 +02:00
parent 3be7a4adfd
commit ff3ea2cdcd
62 changed files with 6197 additions and 1313 deletions

370
src/components/Menu.vue Normal file
View File

@@ -0,0 +1,370 @@
<script setup>
import {ref, onMounted} from 'vue'
onMounted(() => {
window.addEventListener('scroll', onScroll)
const allLinks = document.querySelectorAll('a')
for (const a of allLinks){
a.addEventListener('mouseleave', () => {
if (a.classList[1] != 'router-link-exact-active'){
a.classList.add('hover-out');
a.addEventListener('transitionend', () => {
a.classList.remove('hover-out')
}, {once : true})
}
})
}
})
const onScroll = () => {
const menu = document.querySelector(".menu")
const menuYPosition = menu.getBoundingClientRect().y
//console.log(menu)
if (menuYPosition <= 0){
document.querySelector('.nav-menu').classList.add('sticked')
}
else{
document.querySelector('.nav-menu').classList.remove('sticked')
}
}
const menuOpen = ref(false)
const liShow = ref(false)
const menuIsClosing = ref(false)
const closeMenu = () => {
menuIsClosing.value = true;
menuOpen.value = false;
const sideBarNav = document.querySelector('.nav-menu')
sideBarNav.addEventListener('transitionend', () => {
liShow.value = false
menuIsClosing.value = false;
//if menu is reopen during animation, let show all the li :
if (menuOpen.value){
liShow.value = true
}
}, {once : true})
}
const toggleMenu = () => {
menuOpen.value = !menuOpen.value;
if (menuOpen.value){
liShow.value = true
}
else{
closeMenu();
}
}
</script>
<template>
<nav class="menu-container">
<div class="burger">
<button class="button"
@click="toggleMenu()"
>
<svg class="hamburger"
v-bind:class="{open : menuOpen}"
viewBox="2 0 100 100">
<path
class="cross"
style="fill:none;
stroke-linecap:round;
stroke-linejoin:round;
stroke-opacity:1"
d="M 36,21 H 74 L 74,33 55,52 36,71 36,83 H 74 L 74,71 36,33 Z"
id="path978"
sodipodi:nodetypes="cccccccccc" />
<path
class="middle"
style="fill:none;
stroke-linecap:round;
stroke-linejoin:bevel;
stroke-opacity:1"
d="M 36,52 H 74 C 90,52 82,69 77,74 71,80 63,83 55,83 38,83 24,69 24,52 24,35 38,21 55,21 c 17,0 31,14 31,31 0,9 -3,16 -9,22"
id="path982"
sodipodi:nodetypes="cccssssc" />
</svg>
</button>
</div>
<ul class="nav-menu"
v-bind:class="{open : menuOpen}"
>
<li
class=""
v-bind:class="{show : liShow, closing : menuIsClosing}"
@click="closeMenu()">
<router-link
:to="{name:'whoAmI'}">
Who Am I
</router-link>
</li>
<li
class=""
v-bind:class="{show : liShow, closing : menuIsClosing}"
@click="closeMenu()">
<router-link
:to="{name:'technologies'}">
Technologies
</router-link>
</li>
<li
class=""
v-bind:class="{show : liShow, closing : menuIsClosing}"
@click="closeMenu()">
<router-link
:to="{name:'projects'}">
Projects
</router-link>
</li>
<li
class=""
v-bind:class="{show : liShow, closing : menuIsClosing}"
@click="closeMenu()">
<router-link
:to="{name:'networks'}">
Networks
</router-link>
</li>
<li
v-bind:class="{show : liShow, closing : menuIsClosing}"
@click="closeMenu()">
<router-link
:to="{name:'contact'}">
Contact
</router-link>
</li>
</ul>
</nav>
</template>
<style lang="scss" scoped>
@import '../style/shared.scss';
.burger{
display: none;
opacity:0;
transition:0.5s;
& .button{
width: 3.5em;
// height: 4.5em;
background-color:$red-light;
border: none;
transition:1s ;
&:hover{
cursor: pointer;
}
& .hamburger{
& .cross, & .middle {
stroke-width:7;
transition:1s ;
stroke:$white;
}
& .cross{
stroke-dashoffset: 0 ;
stroke-dasharray: 0 0 36 80 36 80;
}
& .middle{
stroke-dashoffset: 0 ;
stroke-dasharray: 36 250;
}
&.open{
& .cross{
stroke-width:7;
stroke-dashoffset: -61 ;
stroke-dasharray: 33 82 33 79;
}
& .middle{
stroke-width:7;
stroke-dashoffset: -60 ;
stroke-dasharray: 270 ;
}
}
}
}
}
ul.nav-menu{
//z-index: 999;
margin-top: 1em;
margin-bottom: 1.5em;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
background-color: rgba(0, 0, 0, 0.233);
padding:1rem 0.5rem;
//overflow: hidden;
//transition: 0.5s;
&.sticked{
background-color: black;
}
}
a{
font-size:1em;
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
font-weight: 400;
text-align: center;
color : $white;
text-decoration: none;
&::after{
content: "";
background-color: $red-light;
width: 0%;
margin-left:0;
height: 4px;
display: block;
}
&:hover, &.router-link-exact-active{
color:$red-light;
transition: color 0.25s;
cursor: pointer;
}
&.router-link-exact-active{
filter: drop-shadow(0 0 4px $red-light);
transition: filter 0.3s;
}
&:hover::after, &.router-link-exact-active::after{
width: 100%;
//This transition fires on the hover
transition: 0.25s;
}
&.hover-out::after{
margin-left:100%;
//This transition fires on hover-out class
transition:0.5s;
}
}
li {
transform: translateY(1.25em);
opacity:0;
overflow: hidden;
@for $i from 1 to 6 {
&:nth-child(#{$i}){
animation: 250ms theMenu (100 * $i - 0ms) ease forwards;
}
}
}
@media (width < 750px ){
nav.menu-container{
//border: $white solid 3px;
display: flex;
justify-content: flex-end;
& .burger{
margin-bottom: 1.5em;
display: block;
position: sticky;
top:0;
opacity: 0;
z-index:9999;
animation: burger 0.5s ease-in-out forwards;
}
& > ul.nav-menu{
position:fixed;
top:0;
bottom:0;
z-index: 99;
right:-250px;
transform: translateX(0%);
margin-top:0;
margin-bottom: 0;
width: 250px;
background: hsl(0 0% 0% / 0.95);
transition: 0.5s ease-out;
display: flex;
flex-direction: column;
align-items: flex-end;
padding-right: 1em;
text-align: right;
&.open{
transform: translateX(-100%);
}
& > li{
display: none;
opacity:0;
}
& > li.show{
display: block;
transform: translateY(1.25em);
@for $i from 1 to 6 {
&:nth-child(#{$i}){
animation: 250ms theMenu (80 * $i + 0ms) ease-out forwards;
}
}
}
& > li.closing {
transform: translateY(0em);
opacity: 1;
@for $i from 1 to 6 {
&:nth-child(#{$i}){
//animation in reverse side...
animation: 150ms closeMe ( 50ms * (5 - $i)) ease-out forwards;
}
}
}
& > li > a {
font-size: 1.25rem;
}
}
}
}
@supports (backdrop-filter: blur(0.5rem)){
nav.menu-container > ul.nav-menu{
background-color: hsla(0, 100%, 0%, 0.25);
backdrop-filter: blur(0.5rem);
/* adding backdrop-filter compatibility for firefox and safari */
-webkit-backdrop-filter: blur(0.6rem);
}
}
@media (height < 650px) and (width < 750px) {
div.menu-container .burger{
position : fixed;
top:0;
right:0;
}
}
@keyframes burger {
100%{
opacity: 1;
}
}
@keyframes theMenu{
100%{
transform: translateY(0);
opacity:1;
}
}
@keyframes closeMe{
100%{
opacity:0;
}
}
@keyframes border-hover {
0%{
border-bottom: none;
border-width: 0%;
}
100%{
border-width: 50%;
}
}
</style>