375 lines
8.1 KiB
Vue
375 lines
8.1 KiB
Vue
<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:'profile'}">
|
|
Profile
|
|
</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/colors.scss';
|
|
|
|
.burger{
|
|
display: none;
|
|
opacity:0;
|
|
transition:0.5s;
|
|
& .button{
|
|
width: 3.5em;
|
|
// height: 4.5em;
|
|
background-color:$action-normal;
|
|
border: none;
|
|
transition:1s ;
|
|
&:hover{
|
|
cursor: pointer;
|
|
}
|
|
& .hamburger{
|
|
& .cross, & .middle {
|
|
stroke-width:7;
|
|
transition:1s ;
|
|
-moz-transition:1s ;
|
|
-webkit-transition:1s ;
|
|
stroke:black;
|
|
}
|
|
& .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: 'acme', Arial, Helvetica, sans-serif;
|
|
//font-style: italic;
|
|
font-weight: 400;
|
|
text-align: center;
|
|
color : $main-normal;
|
|
text-decoration: none;
|
|
&::after{
|
|
content: "";
|
|
background-color: $action-normal;
|
|
width: 0%;
|
|
margin-left:0;
|
|
height: 4px;
|
|
display: block;
|
|
}
|
|
|
|
&:hover, &.router-link-exact-active{
|
|
color:$action-normal;
|
|
transition: color 0.25s;
|
|
cursor: pointer;
|
|
}
|
|
&.router-link-exact-active{
|
|
filter: drop-shadow(0 0 3px $action-normal);
|
|
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 {
|
|
padding: 0 0.3em;
|
|
transform: translateY(1.25em);
|
|
opacity:0;
|
|
overflow: hidden;
|
|
font-style: italic;
|
|
@for $i from 1 to 6 {
|
|
&:nth-child(#{$i}){
|
|
animation: 250ms theMenu (100 * $i - 0ms) ease forwards;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@media (width < 750px ){
|
|
nav.menu-container{
|
|
//border: $main-normal 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) {
|
|
nav.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> |