131 lines
No EOL
5.1 KiB
Text
131 lines
No EOL
5.1 KiB
Text
---
|
|
import Button from '@components/base/Button.astro';
|
|
import MobileMenu from './MobileMenu.astro';
|
|
|
|
const currentPath = Astro.url.pathname;
|
|
const cleanPath = currentPath.replace(/\/$/, "") || "/";
|
|
const baseLinks = [
|
|
{ text: "Услуги", href: "/services" },
|
|
{ text: "Автопарк", href: "/cars" },
|
|
{ text: "Проекты", href: "/projects" },
|
|
{ text: "Контакты", href: "/contacts" },
|
|
];
|
|
const navLinks = cleanPath !== "/" ? [{ text: "Главная", href: "/" }, ...baseLinks] : baseLinks;
|
|
---
|
|
|
|
<div id="main-header" class="sticky top-0 z-[100] w-full border-b border-[#393328] bg-[#181611]">
|
|
<div class="layout-container flex justify-center w-full">
|
|
<div class="layout-content-container flex flex-col max-w-[1440px] mx-auto w-full px-4 md:px-10">
|
|
<header class="flex items-center justify-between py-4 relative">
|
|
|
|
<!-- Логотип основного хедера -->
|
|
<a href="/" class="flex items-center gap-4 text-white group relative z-10">
|
|
<div class="size-10 bg-primary/20 rounded flex items-center justify-center">
|
|
<span class="material-symbols-outlined text-primary text-2xl">local_shipping</span>
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<h2 class="text-white text-xl font-bold font-display leading-none tracking-tight uppercase">HIMTRANS</h2>
|
|
<span class="text-[10px] text-text-secondary font-display tracking-widest uppercase font-semibold">Service</span>
|
|
</div>
|
|
</a>
|
|
|
|
<!-- Desktop Nav -->
|
|
<div class="hidden lg:flex flex-1 justify-end gap-8 items-center">
|
|
<nav class="flex items-center gap-8">
|
|
{navLinks.map((link) => (
|
|
<a href={link.href} class="text-white/80 hover:text-primary text-sm font-medium transition-colors font-display uppercase tracking-wide">
|
|
{link.text}
|
|
</a>
|
|
))}
|
|
</nav>
|
|
<Button href="#contacts" variant="outline" className="h-9 px-5 text-xs border-white/20">
|
|
Связаться
|
|
</Button>
|
|
</div>
|
|
|
|
<!-- КНОПКА ГАМБУРГЕР -->
|
|
<button
|
|
id="menu-toggle"
|
|
class="lg:hidden flex flex-col gap-[8px] p-2 relative z-[160] focus:outline-none"
|
|
aria-label="Menu"
|
|
>
|
|
<div class="hamburger-line line-1"></div>
|
|
<div class="hamburger-line line-2"></div>
|
|
<div class="hamburger-line line-3"></div>
|
|
</button>
|
|
</header>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- АНИМАЦИОННАЯ ЛИНИЯ ПРОГРЕССА -->
|
|
<div
|
|
id="scroll-line"
|
|
class="absolute bottom-0 left-0 h-[2px] bg-primary z-20 will-change-[width] shadow-[0_0_10px_rgba(242,166,13,0.7)]"
|
|
style="width: 0%"
|
|
></div>
|
|
|
|
<!-- Мобильное меню -->
|
|
<MobileMenu links={navLinks} />
|
|
</div>
|
|
|
|
<script>
|
|
const menuToggle = document.getElementById('menu-toggle');
|
|
const mobileMenu = document.getElementById('mobile-menu');
|
|
const overlay = document.getElementById('menu-overlay');
|
|
const scrollLine = document.getElementById('scroll-line');
|
|
const mobileLinks = document.querySelectorAll('.mobile-link');
|
|
|
|
// --- ЛОГИКА АНИМАЦИОННОЙ ЛИНИИ ---
|
|
function updateScrollProgress() {
|
|
if (!scrollLine) return;
|
|
|
|
// Сколько прокручено
|
|
const winScroll = window.scrollY || document.documentElement.scrollTop;
|
|
// Общая доступная высота (высота всего документа - высота видимого окна)
|
|
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
|
|
|
|
// Рассчитываем процент
|
|
const scrolled = height > 0 ? (winScroll / height) * 100 : 0;
|
|
|
|
// Обновляем ширину
|
|
scrollLine.style.width = scrolled + "%";
|
|
}
|
|
|
|
// --- ЛОГИКА МЕНЮ ---
|
|
function toggleMenu() {
|
|
const isActive = menuToggle?.classList.contains('is-active');
|
|
|
|
if (isActive) {
|
|
menuToggle?.classList.remove('is-active');
|
|
mobileMenu?.classList.add('-translate-x-full');
|
|
overlay?.classList.add('opacity-0', 'pointer-events-none');
|
|
document.body.style.overflow = '';
|
|
} else {
|
|
menuToggle?.classList.add('is-active');
|
|
mobileMenu?.classList.remove('-translate-x-full');
|
|
overlay?.classList.remove('opacity-0', 'pointer-events-none');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
}
|
|
|
|
// Слушатели событий
|
|
menuToggle?.addEventListener('click', toggleMenu);
|
|
overlay?.addEventListener('click', toggleMenu);
|
|
mobileLinks.forEach(l => l.addEventListener('click', toggleMenu));
|
|
|
|
// Оптимизированный слушатель скролла
|
|
let ticking = false;
|
|
window.addEventListener('scroll', () => {
|
|
if (!ticking) {
|
|
window.requestAnimationFrame(() => {
|
|
updateScrollProgress();
|
|
ticking = false;
|
|
});
|
|
ticking = true;
|
|
}
|
|
});
|
|
|
|
// Инициализация при загрузке и ресайзе
|
|
window.addEventListener('DOMContentLoaded', updateScrollProgress);
|
|
window.addEventListener('resize', updateScrollProgress);
|
|
</script> |