new file: main_dc/BB/bbvue/public/images/slide2.jpg

new file:   main_dc/BB/bbvue/public/images/slide3.jpg
	new file:   main_dc/BB/bbvue/public/images/slide4.jpg
	modified:   main_dc/BB/bbvue/src/views/Home.vue
add slider, new slides, and adaptation for all phone sizes
This commit is contained in:
2025-11-04 02:59:12 +05:00
parent 46e804cc90
commit 9bb1690140
4 changed files with 363 additions and 58 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

+363 -58
View File
@@ -1,7 +1,11 @@
<template> <template>
<div class="home-page"> <div class="home-page">
<!-- Герой-секция --> <!-- Герой-секция со слайдером -->
<section class="hero-section"> <section class="hero-section">
<div class="hero-slider">
<div class="slide" v-for="(slide, index) in slides" :key="index" :class="{ active: currentIndex === index }"
:style="{ backgroundImage: `url(${slide.url})` }"></div>
</div>
<div class="hero-overlay"> <div class="hero-overlay">
<div class="container"> <div class="container">
<div class="hero-content"> <div class="hero-content">
@@ -182,13 +186,6 @@
</div> </div>
</section> </section>
<div class="hero-stats">
<div class="stat" v-for="stat in stats" :key="stat.id">
<animated-number :value="stat.value" :format="stat.format" class="stat-number" />
<div class="stat-label">{{ stat.label }}</div>
</div>
</div>
<!-- Быстрые ссылки --> <!-- Быстрые ссылки -->
<section class="quick-links-section"> <section class="quick-links-section">
<div class="container"> <div class="container">
@@ -224,10 +221,34 @@
export default { export default {
// eslint-disable-next-line vue/multi-word-component-names // eslint-disable-next-line vue/multi-word-component-names
name: 'Home', name: 'Home',
data() {
return {
currentIndex: 0,
slideInterval: null,
slides: [
{ url: this.getImageUrl('FastRun.jpg') },
{ url: this.getImageUrl('slide2.jpg') },
{ url: this.getImageUrl('slide3.jpg') },
{ url: this.getImageUrl('slide4.jpg') }
],
hasInteracted: false,
isContentVisible: false,
autoShowTimeout: null
}
},
computed: {
currentSlide() {
return this.slides[this.currentIndex]
}
},
mounted() { mounted() {
this.preloadImages()
this.startSlider()
window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true }) window.addEventListener('scroll', this.handleFirstInteraction, { passive: true, once: true })
window.addEventListener('click', this.handleFirstInteraction, { once: true }) window.addEventListener('click', this.handleFirstInteraction, { once: true })
window.addEventListener('touchstart', this.handleFirstInteraction, { once: true }) window.addEventListener('touchstart', this.handleFirstInteraction, { once: true })
this.autoShowTimeout = setTimeout(() => { this.autoShowTimeout = setTimeout(() => {
if (!this.hasInteracted) { if (!this.hasInteracted) {
this.showContent() this.showContent()
@@ -235,18 +256,34 @@ export default {
}, 3000) }, 3000)
}, },
beforeUnmount() { beforeUnmount() {
// Убираем обработчики при размонтировании this.stopSlider()
window.removeEventListener('scroll', this.handleFirstInteraction) window.removeEventListener('scroll', this.handleFirstInteraction)
window.removeEventListener('click', this.handleFirstInteraction) window.removeEventListener('click', this.handleFirstInteraction)
window.removeEventListener('touchstart', this.handleFirstInteraction) window.removeEventListener('touchstart', this.handleFirstInteraction)
clearTimeout(this.autoShowTimeout) clearTimeout(this.autoShowTimeout)
}, },
methods: { methods: {
startSlider() {
this.slideInterval = setInterval(() => {
this.nextSlide()
}, 8000)
},
stopSlider() {
if (this.slideInterval) {
clearInterval(this.slideInterval)
}
},
nextSlide() {
this.currentIndex = (this.currentIndex + 1) % this.slides.length
},
preloadImages() {
this.slides.forEach(slide => {
const img = new Image()
img.src = slide.url
})
},
getImageUrl(path) { getImageUrl(path) {
// В продакшене замените на правильный путь
const baseUrl = import.meta.env.BASE_URL const baseUrl = import.meta.env.BASE_URL
// Путь от корня public/
console.log(`${baseUrl}images/${path}`)
return `${baseUrl}images/${path}` return `${baseUrl}images/${path}`
}, },
handleFirstInteraction() { handleFirstInteraction() {
@@ -258,9 +295,8 @@ export default {
}, },
showContent() { showContent() {
this.isContentVisible = true this.isContentVisible = true
// Эмитим событие для показа хедера
this.$emit('show-header') this.$emit('show-header')
}, }
} }
} }
</script> </script>
@@ -270,29 +306,45 @@ export default {
overflow-x: hidden; overflow-x: hidden;
} }
.benefit-card { /* Герой-секция со слайдером */
transform-style: preserve-3d;
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}
.benefit-card:hover {
transform: translateY(-10px) rotateX(5deg);
box-shadow: 0 25px 40px rgba(46, 139, 87, 0.15);
}
/* Герой-секция */
.hero-section { .hero-section {
background: url('@/public/images/FastRun.jpg') center/cover no-repeat;
height: 100vh;
color: white;
padding: 0 0 80px 0;
position: relative; position: relative;
animation: backgroundZoom 20s infinite alternate; height: 100vh;
overflow: hidden;
color: white;
padding: 0;
display: flex; display: flex;
align-items: end; align-items: end;
justify-content: center; justify-content: center;
} }
.hero-slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 1.5s ease-in-out;
animation: backgroundZoom 20s infinite alternate;
}
.slide.active {
opacity: 1;
}
@keyframes backgroundZoom { @keyframes backgroundZoom {
0% { 0% {
transform: scale(1); transform: scale(1);
@@ -306,58 +358,64 @@ export default {
.hero-overlay { .hero-overlay {
position: relative; position: relative;
z-index: 2; z-index: 2;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
} }
.hero-content { .hero-content {
text-align: center; text-align: center;
max-width: 800px; max-width: 1200px;
width: 90%;
margin: 0 auto; margin: 0 auto;
padding: 2rem 1rem;
} }
.hero-title { .hero-title {
margin-bottom: 1.5rem; margin-bottom: clamp(1rem, 4vw, 2.5rem);
font-style: italic; font-style: italic;
} }
.title-main { .title-main {
display: block; display: block;
font-size: 3rem; font-size: clamp(2rem, 8vw, 4.5rem);
font-weight: 800; font-weight: 800;
text-shadow: text-shadow: 2px 2px 4px #8bbb939f;
2px 2px 4px #8bbb939f;
line-height: 1.1; line-height: 1.1;
margin-bottom: 0.5rem; margin-bottom: clamp(0.5rem, 2vw, 1rem);
letter-spacing: 2px; letter-spacing: clamp(1px, 0.5vw, 3px);
font-family: var(--h1VictorMono); font-family: var(--h1VictorMono);
font-size: clamp(1.5rem, 3vw + 1rem, 3rem);
} }
.title-sub { .title-sub {
display: block; display: block;
font-size: 1.5rem; font-size: clamp(1.1rem, 4vw, 2rem);
font-weight: 300; font-weight: 300;
opacity: 0.9; opacity: 0.9;
font-family: 'H1VM', sans-serif; font-family: 'H1VM', sans-serif;
font-size: clamp(1rem, 2vw + 0.3rem, 1.5rem); line-height: 1.3;
} }
.hero-description { .hero-description {
font-size: 1.2rem; font-size: clamp(1rem, 3vw, 1.4rem);
line-height: 1.6; line-height: 1.6;
margin-bottom: 2.5rem; margin-bottom: clamp(2rem, 6vw, 3.5rem);
opacity: 0.9; opacity: 0.9;
max-width: 600px; max-width: min(90%, 800px);
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
letter-spacing: 2px; letter-spacing: clamp(0.5px, 0.3vw, 2px);
padding: 0 1rem;
} }
.hero-actions { .hero-actions {
display: flex; display: flex;
gap: 1rem; gap: clamp(0.8rem, 3vw, 1.5rem);
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: 3rem; margin-bottom: clamp(2rem, 6vw, 4rem);
width: 100%; width: 100%;
} }
@@ -365,20 +423,22 @@ export default {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 15px 30px; padding: clamp(0.8rem, 3vw, 1rem) clamp(1.5rem, 4vw, 2rem);
border-radius: 50px; border-radius: 50px;
text-decoration: none; text-decoration: none;
font-weight: 600; font-weight: 600;
transition: all 0.3s ease; transition: all 0.3s ease;
border: 2px solid transparent; border: 2px solid transparent;
gap: 0.5rem; gap: 0.5rem;
min-width: 100px; min-width: min(200px, 40vw);
font-size: clamp(0.9rem, 3vw, 1.1rem);
white-space: nowrap;
} }
.btn-large { .btn-large {
padding: 18px 35px; padding: clamp(1rem, 4vw, 1.2rem) clamp(2rem, 5vw, 2.5rem);
font-size: 1.1rem; font-size: clamp(1rem, 3.5vw, 1.3rem);
min-width: 120px; min-width: min(220px, 45vw);
} }
.btn-primary { .btn-primary {
@@ -420,24 +480,268 @@ export default {
.hero-stats { .hero-stats {
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 3rem; gap: clamp(1.5rem, 5vw, 4rem);
flex-wrap: wrap; flex-wrap: wrap;
padding: 0 1rem;
} }
.stat { .stat {
text-align: center; text-align: center;
min-width: 80px;
} }
.stat-number { .stat-number {
font-size: 2.5rem; font-size: clamp(1.8rem, 6vw, 3rem);
font-weight: 800; font-weight: 800;
color: #ffd700; color: #ffd700;
margin-bottom: 0.5rem; margin-bottom: clamp(0.3rem, 1vw, 0.8rem);
line-height: 1;
} }
.stat-label { .stat-label {
font-size: 0.9rem; font-size: clamp(0.8rem, 2.5vw, 1rem);
opacity: 0.8; opacity: 0.8;
line-height: 1.2;
}
/* АДАПТИВНЫЕ МЕДИА-ЗАПРОСЫ ДЛЯ РАЗНЫХ УСТРОЙСТВ */
/* Планшеты (768px - 1024px) */
@media (max-width: 1024px) {
.hero-section {
height: 80vh;
min-height: 500px;
}
.hero-content {
padding: 1.5rem 0.5rem;
}
.title-main {
font-size: clamp(1.8rem, 6vw, 3rem);
}
.title-sub {
font-size: clamp(1rem, 3vw, 1.5rem);
}
}
/* Большие телефоны (576px - 768px) */
@media (max-width: 768px) {
.hero-section {
height: 70vh;
min-height: 450px;
align-items: flex-end;
}
.hero-content {
padding-bottom: clamp(2rem, 8vh, 4rem);
}
.hero-actions {
flex-direction: column;
align-items: center;
}
.btn-large {
width: min(280px, 80vw);
min-width: auto;
}
.hero-stats {
gap: clamp(1rem, 4vw, 2rem);
}
.stat {
min-width: 70px;
}
}
/* Телефоны (480px - 576px) */
@media (max-width: 576px) {
.hero-section {
height: 65vh;
min-height: 400px;
}
.hero-content {
width: 95%;
padding: 1rem 0.5rem;
padding-bottom: clamp(1.5rem, 6vh, 3rem);
}
.title-main {
font-size: clamp(1.6rem, 7vw, 2.2rem);
margin-bottom: 0.3rem;
}
.title-sub {
font-size: clamp(0.9rem, 4vw, 1.2rem);
}
.hero-description {
font-size: clamp(0.9rem, 3.5vw, 1.1rem);
margin-bottom: clamp(1.5rem, 5vw, 2.5rem);
padding: 0 0.5rem;
}
.hero-stats {
gap: clamp(0.8rem, 3vw, 1.5rem);
}
.stat {
min-width: 60px;
}
.stat-number {
font-size: clamp(1.5rem, 5vw, 2.2rem);
}
.stat-label {
font-size: clamp(0.7rem, 2.5vw, 0.85rem);
}
}
/* Маленькие телефоны (до 480px) */
@media (max-width: 480px) {
.hero-section {
height: 60vh;
min-height: 350px;
}
.hero-content {
padding-bottom: clamp(1rem, 5vh, 2rem);
}
.title-main {
font-size: clamp(1.4rem, 6vw, 1.8rem);
letter-spacing: 0.5px;
}
.title-sub {
font-size: clamp(0.8rem, 3.5vw, 1rem);
}
.hero-description {
font-size: clamp(0.8rem, 3vw, 0.95rem);
line-height: 1.5;
margin-bottom: clamp(1rem, 4vw, 2rem);
}
.btn {
padding: 0.7rem 1.2rem;
font-size: 0.85rem;
min-width: 160px;
}
.btn-large {
padding: 0.8rem 1.5rem;
font-size: 0.9rem;
min-width: 180px;
}
.hero-stats {
gap: 0.8rem;
}
.stat {
min-width: 55px;
}
.stat-number {
font-size: 1.4rem;
}
.stat-label {
font-size: 0.7rem;
}
}
/* Очень маленькие телефоны (до 360px) */
@media (max-width: 360px) {
.hero-section {
height: 55vh;
min-height: 320px;
}
.hero-content {
padding: 0.5rem;
padding-bottom: clamp(0.8rem, 4vh, 1.5rem);
}
.title-main {
font-size: 1.3rem;
}
.title-sub {
font-size: 0.85rem;
}
.hero-actions {
gap: 0.5rem;
}
.btn {
min-width: 140px;
font-size: 0.8rem;
padding: 0.6rem 1rem;
}
.btn-large {
min-width: 150px;
font-size: 0.85rem;
padding: 0.7rem 1.2rem;
}
.hero-stats {
gap: 0.5rem;
}
.stat {
min-width: 50px;
}
.stat-number {
font-size: 1.2rem;
}
.stat-label {
font-size: 0.65rem;
}
}
/* Ландшафтная ориентация */
@media (max-height: 600px) and (orientation: landscape) {
.hero-section {
height: 100vh;
min-height: 400px;
}
.hero-content {
padding: 1rem 0;
}
.title-main {
font-size: clamp(1.5rem, 5vw, 2rem);
}
.title-sub {
font-size: clamp(0.9rem, 3vw, 1.1rem);
}
.hero-description {
margin-bottom: clamp(1rem, 3vh, 1.5rem);
font-size: 0.9rem;
}
.hero-actions {
margin-bottom: clamp(1rem, 3vh, 2rem);
}
.hero-stats {
gap: 1.5rem;
}
} }
/* Секции */ /* Секции */
@@ -474,10 +778,13 @@ export default {
text-align: center; text-align: center;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08); box-shadow: 0 5px 20px rgba(0, 0, 0, 0.08);
transition: transform 0.3s ease; transition: transform 0.3s ease;
transform-style: preserve-3d;
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
} }
.benefit-card:hover { .benefit-card:hover {
transform: translateY(-5px); transform: translateY(-10px) rotateX(5deg);
box-shadow: 0 25px 40px rgba(46, 139, 87, 0.15);
} }
.benefit-icon { .benefit-icon {
@@ -821,9 +1128,7 @@ export default {
.container { .container {
padding: 0 15px; padding: 0 15px;
} }
}
@media (max-width: 480px) {
.hero-actions { .hero-actions {
gap: 0.5rem; gap: 0.5rem;
} }