Fix hero animation: object-fit cover + conditional blur + glass on collapse
All checks were successful
Build Docker Image / build (push) Successful in 5m14s

- HeroBackground.vue:
  - Add object-cover class to Lottie animation (fills container)
  - Make dark overlay conditional (v-if collapseProgress > 0.5)
  - Overlay fades in during collapse (opacity 0→1)

- MainNavigation.vue:
  - Replace glassStyle prop with isCollapsed
  - Glass effect (backdrop-blur-md) applies only when collapsed

- topnav.vue:
  - Pass isCollapsed instead of glass-style
  - Home page: isCollapsed from useHeroScroll
  - Other pages: always true (always collapsed)

Result:
- Animation covers full viewport without crop
- No blur overlay when hero is expanded
- Glass effect appears only when header collapses to 100px
This commit is contained in:
Ruslan Bakiev
2026-01-27 09:14:20 +07:00
parent 70c53da8eb
commit 75ce64b46e
3 changed files with 22 additions and 18 deletions

View File

@@ -6,7 +6,7 @@
src="/animations/supply-chain.lottie" src="/animations/supply-chain.lottie"
autoplay autoplay
loop loop
class="absolute inset-0 w-full h-full" class="absolute inset-0 w-full h-full object-cover"
:style="{ :style="{
opacity: 1 - collapseProgress * 0.7, opacity: 1 - collapseProgress * 0.7,
transform: `scale(${1 + collapseProgress * 0.1})` transform: `scale(${1 + collapseProgress * 0.1})`
@@ -14,8 +14,12 @@
/> />
</ClientOnly> </ClientOnly>
<!-- Overlay for text readability --> <!-- Overlay for text readability - only when hero starts collapsing -->
<div class="absolute inset-0 bg-gradient-to-b from-slate-900/60 via-slate-900/40 to-slate-900/70" /> <div
v-if="collapseProgress > 0.5"
class="absolute inset-0 bg-gradient-to-b from-slate-900/60 via-slate-900/40 to-slate-900/70"
:style="{ opacity: (collapseProgress - 0.5) * 2 }"
/>
</div> </div>
</template> </template>

View File

@@ -1,7 +1,7 @@
<template> <template>
<header <header
class="shadow-lg" class="shadow-lg"
:class="glassStyle ? 'bg-black/30 backdrop-blur-md border-b border-white/10' : 'bg-base-100 border-b border-base-300'" :class="isCollapsed ? 'bg-black/30 backdrop-blur-md border-b border-white/10' : 'bg-base-100 border-b border-base-300'"
:style="{ height: `${height}px` }" :style="{ height: `${height}px` }"
> >
<!-- Single row: Logo + Search + Icons --> <!-- Single row: Logo + Search + Icons -->
@@ -9,7 +9,7 @@
<!-- Left: Logo + Nav links (top aligned) --> <!-- Left: Logo + Nav links (top aligned) -->
<div class="flex items-start gap-6 flex-shrink-0 pt-4"> <div class="flex items-start gap-6 flex-shrink-0 pt-4">
<NuxtLink :to="localePath('/')" class="flex items-center gap-2"> <NuxtLink :to="localePath('/')" class="flex items-center gap-2">
<span class="font-bold text-xl" :class="glassStyle ? 'text-white' : 'text-base-content'">Optovia</span> <span class="font-bold text-xl" :class="isCollapsed ? 'text-white' : 'text-base-content'">Optovia</span>
</NuxtLink> </NuxtLink>
<!-- Service nav links --> <!-- Service nav links -->
@@ -17,8 +17,8 @@
<button <button
class="px-3 py-1 text-sm font-medium rounded-lg transition-colors" class="px-3 py-1 text-sm font-medium rounded-lg transition-colors"
:class="showActiveMode && catalogMode === 'explore' :class="showActiveMode && catalogMode === 'explore'
? (glassStyle ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content') ? (isCollapsed ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content')
: (glassStyle ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')" : (isCollapsed ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')"
@click="$emit('set-catalog-mode', 'explore')" @click="$emit('set-catalog-mode', 'explore')"
> >
{{ $t('catalog.modes.explore') }} {{ $t('catalog.modes.explore') }}
@@ -26,8 +26,8 @@
<button <button
class="px-3 py-1 text-sm font-medium rounded-lg transition-colors" class="px-3 py-1 text-sm font-medium rounded-lg transition-colors"
:class="showActiveMode && catalogMode === 'quote' :class="showActiveMode && catalogMode === 'quote'
? (glassStyle ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content') ? (isCollapsed ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content')
: (glassStyle ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')" : (isCollapsed ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200')"
@click="$emit('set-catalog-mode', 'quote')" @click="$emit('set-catalog-mode', 'quote')"
> >
{{ $t('catalog.modes.quote') }} {{ $t('catalog.modes.quote') }}
@@ -141,7 +141,7 @@
<NuxtLink <NuxtLink
:to="localePath('/clientarea/ai')" :to="localePath('/clientarea/ai')"
class="w-8 h-8 rounded-full flex items-center justify-center transition-colors" class="w-8 h-8 rounded-full flex items-center justify-center transition-colors"
:class="glassStyle ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'" :class="isCollapsed ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
> >
<Icon name="lucide:bot" size="18" /> <Icon name="lucide:bot" size="18" />
</NuxtLink> </NuxtLink>
@@ -151,7 +151,7 @@
<button <button
tabindex="0" tabindex="0"
class="w-8 h-8 rounded-full flex items-center justify-center transition-colors" class="w-8 h-8 rounded-full flex items-center justify-center transition-colors"
:class="glassStyle ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'" :class="isCollapsed ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
> >
<Icon name="lucide:globe" size="18" /> <Icon name="lucide:globe" size="18" />
</button> </button>
@@ -185,7 +185,7 @@
<button <button
tabindex="0" tabindex="0"
class="h-8 flex items-center gap-1 px-2 rounded-lg transition-colors" class="h-8 flex items-center gap-1 px-2 rounded-lg transition-colors"
:class="glassStyle ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'" :class="isCollapsed ? 'text-white/70 hover:text-white hover:bg-white/10' : 'text-base-content/70 hover:text-base-content hover:bg-base-200'"
> >
<Icon name="lucide:building-2" size="16" /> <Icon name="lucide:building-2" size="16" />
<span class="hidden lg:inline max-w-24 truncate text-xs"> <span class="hidden lg:inline max-w-24 truncate text-xs">
@@ -222,13 +222,13 @@
tabindex="0" tabindex="0"
role="button" role="button"
class="w-8 h-8 rounded-full overflow-hidden ring-2 transition-all cursor-pointer" class="w-8 h-8 rounded-full overflow-hidden ring-2 transition-all cursor-pointer"
:class="glassStyle ? 'ring-white/20 hover:ring-white/40' : 'ring-base-300 hover:ring-primary'" :class="isCollapsed ? 'ring-white/20 hover:ring-white/40' : 'ring-base-300 hover:ring-primary'"
> >
<div v-if="userAvatarSvg" v-html="userAvatarSvg" class="w-full h-full" /> <div v-if="userAvatarSvg" v-html="userAvatarSvg" class="w-full h-full" />
<div <div
v-else v-else
class="w-full h-full flex items-center justify-center font-bold text-xs" class="w-full h-full flex items-center justify-center font-bold text-xs"
:class="glassStyle ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content'" :class="isCollapsed ? 'bg-white/20 text-white' : 'bg-base-300 text-base-content'"
> >
{{ userInitials }} {{ userInitials }}
</div> </div>
@@ -260,7 +260,7 @@
<button <button
@click="$emit('sign-in')" @click="$emit('sign-in')"
class="px-4 py-1.5 rounded-full text-sm font-medium transition-colors" class="px-4 py-1.5 rounded-full text-sm font-medium transition-colors"
:class="glassStyle ? 'bg-white/20 text-white hover:bg-white/30' : 'bg-primary text-primary-content hover:bg-primary-focus'" :class="isCollapsed ? 'bg-white/20 text-white hover:bg-white/30' : 'bg-primary text-primary-content hover:bg-primary-focus'"
> >
{{ $t('auth.login') }} {{ $t('auth.login') }}
</button> </button>
@@ -306,8 +306,8 @@ const props = withDefaults(defineProps<{
canSearch?: boolean canSearch?: boolean
showModeToggle?: boolean showModeToggle?: boolean
showActiveMode?: boolean // Whether to show active state on mode toggle showActiveMode?: boolean // Whether to show active state on mode toggle
// Glass style (transparent) for map pages // Glass style applied when header is collapsed
glassStyle?: boolean isCollapsed?: boolean
// Dynamic height for hero effect // Dynamic height for hero effect
height?: number height?: number
}>(), { }>(), {

View File

@@ -28,7 +28,7 @@
:can-search="canSearch" :can-search="canSearch"
:show-mode-toggle="true" :show-mode-toggle="true"
:show-active-mode="isCatalogSection" :show-active-mode="isCatalogSection"
:glass-style="isHomePage || isCatalogSection" :is-collapsed="isHomePage ? heroIsCollapsed : true"
@toggle-theme="toggleTheme" @toggle-theme="toggleTheme"
@set-catalog-mode="setCatalogMode" @set-catalog-mode="setCatalogMode"
@sign-out="onClickSignOut" @sign-out="onClickSignOut"